1、廢話
?? 這部分將要描述瀏覽器為我們創建的對象。就是大家熟悉的window,document
等。一般書上都叫對象層次和文檔對象模型。用dom標準來說,一般瀏覽器都實現
了0級DOM,關于DOM標準我感覺知道0級就可以了。對于DOM標準W3C早已定義了1級
,2級,三級也在標準化,問題是各個瀏覽器不完全實現,尤其是IE的事件模型,
完全不和DOM一致。(不過prototype.js已經做了很好的封裝)
??? 我這里不會講dom接口,更不會講各個瀏覽器的如何實現這些接口及區別。(
我也沒這能力)。而是要猜測一下瀏覽器是怎么用javascript定義這些接口或類
的。(注意是猜測,個人理解)
2、引子
<SCRIPT LANGUAGE="JavaScript">
<!--
alert(document);
alert(typeof(document));
//alert(Document);//出錯
function desc(obj){
? var ret='';
? for(var key in obj){
??? ret+=key+':'+obj[key]+'</br>';
? }
? return ret;
}
document.writeln(desc(document));
//-->
</SCRIPT>
以上簡單的javascript代碼,不知大家提出過疑問沒有。
首先,document是個javascript對象,誰創建了它。;document的類是什么
(function Document(){....} 可能是new Document()創建了它);document有些
什么屬性或方法。這些對象與html關系是什么。這些對象與dom標準有什么關系。
接下來將試著回答這些問題。我會側重講述我的理解思路,而不是具體哪個方法
,接口。
3、一個簡單的例子的深入理解
<SCRIPT LANGUAGE="JavaScript">
<!--
??? alert(document);//存在
??? alert(this.document==window.document);//true
//-->
</SCRIPT>
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<SCRIPT LANGUAGE="JavaScript">
??? alert(document.getElementById('xm'));//null
</SCRIPT>
</HEAD>
<SCRIPT LANGUAGE="JavaScript">
??? alert(document.getElementById('xm'));//null
</SCRIPT>
<BODY>
<SCRIPT LANGUAGE="JavaScript">
??? alert(document.getElementById('xm'));//null
</SCRIPT>
<input type="text" id="xm">
<SCRIPT LANGUAGE="JavaScript">
??? alert(document.getElementById('xm'));//存在
</SCRIPT>
</BODY>
<SCRIPT LANGUAGE="JavaScript">
??? alert(document.getElementById('xm'));//存在
</SCRIPT>
</HTML>
上面代碼說明幾個問題:
a、window\this就是我在變量篇里面提到過的窗體的全局對象,document是它的
一個屬性,也叫全局屬性。
b、window,document在html最前面已經存在了。我們可以隨處使用document對象
。
c、對于輸入框按鈕這類html標記的javascript對象只有在解釋過以后才能訪問到
。當然我們編碼用到這些對象時,都在body.onload或鼠標觸發,一般不會出錯。
d、例子中的document.getElementById('xm')javascript對象和我們自己創建的
javascript對象有什么區別呢?從應用角度看沒有區別,只是自己定義的對象由
自己new來初始化,而document.getElementById('xm')有瀏覽器為我們初始化對
象,我們直接用方法得到句柄就可以了(有多種方法)。
e、我們怎么知道這些對象的用法呢?查看w3c DOM參考嗎?我認為不用。
4、瀏覽器為我們創建的對象與我們自己定義的對象的區別。
<input type="text" id="xm" value="aaa">
<INPUT TYPE="button" value='click me' onclick="alert
(document.getElementById('xm').value);
alert(document.getElementById('myxm').value);">
<br>
<SCRIPT LANGUAGE="JavaScript">
<!--
function desc(obj){
? var ret='';
? for(var key in obj){
??? ret+=key+':'+obj[key]+'</br>';
? }
? return ret;
}
function MyText(id,value){
??? this.id=id;
?this.outHtml='<input type=text id='+id+' value='+value+'>';
?this.toString=function(){
??????? return this.outHtml;
?}
?//...
?//...
?//...
}
//document.writeln(desc(document.getElementById('xm')));
var myText=new MyText('myxm','zkj');
document.writeln(myText);
//-->
</SCRIPT>
希望你仔細的看看上面代碼的執行結果。可能你會得到更震撼的想法來。暫時我
有以下幾個感想:
a、我們自己也可以寫一個界面控件,如果把屬性建立全的話,完全可以復原瀏覽
器的內建類。
b、反過來,對于瀏覽器為我們創建的對象,我們可以當成自己的對象一樣使用。
看看prototype.js中,使用了內建對象的方法。
escapeHTML: function() {
??? var div = document.createElement('div');
??? var text = document.createTextNode(this);
??? div.appendChild(text);
??? return div.innerHTML;
? },
? unescapeHTML: function() {
??? var div = document.createElement('div');
??? div.innerHTML = this.stripTags();
??? return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
? },
c、大家可以打開描述注釋,看看<input >到底包含哪些屬性和方法。注意
outerHTML屬性的值是什么,在網頁上表示什么。可以看出javascript對象的
outerHTML屬性就是html(xhtml)規范中的標簽。這樣給了我們寫javascriptUI控
件的新思路,一個控件就是一個javascript對象(其實很多人都這樣做了,但好
象都是innerHtml等等)。可以象asp.net或jsf那樣編寫組合控件。
大家可以看一下ActiveWidgets代碼(與我的思路有些差別),我認為這種基于
html標簽的UI控件無論性能、開發人員使用難度上都不錯。
對于dojo的widget這種做UI做法我個人不很贊同,完全用div,圖片實現了一便
html的UI標簽。性能不好,開發人員上手不容易,美工更不能修改,另外圖片都
是定死的,界面也比較單調,也不好修改。
對于自己實現javascript控件,我認為在htmlUI基礎上就可以了,畢竟自己實現
存在的UI難度不小。把html的標準UI組合成新的控件。例如,我們可以很容易的
實現一個包括? (登陸 密碼 驗證碼 確認)? 的組合javascript控件
d、dom標準與瀏覽器對象
打開document.writeln(desc(document.getElementById('xm')));,你可以看到<
input type="text">的所有屬性。這些屬性 ”dom標準“,之所以加引號,DOM標
準我們有很多誤解,認為DOM標準是個什么高不可及、不可違抗的、復雜的東西。
首先:我們接觸了靜態HTML,xml,有了DOM對象模型(熟悉java的都知道java的實
現),但javascript語言的特點使不能象java,c++那樣來實現DOM對象模型。例如
input 繼承了 HTMLElement,HTMLElement定義的一堆屬性。按照dom標準,所有瀏
覽器實現 input javascript對象時都必須把這些屬性加上,這就叫符合標準。其
實說白了:DOM標準就是瀏覽器為我們實現的javascript代碼的總和。(可以瀏覽
器廠商不完全實現)
看protorype.js的代碼
為了支持多了瀏覽器,定義下面代碼。說明有的瀏覽器網頁全局變量里有Element
,Event,有些瀏覽器沒給我們定義。所以只能這樣了。
if (!window.Element) {
? var Element = new Object();
}
if (!window.Event) {
? var Event = new Object();
}
還有用AJAX技術時
'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0', 其實很簡
單,就是瀏覽器中有沒有這些javascript實現了。所有大家在DWR框架中用iframe
實現了一個javascript? XMLHTTP類。
e、與xhtml標準的矛盾
在xhtml中,<input type="button"> 雙引號是必須的,但outerHTML屬性中卻沒
雙引號。還沒想明白。
5、瀏覽器為我們創建了幾類對象
a、全局對象window或this。其實javascript的全局變量、全局方法(如
Math,setTimeout())都可以由window對象訪問。另外瀏覽器的特殊函數或屬性。
(如window.status,window.alert())
b、document對象。包括圖片,applet,form等屬性,可能我們用的最多。也是訪
問我們可見的元素的入口(document.getElementById),也提供了動態創建html
標簽的方法。如var t=new Text("test");沒有這樣方法,只能 var
t=document.creatTextNode("test");都由document提供的工廠方法來創建。
c、頁面中的html標簽,當解釋執行過,瀏覽器會為你初始化對象,放到document
對象中去。
6、對DOM標準的認識
DOM標準定義了接口,沒有定義類。瀏覽器為我們實現了這些接口,實現這些接口
的類我們也看不見。所以這里接口的含義和java中接口的含義不同。
例如我們常用的document對象
DOM標準中定義了個Document接口,實現HTMLElemnt接口。
Document接口和HTMLElemnt接口在DOM標準中定義了很多屬性和方法。
注意我們使用的document對象是瀏覽器為我們創建的javascript對象,到底
document對象有哪些屬性和方法是有瀏覽器決定的,而不是由DOM標準決定的。
在這里javascript世界里沒有繼承概念,所以DOM標準定義的接口,對于我們開發
人員來說只能當成一個參考手冊,象javadoc。
7、如何寫出跨瀏覽器的javascript代碼
?? 這難度大了點.但說穿了,只要我們用javascript代碼把瀏覽器沒符合DOM標準
的代碼補全就好了。但DOM標準之大不是一般人能全部搞清楚的,瀏覽器廠商也使
壞,讓這個工作更難了。?? 現在好象有個誤區,人們寫javascript都喜歡按照
DOM標準來寫。如果我們按照各個瀏覽器實現DOM標準的交集寫代碼的話,可能會
更好點。
?
?