-
2009-04-01
什么是DOM?DOM和JavaScript的关系 - [web开发]
这个做了这么久的front-end了,这个问题还没有理解的这么深入,惭愧,惭愧。看看这篇文章吧
什么是DOM?
文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口。它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式。我们最为关心的是,DOM把网页和脚本以及其他的编程语言联系了起来。
脚本开发人员可以通过文档对象的属性、方法和事件来掌控、操纵和创建动态的网页元素。每一个网页元素(一个HTML标签)都对应着一个对象 (object,所谓“对象”,用白话说就是“东西”。object这个词在台湾通常翻译成“物件”)。网页上的标签是一层层嵌套的,最外面的一层 是<HTML>,文档对象模型也这样一层层嵌套着,但是通常被理解成一棵树的形状。树根是window或document对象,相当于最外层 的标签的外围,也就是整个文档。树根之下(这棵树的图通常是倒着画,就好像遗传谱系或者家谱那样。树根就是唯一的共同祖先)是子一级的对象,子对象也有它 自己的子对象,除了根对象以外,所有的对象都有自己的父对象,同一对象的子对象之间就是兄弟的关系。
在这种由“父子兄弟”组成的“单性繁殖家族图谱树”框架结构中,每个网页元素都可以被确切地定位。文档对象模型把整张网页组织成这样的一个树状的结构,树 结构中的每一个元素都被视为一个节点(node)。包括JavaScript在内的各种编程语言都可以通过文档对象模型来访问和改变网页的各种细节。
万维网协会(World Wide Web Consortium,W3C)已经给文档对象模型制定了一系列标准,并且正在制定更多的相关标准。当代的浏览器除支持其中的一部分标准之外,还支持某些 早在W3C标准制定以前就流行了的历史既成的编程接口。也就是说现在浏览器使用的技术历史由来纷繁复杂,有些人们普遍使用的DOM技术并无标准可依。
我们将深入所有通用DOM的细节(包括IE浏览器中“与众不同”的某些技术),以全面掌握面向实践的技术。
DOM和JavaScript
我经常在QQ、MSN和email中被大家问到的“有关JavaScript”的问题,95%其实是DOM的问题。人们在习惯上不爱说DOM,要么就说 JavaScript,要么就扯到“Ajax”(一度火爆的“概念”,最近刚刚有所降温,一如上世纪末的“DHTML”那样。对于这些热点词汇的产生,我 个人感到非常欣慰,因为每一次都带来人们对JavaScript技术的热捧。下一个热点词汇是什么?也许我们可以炮制一个也说不定……Pseudo- Mashup,如何?)。
我们用JavaScript对网页进行的所有操作都是通过DOM进行的。DOM属于浏览器,而不是JavaScript语言规范里的规定的核心内容,所以 如果你下载一个JavaScript语言的参考帮助文档来查的话,就连妇孺皆知的document.write方法也找不到。
下面这段代码的作用是用一个提示框逐个显示网页中所有链接的网址,代码中被标为红色的部分就是DOM。
var anchorTags = document.getElementsByTagName("a");
for (var i = 0; i < anchorTags.length ; i++)
{
alert("Href of this a element is : " + anchorTags[i].href + "\n");
}
这样一来哪些是核心JavaScript,哪些是DOM,各自起什么作用,就可以一目了然了。
var anchorTags =
创建了一个名为 anchorTags 的 JavaScript 变量。
document.getElementsByTagName("a")
Document接口是 DOM1核心(DOM1 Core)规范 中定义的第一个接口,而 document 是实现了Document接口的一个宿主对象。document掌控着网页里的所有东西。
DOM1核心 为Document 接口定义了 getElementsByTagName() 方法。这个方法返回一个节点列表(NodeList) ,也就是一种DOM特有的包含节点的数组,包含了所有符合匹配参数条件的标签,按照在文档中出现的顺序排列。于是anchorTags变量现在就成了一个 节点列表。
;
分号是JavaScript里的语句结束符号。
for (var i = 0; i <
这是编程语言里典型的“for循环”。声明了循环变量i,逐个处理anchorTags节点列表里的每一个节点。这也是JavaScript的东西。
anchorTags.length
DOM1 核心 定义了NodeList接口的 length 属性。这个属性返回一个整数,就是节点列表里包含的节点数目。说起来JavaScript 的数组也有一个 length属性。
; i++) {
典型的JavaScript变量增1运算。
alert(
alert() 是一个DOM方法,弹出一个提示框,显示传递给该方法的参数(字符串)。话说这个东西是通称 0级DOM(DOM level 0)或DOM0的一些历史既成的编程接口当中的一员。DOM0 是一套“被某些浏览器所支持”的编程接口(事实上,市场上不存在不支持DOM0的浏览器,只有在某些软件爱好者的收藏品中才能见得到),不属于任何DOM 标准规范。
"Href of this a element is : " +
一个字符串字面量和一个字符串链接符。JavaScript的东西。
anchorTags[i].href
href 是 DOM1 HTML 规范中定义的 HTMLAnchorElement 接口的属性,返回链接(<a>)元素的href属性的值。
在此我们用了像anchorTags[i]这样的用法,这和JavaScript里访问第i个数组项的语法是一样的。语言中性(language- neutral,与具体语言无关)的所谓“DOM方式”访问某个节点列表中的一个项目的办法是使用在NodeList接口中定义的item() 方法:anchorTags.item(1).href。但是大多数JavaScript实现程序都允许你使用这种简单的类似于数组的语法,而这也是大多 数人实际在用的方式。
+ "\n");
又一个字符串连接。在字符串的末尾加入一个回车符。
}
“for循环”结束 -
怎样拍夜景
在论坛上看到这篇文章,转一下
夜景主要是指在夜晚户外灯光或夜晚自然光下的景物,拍摄时以灯光、火光、月光等作为主要光源. 拍摄时要注意以下几点:
1. 保持夜晚气氛.夜晚光值比较低,而景物的反差又比较大,要适当控制曝光量.如果把天空拍得过亮,或灯光的亮度曝光过度时,都会把夜晚拍成白昼,而减弱了夜晚气氛.所以夜景的天空色调应是浅黑色,要有意识地使曝光略不足,一般按正常曝光时间减少1/3或1/2.
2. 保持灯光的真实效果.夜间摄影的光源主要来自灯光,所以用光时,要表现出灯光光线的照射效果.比如灯光近明远暗,它的光线的亮度随光源距离加长而递减,使用闪光灯辅助照明时,要保留这一特点.可用光圈控制闪光灯的亮度,用慢速度感受原灯光.闪光灯发光的方向要与灯光原照射方向一致.
3. 拍摄夜晚街景时,为了渲染车辆繁忙的景象,可以用长时间曝光的方法,让来往车辆的灯光在底片上多次感光.因车身较暗而又在行动,所以在胶片上不会感光,而汽车的车灯,就会在画面上划出光亮的线条.画面上白线条的数量和方向,可以根据构图的要求加以控制.一般拍摄时,多利用镜头盖,如车的行动方向符合要求时,可打开镜头盖曝光;如车的行动方向不符合要求时,可盖上镜头盖不感光.拍摄时,把相机固定在三脚架上,盖上镜头盖,然后打开T门或B门(B门需要锁住)取下镜头盖进行曝光,用镜头盖的开关来控制曝光.
4. 夜间摄影可使用一次曝光或多次曝光等方法.一次曝光法就是用三脚架把相机固定,使用长时间曝光,用快门线控制快门的开闭.多次曝光法是在一张底片上,进行两次以上的曝光,拍摄室外灯光夜景时,常采用这种方法.在天空还没有全黑时,进行第一次曝光,曝光量比正常曝光少.灯光点燃后,再进行第二次曝光.如果需要来往车灯时还可进行多次曝光.在进行多次曝光时要注意不要移动三脚架,以免影像重叠.
5. 画面有灯时,可加用十字滤光镜或星光镜,获得灯光闪烁、光芒四射的特殊效果.用彩色片拍摄时,也可加用虹镜或星女座镜,获得五彩缤纷的色彩效果.
6. 雨天的柏油马路或光滑的地面,可以表现出建筑和灯光的倒影.如果在画面里拍摄了海边、河流、湖泊旁的建筑,由于水的反光倒影,可以使岸上或周围的灯光增加亮度,衬出景物轮廓,用彩色片拍摄效果更好.
7. 夜晚使用彩色片拍摄时,一般应选用灯光片.但是如果使用日光片时,拍出的片子色调偏红橙,也能更好地表现了灯光辉煌的气氛.
8. 现在国外新出产了一种夜间摄影镜头,内部装有一个"影像增强管",它是一个能把微弱的光放大到几万倍的元件.因此,用这种镜头在夜间拍摄,可使用高的快门速度.如使用A、S、 A400度片,在明亮月光下,可使用1/500;在淡淡月光下,可使用1/60秒;即使在星光下,也可以用1/4秒以上的快门速度. -
好满——好
对满——对
豆是——就是
好生点——注意点
背时——运气差
搓脱——意思很复杂,语文不好,解释不清楚
哈批——和哈杯儿意思差不多 还含有瓜批的意思
瓜戳戳——瓜
你娃是不是摸了一对王,老子问你半天都不开腔.......——不说话
好嘴 嘴子(我原来还以为四川的都这么说也,结果好像只有绵阳说样)——就是很拽很刁的意思 例如:哦~你好嘴哦 你娃是个嘴子!
好冒人……
啊叻!——就是勒,你要怎样?
要勒!(我经常说的,常被重庆和成都人笑。。。)——不是这样的
你要爪子蛮!——你要怎样
吃sha午——吃中午饭
靠是——实在是……
架势——赶紧的……
“憋”遭——肯定要遭
“憋憋”要遭——绝对肯定要遭
撒子喃——什么?
纳门喃~——为什么呢
好扯哦~——好搞笑哦
我走过那个“卡卡” ,又饶过那个“湾湾”——就是犄角旮旯的意思
冲壳子——听某人冲壳子就是听某人瞎掰
前头有个当当——前面那个地方
“把土豆空下切”——(形容词作动词)把土豆倒下去
吼头——指里面,一般人以为是后头的意思
瓜米显眼的——也是说一个人瓜,但还有丢人的意思
装疯迷翘——装瓜
“冤” 就是非要哪个切做啥子 如“把他冤出来耍”
“JIU到”——蹲到
摆条——聊天(开始她们弄死没搞清楚我的摆条是啥意思)
哨皮——我解释不清楚这个,只可意会不可言传
扯谎lia百的——说谎话
搂你娃钩子两角——踢你屁股两脚
料翻你娃——把你整翻,就是把你整赢
快点把那爬痰li了 拿脚疵嘛
看你浓迷浓眼(很恶心)的,恼火
娄收——和浓迷浓眼意思差不多
麽那么餸(song)满
憨口水!哎呀,清鼻子出来了
来,纸拿切,快点醒~
攒劲。
弹合子——神经病的意思
那闷——那么
哪闷——怎么
例如:你哪闷那闷谭哦?——你怎么这么神经哦?
鬼米日眼德。
改手~上厕所。
dia到~拎到德意思。
胚Mer~刘海德意思。
哦屎哦尿!
哨皮 其实就是丢人的意思,脸上的皮都丢光了~~
砍脑壳的——骂人没有长脑袋
龟儿子——乌龟的儿子
烦求的很——很烦
弄凶——要好好修理你一番
抖肉——打你
巴适——安逸,舒服
三医院跑出来的——神经病(因为三医院是绵阳的精神病院)
四川话说苦说“焦苦”,说甜叫“min甜”,轻叫“捞轻”,重叫“邦重”,长叫“飞长”...哭叫“惊叫唤”~
还有打饼子 就是ML的意思
刘海还有种说法是乖乖毛,想起来特搞,小时候是经常说。
蹉跎嘛,就是挂了嘛
还有贼娃子——小偷
紧到——一直
求莫名堂,莫球名堂——莫名其妙
dia——打
仙人板板——这个哪个解释哈~~?
架势——使劲;不停的做某件事
多么多么爪子```就是好 很爪子的意思~~~!
倒拐子——胳膊肘
磕膝Mer——膝盖
鸡霸腿——鸡腿(曾经琢磨这个,越想越扯,瓜笑了半天)
卯惨了
专专)——背心的意思
塔塔——地方的意思
yao裤——短裤的意思
sewu yewu——骂人的话(什么意思?谁解释哈?)
把水niu紧——把水关好的意思
好撤把子
(还有好撤阿,就是好搞笑) -
2008-09-24
IE6默认不缓存背景图片的解决 - [web开发]
在IE6下,如果重复使用了一个图片作为背景,那么每用一次就会重新去服务器拉一次。。。给服务器带来巨大的压力。这该死的bug。微软也不出个补丁修改一下。
以下方法可解决(让IE6缓存背景图片):
document.execCommand("BackgroundImageCache", false, true); -
2008-08-05
Javascript条件判断小伎俩 - [javascript开发]
原文:http://www.gracecode.com/Archive/Display/2086
我们已经知道,null 没有任何的属性值,并且无法获取其实体(existence)值。所以 null.property 返回的是错误(error)而不是 undefined 。考虑下面的代码
if (node.nextSibling.className == ...) {
...
}在 node 或者 node.nextSibling 为空(null)的情况下,会返回错误(error)。所以,通常情况下的解决方案的代码为
if ((node) && (next = node.nextSibling) && ... ) {
...
}那么,当条件判断一多的情况下,代码会形成下面的情况
if (
(node) &&
(node.nextSibling) &&
(node.nextSibling.className == ...)
... ) {
...
}随着判断条件的不断的增加,代码会变得非常的“丑陋”。
有个小的“伎俩”,可以简化条件判断表达式。我们可以增加个空对象({})或者零(0)作为替代
if ( next = (node || 0).nextSibling) ) {
...
}那么,上述的代码就可以这样写
if (((node || 0).nextSibling || 0).className == ...) {
...
}--Split--
就个人而言,上述的从某种角度而言,代码会非常的精简。但日常实际的编码过程中,尤其是多人配合的情况下,这些代码可能会给其他开发人员造成一定的困扰。
正如 小马 所言,如果已经在使用某些框架,需要具体问题具体分析。比如上述的条件判断代码,使用 YUI 编码就可以使用
YAHOO.util.Dom.hasClass(el, className)
显得更加的精简,并且相比上述的代码更容易理解。
-
2008-08-03
为什么会有海贼王这么好看的动画! - [life生活]
海贼王是我长这么大看过无数动画片中最喜欢的。

为什么有这么好看的动画,那美妙的音乐,精彩的配音,还有出了364集也不会变质的上色(暗指火影忍者上色越来越偷工减料),真不知道他演完了怎么办?
不过要等他演完估计也要几年时间了,说不定和我儿子一起看结局了。
“老豆,海贼王大结局了,快来!”囧rz -
embed
(一)、基本语法:
embed src=url
说明:embed可以用来插入各种多媒体,格式可以是 Midi、Wav、AIFF、AU、MP3等等,
Netscape及新版的IE 都支持。url为音频或视频文件及其路径,可以是相对路径或绝对路径。
示例:<embed src="your.mid">(二)、属性设置:
1、自动播放:
语法:autostart=true、false
说明:该属性规定音频或视频文件是否在下载完之后就自动播放。
true:音乐文件在下载完之后自动播放;
false:音乐文件在下载完之后不自动播放。
示例:<embed src="your.mid" autostart=true>
<embed src="your.mid" autostart=false>2、循环播放:
语法:loop=正整数、true、false
说明:该属性规定音频或视频文件是否循环及循环次数。
属性值为正整数值时,音频或视频文件的循环次数与正整数值相同;
属性值为true时,音频或视频文件循环;
属性值为false时,音频或视频文件不循环。
示例:<embed src="your.mid" autostart=true loop=2>
<embed src="your.mid" autostart=true loop=true>
<embed src="your.mid" autostart=true loop=false>3、面板显示:
语法:hidden=ture、no
说明:该属性规定控制面板是否显示,默认值为no。
ture:隐藏面板;
no:显示面板。
示例:<embed src="your.mid" hidden=ture>
<embed src="your.mid" hidden=no>4、开始时间:
语法:starttime=mm:ss(分:秒)
说明:该属性规定音频或视频文件开始播放的时间。未定义则从文件开头播放。
示例:<embed src="your.mid" starttime="00:10">5、音量大小:
语法:volume=0-100之间的整数
说明:该属性规定音频或视频文件的音量大小。未定义则使用系统本身的设定。
示例:<embed src="your.mid" volume="10">6、容器属性:
语法:height=# width=#
说明:取值为正整数或百分数,单位为像素。该属性规定控制面板的高度和宽度。
height:控制面板的高度;
width:控制面板的宽度。
示例:<embed src="your.mid" height=200 width=200>7、容器单位:
语法:units=pixels、en
说明:该属性指定高和宽的单位为pixels或en。
示例:<embed src="your.mid" units="pixels" height=200 width=200>
<embed src="your.mid" units="en" height=200 width=200>8、外观设置:
语法:controls=console、smallconsole、playbutton、pausebutton、stopbutton、
volumelever 说明:该属性规定控制面板的外观。默认值是console。
console:一般正常面板;
smallconsole:较小的面板;
playbutton:只显示播放按钮;
pausebutton:只显示暂停按钮;
stopbutton:只显示停止按钮;
volumelever:只显示音量调节按钮。
示例:<embed src="your.mid" controls=smallconsole>
<embed src="your.mid" controls=volumelever>9、对象名称:
语法:name=#
说明:#为对象的名称。该属性给对象取名,以便其他对象利用。
示例:<embed src="your.mid" name="sound1">10、说明文字:
语法:title=#
说明:#为说明的文字。该属性规定音频或视频文件的说明文字。
示例:<embed src="your.mid" title="第一首歌">11、前景色和背景色:
语法:palette=color|color
说明:该属性表示嵌入的音频或视频文件的前景色和背景色,第一个值为前景色,第二个值为背景
色,中间用 | 隔开。color可以是RGB色(RRGGBB)也可以是颜色名,还可以是transparent
(透明)。 示例:<embed src="your.mid" palette="red|black">12、对齐方式:
语法:align=top、bottom、center、baseline、 left、right、texttop、middle、
absmiddle、absbottom
说明:该属性规定控制面板和当前行中的对象的对齐方式。
center:控制面板居中;
left:控制面板居左;
right:控制面板居右;
top:控制面板的顶部与当前行中的最高对象的顶部对齐;
bottom:控制面板的底部与当前行中的对象的基线对齐;
baseline:控制面板的底部与文本的基线对齐;
texttop:控制面板的顶部与当前行中的最高的文字顶部对齐;
middle:控制面板的中间与当前行的基线对齐;
absmiddle:控制面板的中间与当前文本或对象的中间对齐;
absbottom:控制面板的底部与文字的底部对齐。
示例:<embed src="your.mid" align=top>
<embed src="your.mid" align=center> -
2008-07-30
深入理解Javascript的函数 - [javascript开发]
函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解。javascript中的函数不同于其他的语言,每个函 数都是作为一个对象被维护和运行的。通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或者将函数作为参数传递。在继续讲述之前,先看一下函数的 使用语法:
以下为引用的内容:
function func1(…){…}
var func2=function(…){…};
var func3=function func4(…){…};
var func5=new Function();
这些都是声明函数的正确语法。它们和其他语言中常见的函数或之前介绍的函数定义方式有着很大的区别。那么在JavaScript中为什么能这么写?它所遵循的语法是什么呢?下面将介绍这些内容。
认识函数对象(Function Object)
可以用function关键字定义一个函数,并为每个函数指定一个函数名,通过函数名来进行调用。在JavaScript解释执行时,函数都是被维护为一个对象,这就是要介绍的函数对象(Function Object)。
函数对象与其他用户所定义的对象有着本质的区别,这一类对象被称之为内部对象,例如日期对象(Date)、数组对象(Array)、字符串对象 (String)都属于内部对象。这些内置对象的构造器是由JavaScript本身所定义的:通过执行new Array()这样的语句返回一个对象,JavaScript内部有一套机制来初始化返回的对象,而不是由用户来指定对象的构造方式。
在JavaScript中,函数对象对应的类型是Function,正如数组对象对应的类型是Array,日期对象对应的类型是Date一样, 可以通过new Function()来创建一个函数对象,也可以通过function关键字来创建一个对象。为了便于理解,我们比较函数对象的创建和数组对象的创建。先看数组对象:下面两行代码都是创建一个数组对象myArray:
以下为引用的内容:
var myArray=[];
//等价于
var myArray=new Array();
同样,下面的两段代码也都是创建一个函数myFunction:
function myFunction(a,b){
return a+b;
}
//等价于
var myFunction=new Function("a","b","return a+b");
通过和构造数组对象语句的比较,可以清楚的看到函数对象本质,前面介绍的函数声明是上述代码的第一种方式,而在解释器内部,当遇到这种语法时, 就会自动构造一个Function对象,将函数作为一个内部的对象来存储和运行。从这里也可以看到,一个函数对象名称(函数变量)和一个普通变量名称具有 同样的规范,都可以通过变量名来引用这个变量,但是函数变量名后面可以跟上括号和参数列表来进行函数调用。
用new Function()的形式来创建一个函数不常见,因为一个函数体通常会有多条语句,如果将它们以一个字符串的形式作为参数传递,代码的可读性差。下面介绍一下其使用语法:
以下为引用的内容:
var funcName=new Function(p1,p2,...,pn,body);
参数的类型都是字符串,p1到pn表示所创建函数的参数名称列表,body表示所创建函数的函数体语句,funcName就是所创建函数的名称。可以不指定任何参数创建一个空函数,不指定funcName创建一个无名函数,当然那样的函数没有任何意义。
需要注意的是,p1到pn是参数名称的列表,即p1不仅能代表一个参数,它也可以是一个逗号隔开的参数列表,例如下面的定义是等价的:
以下为引用的内容:
new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")
JavaScript引入Function类型并提供new Function()这样的语法是因为函数对象添加属性和方法就必须借助于Function这个类型。
函数的本质是一个内部对象,由JavaScript解释器决定其运行方式。通过上述代码创建的函数,在程序中可以使用函数名进行调用。本节开头列出的函数定义问题也得到了解释。注意可直接在函数声明后面加上括号就表示创建完成后立即进行函数调用,例如:
以下为引用的内容:
var i=function (a,b){
return a+b;
}(1,2);
alert(i);
这段代码会显示变量i的值等于3。i是表示返回的值,而不是创建的函数,因为括号“(”比等号“=”有更高的优先级。这样的代码可能并不常用,但当用户想在很长的代码段中进行模块化设计或者想避免命名冲突,这是一个不错的解决办法。
需要注意的是,尽管下面两种创建函数的方法是等价的:
以下为引用的内容:
function funcName(){
//函数体
}
//等价于
var funcName=function(){
//函数体
}
但前面一种方式创建的是有名函数,而后面是创建了一个无名函数,只是让一个变量指向了这个无名函数。在使用上仅有一点区别,就是:对于有名函数,它可以出现在调用之后再定义;而对于无名函数,它必须是在调用之前就已经定义。例如:
以下为引用的内容:
<script language="JavaScript" type="text/javascript">
<!--
func();
var func=function(){
alert(1)
}
//-->
</script>
这段语句将产生func未定义的错误,而:
以下为引用的内容:
<script language="JavaScript" type="text/javascript">
<!--
func();
function func(){
alert(1)
}
//-->
</script>
则能够正确执行,下面的语句也能正确执行:
以下为引用的内容:
<script language="JavaScript" type="text/javascript">
<!--
func();
var someFunc=function func(){
alert(1)
}
//-->
</script>
由此可见,尽管JavaScript是一门解释型的语言,但它会在函数调用时,检查整个代码中是否存在相应的函数定义,这个函数名只有是通过function funcName()形式定义的才会有效,而不能是匿名函数。
函数对象和其他内部对象的关系
除了函数对象,还有很多内部对象,比如:Object、Array、Date、RegExp、Math、Error。这些名称实际上表示一个类 型,可以通过new操作符返回一个对象。然而函数对象和其他对象不同,当用typeof得到一个函数对象的类型时,它仍然会返回字符串 “function”,而typeof一个数组对象或其他的对象时,它会返回字符串“object”。下面的代码示例了typeof不同类型的情况:
以下为引用的内容:
alert(typeof(Function)));
alert(typeof(new Function()));
alert(typeof(Array));
alert(typeof(Object));
alert(typeof(new Array()));
alert(typeof(new Date()));
alert(typeof(new Object()));
运行这段代码可以发现:前面4条语句都会显示“function”(可以理解为构造器,即构造一个对象的仪器),而后面3条语句则显示“object”(即已经被实例化了的构造器,即类的实例:对象),可见new一个function实 际上是返回一个函数。这与其他的对象有很大的不同。其他的类型Array、Object等都会通过new操作符返回一个普通对象。尽管函数本身也是一个对象,但它与普通的对象还是有区别的,因为它同时也是对象构造器,也就是说,可以new一个函数来返回一个对象,这在前面已经介绍。所有typeof返回 “function”的对象都是函数对象。也称这样的对象为构造器(constructor),因而,所有的构造器都是对象,但不是所有的对象都是构造器。
既然函数本身也是一个对象,它们的类型是function,联想到C++、Java等面向对象语言的类定义,可以猜测到Function类型的作用所在,那就是可以给函数对象本身定义一些方法和属性,借助于函数的prototype对象,可以很方便地修改和扩充Function类型的定义,例如下面扩展了函数类型Function,为其增加了method1方法,作用是弹出对话框显示"function":
以下为引用的内容:
Function.prototype.method1=function(){
alert("function");
}
function func1(a,b,c){
return a+b+c;
}
func1.method1();
func1.method1.method1();
注意最后一个语句:func1.method1.mehotd1(),它调用了method1这个函数对象的method1方法。虽然看上去有 点容易混淆,但仔细观察一下语法还是很明确的:这是一个递归的定义。因为method1本身也是一个函数,所以它同样具有函数对象的属性和方法,所有对 Function类型的方法扩充都具有这样的递归性质。
Function是所有函数对象的基础,而Object则是所有对象(包括函数对象)的基础。在JavaScript中,任何一个对象都是 Object的实例,因此,可以修改Object这个类型来让所有的对象具有一些通用的属性和方法,修改Object类型是通过prototype来完成 的:
以下为引用的内容:
Object.prototype.getType=function(){
return typeof(this);
}
var array1=new Array();
function func1(a,b){
return a+b;
}
alert(array1.getType());
alert(func1.getType());
上面的代码为所有的对象添加了getType方法,作用是返回该对象的类型。两条alert语句分别会显示“object”和“function”。
将函数作为参数传递
在前面已经介绍了函数对象本质,每个函数都被表示为一个特殊的对象,可以方便的将其赋值给一个变量,再通过这个变量名进行函数调用。作为一个变量,它可以以参数的形式传递给另一个函数,这在前面介绍JavaScript事件处理机制中已经看到过这样的用法,例如下面的程序将func1作为参数传递给func2:
以下为引用的内容:
function func1(theFunc){
theFunc();
}
function func2(){
alert("ok");
}
func1(func2);
在最后一条语句中,func2作为一个对象传递给了func1的形参theFunc,再由func1内部进行theFunc的调用。事实上,将函数作为参数传递,或者是将函数赋值给其他变量是所有事件机制的基础。
例如,如果需要在页面载入时进行一些初始化工作,可以先定义一个init的初始化函数,再通过window.onload=init;语句将其绑定到页面载入完成的事件。这里的init就是一个函数对象,它可以加入window的onload事件列表。
传递给函数的隐含参数:arguments
当进行函数调用时,除了指定的参数外,还创建一个隐含的对象——arguments。arguments是一个类似数组但不是数组的对象,说它 类似是因为它具有数组一样的访问性质,可以用arguments[index]这样的语法取值,拥有数组长度属性length。arguments对象存储的是实际传递给函数的参数,而不局限于函数声明所定义的参数列表,例如:
以下为引用的内容:
function func(a,b){
alert(a);
alert(b);
for(var i=0;i<arguments.length;i++){
alert(arguments[i]);
}
}
func(1,2,3);
代码运行时会依次显示:1,2,1,2,3。因此,在定义函数的时候,即使不指定参数列表,仍然可以通过arguments引用到所获得的参 数,这给编程带来了很大的灵活性。arguments对象的另一个属性是callee,它表示对函数对象本身的引用,这有利于实现无名函数的递归或者保证 函数的封装性,例如使用递归来计算1到n的自然数之和:
以下为引用的内容:
var sum=function(n){
if(1==n)return 1;
else return n+sum(n-1);
}
alert(sum(100));
其中函数内部包含了对sum自身的调用,然而对于JavaScript来说,函数名仅仅是一个变量名,在函数内部调用sum即相当于调用一个全局变量,不能很好的体现出是调用自身,所以使用arguments.callee属性会是一个较好的办法:(卡卡..是手册上类似的例子..)
以下为引用的内容:
var sum=function(n){
if(1==n)return 1;
else return n+arguments.callee(n-1);
}
alert(sum(100));
callee属性并不是arguments不同于数组对象的惟一特征,下面的代码说明了arguments不是由Array类型创建:
以下为引用的内容:
Array.prototype.p1=1;
alert(new Array().p1);
function func(){
alert(arguments.p1);
}
func();
运行代码可以发现,第一个alert语句显示为1,即表示数组对象拥有属性p1,而func调用则显示为“undefined”,即p1不是arguments的属性,由此可见,arguments并不是一个数组对象。
函数的apply、call方法和length属性
JavaScript为函数对象定义了两个方法:apply和call,它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数的方式有所区别:
以下为引用的内容:
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);
从函数原型可以看到,第一个参数都被取名为thisArg,即所有函数内部的this指针都会被赋值为thisArg,这就实现了将函数作为另 外一个对象的方法运行的目的。两个方法除了thisArg参数,都是为Function对象传递的参数。下面的代码说明了apply和call方法的工作 方式:
以下为引用的内容:
//定义一个函数func1,具有属性p和方法A
function func1(){
this.p="func1-";
this.A=function(arg){
alert(this.p+arg);
}
}
//定义一个函数func2,具有属性p和方法B
function func2(){
this.p="func2-";
this.B=function(arg){
alert(this.p+arg);
}
}
var obj1=new func1();
var obj2=new func2();
obj1.A("byA"); //显示func1-byA
obj2.B("byB"); //显示func2-byB
obj1.A.apply(obj2,["byA"]); //显示func2-byA,其中[“byA”]是仅有一个元素的数组,下同
obj2.B.apply(obj1,["byB"]); //显示func1-byB
obj1.A.call(obj2,"byA"); //显示func2-byA
obj2.B.call(obj1,"byB"); //显示func1-byB
可以看出,obj1的方法A被绑定到obj2运行后,整个函数A的运行环境就转移到了obj2,即this指针指向了obj2。同样obj2的函数B也可以绑定到obj1对象去运行。代码的最后4行显示了apply和call函数参数形式的区别。
与arguments的length属性不同,函数对象还有一个属性length,它表示函数定义时所指定参数的个数,而非调用时实际传递的参数个数。例如下面的代码将显示2:
以下为引用的内容:
function sum(a,b){
return a+b;
}
alert(sum.length);
深入认识JavaScript中的this指针
this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象。在实现对象的方法时,可以使用this指针来获得该对象自身的引用。
和其他面向对象的语言不同,JavaScript中的this指针是一个动态的变量,一个方法内的this指针并不是始终指向定义该方法的对象的,在上一节讲函数的apply和call方法时已经有过这样的例子。为了方便理解,再来看下面的例子:
以下为引用的内容:
<script language="JavaScript" type="text/javascript">
<!--
//创建两个空对象
var obj1=new Object();
var obj2=new Object();
//给两个对象都添加属性p,并分别等于1和2
obj1.p=1;
obj2.p=2;
//给obj1添加方法,用于显示p的值
obj1.getP=function(){
alert(this.p); //表面上this指针指向的是obj1
}
//调用obj1的getP方法
obj1.getP();
//使obj2的getP方法等于obj1的getP方法
obj2.getP=obj1.getP;
//调用obj2的getP方法
obj2.getP();
//-->
</script>
从代码的执行结果看,分别弹出对话框显示1和2。由此可见,getP函数仅定义了一次,在不同的场合运行,显示了不同的运行结果,这是有 this指针的变化所决定的。在obj1的getP方法中,this就指向了obj1对象,而在obj2的getP方法中,this就指向了obj2对 象,并通过this指针引用到了两个对象都具有的属性p。
由此可见,JavaScript中的this指针是一个动态变化的变量,它表明了当前运行该函数的对象。由this指针的性质,也可以更好的理解JavaScript中对象的本质:一个对象就是由一个或多个属性(方法)组成的集合。每个集合元素不是仅能属于一个集合,而是可以动态的属于多个集合。这样,一个方法(集合元素)由谁调用,this指针就指向谁。实际上,前面介绍的apply方法和call方法都是通过强制改变this指针的值来实现的,使this指针指向参数所指定的对象,从而达到将一个对象的方法作为另一个对象的方法运行。
每个对象集合的元素(即属性或方法)也是一个独立的部分,全局函数和作为一个对象方法定义的函数之间没有任何区别,因为可以把全局函数和变量看作为window对象的方法和属性。也可以使用new操作符来操作一个对象的方法来返回一个对象,这样一个对象的方法也就可以定义为类的形式,其中的 this指针则会指向新创建的对象。在后面可以看到,这时对象名可以起到一个命名空间的作用,这是使用JavaScript进行面向对象程序设计的一个技巧。例如:
以下为引用的内容:
var namespace1=new Object();
namespace1.class1=function(){
//初始化对象的代码
}
var obj1=new namespace1.class1();
这里就可以把namespace1看成一个命名空间。
由于对象属性(方法)的动态变化特性,一个对象的两个属性(方法)之间的互相引用,必须要通过this指针,而其他语言中,this关键字是可以省略的。如上面的例子中:
以下为引用的内容:
obj1.getP=function(){
alert(this.p); //表面上this指针指向的是obj1
}
这里的this关键字是不可省略的,即不能写成alert(p)的形式。这将使得getP函数去引用上下文环境中的p变量,而不是obj1的属性。
-
2008-07-17
Javascript在IE和Firefox中的区别 - [javascript开发]
1. 当一个对象为不可见时,在IE中是不可以设置它集中焦点的,但是在Firefox里可以
2. 向表(Table)追加行:
在FF、 Safari、Opera等浏览器中,用document.createElement创建行后用document.appendChild将行直接添加到表上。但是在IE里不可以,而且没有任何错误提示,这时候,需要为表添加表体(tbody),然后将新创建的行添加到表体(tbody),
3. childNodes的不同:Firefox把回车后的空白当作文本节点,而ie不是
4. innerText是IE专有的方法,textContent是Firefox专有的,innerHTML则两者都兼容
5. 设置某个node对象的style class名称。
ie中要设置某个node的class用”className”作为attr来set或者get。
ff等其它的浏览器用”class”作为attr来set或者get。
6. 事件对象。ie用eventff用evnt
7. 事件作用对象。ie用objEvent.srcElement,ff用objEvent.target
8,document.form.item 问题。
ie中用document.formName.item("itemName")
ff中改用 document.formName.elements["elementName"]
9。集合类对象取用时使用 (),IE 能接受,MF 不能。解决方法:改用 [] 作为下标运算
10,window.event 无法在 fF 上运行
11,HTML 对象的 id 作为对象名的问题
现有问题:在 IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 fF 中不能。
解决方法:用 getElementById("idName") 代替 idName 作为对象变量使用
11,变量名与某 HTML 对象 id 相同的问题
现有问题: fF中,对象 id 不作为 HTML 对象的名称,所以可使用与 HTML 对象 id 相同的变量名,IE 中不能
解决方法:在声明变量时,一律加上 var ,以避免歧义,这样在 IE 中亦可正常运行。此外,最好不要取与 HTML 对象 id 相同的变量名,以减少错误
12,event.x 与 event.y 问题
现有问题:在IE 中,event 对象有 x, y 属性,fF中没有。
解决方法:
在fF中,与event.x 等效的是 event.pageX。但event.pageX IE中没有。
故采用 event.clientX 代替 event.x。在IE 中也有这个变量。
event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。
如果要完全一样,可以稍麻烦些:mX = event.x ? event.x : event.pageX;然后用 mX 代替 event.x
13,父结点的问题
在 ff中没有 parentElement parement.children 而用 parentNode parentNode.childNodes。childNodes的下标的含义在IE和fF中不同,fF使用DOM规范,childNodes中会插入空白文本节点。一般可以通过node.getElementsByTagName()来回避这个问题。
14,const 问题
现有问题:在 IE 中不能使用 const 关键字。如 const constVar = 32; 在IE中这是语法错误。
解决方法:不使用 const ,以 var 代替。
15,body 对象
fF的body在body标签没有被浏览器完全读入之前就存在,而IE则必须在body完全被读入之后才存在
16,nodeName 和 tagName 问题
现有问题:在ff中,所有节点均有 nodeName 值,但 textNode 没有 tagName 值。在 IE 中,nodeName 的使用好象有问题。
解决方法:使用 tagName,但应检测其是否为空
17,元素属性
IE下 input.type属性为只读,但是ff下可以修改
18,document.getElementsByName() 和 document.all[name] 的问题
现有问题:在 IE 中,getElementsByName()、document.all[name] 均不能用来取得 div 元素(是否还有其它不能取的元素还不知道)。
19, 对空格符的处理。按照HTML的标准,空格字符是 。在ff中,如果你误写成 (少了一个分号)一定不会被FireFox认为是空格,FireFox会认为它是 。而在IE中,如果你误写成 (少了一个分号)IE智能地认为它是空格。
20,对注释的处理。
按照HTML的标准,注释的操作是放在<!--和-->之间的,而且注释中不能有--,否则会产生 HTML解析错误 -
今天刚刚一周年,回首往事总是觉得是快的,不管这一年经历了什么,在浅层记忆中总是会觉得快乐的。呵呵。一年可以让人变得浮躁,因为这一年中你在工作上的成长肯定是飞快的(除非你没有认证对待它)。会让人觉得似乎这份工作对我来说已经没有什么挑战了,变得无趣了。这样不好,哈哈。
希望快点升职加薪,其实也不一定要升职啦,加薪就行了。

master乌龟说:yesterday is history, tomorrow is mystery, today is a gift, that is why it is called the "present"..








