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標準的交集寫代碼的話,可能會

更好點。

?


?