论坛首页 Web前端技术论坛

对象篇(7)网页中的javascript对象

浏览 8146 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-04-23  
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标准的交集写代码的话,可能会更好点。
   发表时间:2006-04-23  
:shock: 累坏了,写东西真难.很佩服技术作家.

现在感觉修炼内功的重要性.
如果你jdk还半生不熟,jsp也没写过多少,就struts\webwork,那你根本不能体会优秀框架的优秀.
对于javascript,如果你只写过些客户端表单验证,就用那些"优秀"的js类库,动口就javascript的类封装\继承等,那更不能写出稳定的应用程序来.


我提个问题来:
对于继承,javascript语言非要模拟实现.
0 请登录后投票
   发表时间:2006-04-23  
:shock: 累坏了,写东西真难.很佩服技术作家.

现在感觉修炼内功的重要性.
如果你jdk还半生不熟,jsp也没写过多少,就struts\webwork,那你根本不能体会优秀框架的优秀.
对于javascript,如果你只写过些客户端表单验证,就用那些"优秀"的js类库,动口就javascript的类封装\继承等,那更不能写出稳定的应用程序来.


我提个问题来:
对于继承,javascript语言非要模拟实现.
0 请登录后投票
   发表时间:2006-04-26  
对于自己实现javascript控件,我认为在htmlUI基础上就可以了,毕竟自己实现存在的UI难度不小。把html的标准UI组合成新的控件。例如,我们可以很容易的实现一个包括 (登陆 密码 验证码 确认) 的组合javascript控件


大家都关心自制widget,楼主多写写这个

dojo有些很猥琐,根据element的class来把这个element内部改成控件
自己比较喜欢根据id来做
0 请登录后投票
   发表时间:2006-05-26  
zkj_beyond 写道
:
如果你jdk还半生不熟,jsp也没写过多少,就struts\webwork,那你根本不能体会优秀框架的优秀.
对于javascript,如果你只写过些客户端表单验证,就用那些"优秀"的js类库,动口就javascript的类封装\继承等,那更不能写出稳定的应用程序来.


这么巧,我就刚刚是这一个"非常不幸"的人了.刚接触jdk一点点,就开始做web应用,老大一提出"spring+struts+hibernate",我们就开始动手,后来又要求Ajax加入,费了老半天力,总算能把dwr给弄进来了.

没办法啊,有压力啊!

于是我现在整天泡在javaeye上面,dlee翻译的ajaxInaction也买了,reading...

不幸中的万幸,知道自己是不幸...
0 请登录后投票
   发表时间:2006-05-29  
很支持zkj_beyond这样的研究性学习,如果用这些知识写框架不错,但在现实开发中可能都用不上

从刚开始工作到现在我基本都是做UI这快(除了美工),感觉要写好javascript真的不容易,zkj_beyond说得不错:对于javascript,如果你只写过些客户端表单验证,就用那些"优秀"的js类库,动口就javascript的类封装\继承等,那更不能写出稳定的应用程序来.  很赞同这样的说法。

很多人对JS有误解,认为JS不过如此,认为写个验证就是JS,不知道他能不能写个稳定的UI出来。

写优秀的JS需要经验,有幸,公司打算培养我成这样的人才,目前写JS大概有大概也有9个月了,从一开始的摸不着边到现在的研究dojo框架,感觉自己在不断进步

对于现在众多的AJAX框架,我认为没有JS经验的团队不应该用,因为那样会另你更麻烦

乱谈一通,真不好意思 
0 请登录后投票
   发表时间:2006-05-29  
引用
e、与xhtml标准的矛盾
在xhtml中,<input type="button"> 双引号是必须的,但outerHTML属性中却没双引号。还没想明白


关于这个我做了实验
<input type="text" id="xm" value="aaa"> 
<script language="JavaScript">
<!--
alert(document.getElementById("xm");.parentNode.innerHTML);;
//-->
</script>


分别用IE和Firefox打开,你会发现firefox下有""而IE下没有""
我猜测是浏览器不同而不同,这些小差异其实没必要太深入 
0 请登录后投票
   发表时间:2006-05-29  
引用
对于dojo的widget这种做UI做法我个人不很赞同,完全用div,图片实现了一便html的UI标签。性能不好,开发人员上手不容易,美工更不能修改,另外图片都是定死的,界面也比较单调,也不好修改。


关于dojo widgets,不说美工,从效率来看就不行,不知道为什么这些widgets都用DIV封装起来,想把两个dojo.widget.Button放一起都要用Table,无语 
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics