Archive for the ‘ 行为 ’ Category

js中的相等与不等运算

1,完全相同的比较( === ):用来比较不进行转换是否相等

2,不完全相同的比较( == ):用来比较进行转换是否相等

3,不完全相同的比较( != ):用来比较进行转换是否不相等

4,完全相同的比较( !== )用来比较不进行转换是否不相等

例如:

var a = “100″;
var b = 100;

alert(a == b); // true
alert(a === b); // false

== 比较将返回真,因为 “100” 首先转换为数字 100, 然后与数字 100 进行比较,结果相等。
=== 比较将返回假,因为字符串 ”100” 不经过转换的话,与数字 100 不相等。

!= 用于比较在转换的情况下,是否不相等。

!== 用于比较在不转换的情况下,是否不相等。

alert(a != b); // false
alert(a !== b); // true

第一种情况将返回假,因为转换后是相等的。第二种情况将返回真,因为不经过转换的话,他们一个是字符串,一个是数字,是不相等的。

本文链接地址: js中的相等与不等运算  拓子博客

【转】解剖JavaScript中的null和undefined

在JavaScript开发中,被人问到:null与undefined到底有啥区别?

一时间不好回答,特别是undefined,因为这涉及到undefined的实现原理。于是,细想之后,写下本文,请各位大侠拍砖。

总所周知:null == undefined

但是:null !== undefined

那么这两者到底有啥区别呢?

请听俺娓娓道来…

 

null

这是一个对象,但是为空。因为是对象,所以 typeof null  返回 ‘object’ 。

null 是 JavaScript 保留关键字。

null 参与数值运算时其值会自动转换为 0 ,因此,下列表达式计算后会得到正确的数值:

表达式:123 + null    结果值:123

表达式:123 * null    结果值:0

 

undefined

undefined是全局对象(window)的一个特殊属性,其值是未定义的。但 typeof undefined 返回 ‘undefined’ 。

虽然undefined是有特殊含义的,但它确实是一个属性,而且是全局对象(window)的属性。请看下面的代码:

    alert(‘undefined’ in window);   //输出:truevar anObj = {};
alert(‘undefined’ in anObj);    //输出:false

从中可以看出,undefined是window对象的一个属性,但却不是anObj对象的一个属性。

 

 

注意:尽管undefined是有特殊含义的属性,但却不是JavaScript的保留关键字。

undefined参与任何数值计算时,其结果一定是NaN。

随便说一下,NaN是全局对象(window)的另一个特殊属性,Infinity也是。这些特殊属性都不是JavaScript的保留关键字!

 

提高undefined性能

当我们在程序中使用undefined值时,实际上使用的是window对象的undefined属性。

同样,当我们定义一个变量但未赋予其初始值,例如:

var aValue;

这时,JavaScript在所谓的预编译时会将其初始值设置为对window.undefined属性的引用,

于是,当我们将一个变量或值与undefined比较时,实际上是与window对象的undefined属性比较。这个比较过程中,JavaScript会搜索window对象名叫‘undefined’的属性,然后再比较两个操作数的引用指针是否相同。

由于window对象的属性值是非常多的,在每一次与undefined的比较中,搜索window对象的undefined属性都会花费时 间。在需要频繁与undefined进行比较的函数中,这可能会是一个性能问题点。因此,在这种情况下,我们可以自行定义一个局部的undefined变 量,来加快对undefined的比较速度。例如:

    function anyFunc()
{
var undefined;          //自定义局部undefined变量

if(x == undefined)      //作用域上的引用比较

while(y != undefined)   //作用域上的引用比较

};

其中,定义undefined局部变量时,其初始值会是对window.undefined属性值的引用。新定义的局部undefined变 量存在与该函数的作用域上。在随后的比较操作中,JavaScript代码的书写方式没有任何的改变,但比较速度却很快。因为作用域上的变量数量会远远少 于window对象的属性,搜索变量的速度会极大提高。

这就是许多前端JS框架为什么常常要自己定义一个局部undefined变量的原因!

 

原著:李战(leadzen).杭州-阿里软件 2009-2-18
原址:http://blog.csdn.net/leadzen/archive/2009/02/17/3899392.aspx

[转]如何编写兼容各主流邮箱的HTML邮件

最近一个需求中遇到了发送邮件的功能,发现很多css在邮件里是有限制的,通过对以前的各位达人总结的学习,解决了这个问题,现转载如下。

几乎每个会员制网站都需要通过后台发送邮件来与会员进行沟通,如注册确认、营销推广。这些由站方发给会员的信件,往往纯文本格式已不能满足界面和交互的要求,这时候我们就需要发送HTML页面。由于HTML邮件不是独立的HOST在本站的页面,是寄人篱下的。所以编写HTML邮件与编写HTML页面有很大的不同。因为,各面向网民的主流邮箱都或多或少的会对它们接收到的HTML邮件在后台进行过滤。毫无疑问,JS代码是被严格过滤掉的,包括所有的事件监听属性,如onclick、onmouseover,这是基于邮件安全性的考虑。不仅如此,CSS代码也会被部分过滤。本人要讲的就是如何编写不被各大主流邮箱过滤的,能正常显示的HTML邮件。

首先,我们先来看看邮箱是如何展现HTML邮件的。我本人没有做过邮件系统,况且各大邮箱后台的过滤算法也不是那么容易可以让外人知道的。所以,我们只能通过前端展现,来推测哪些是被邮箱接受的写法,而哪些又是会被过滤掉的。通过对 gmail、hotmail、163、sohu、sina几个邮箱的分析,我把邮箱分为两类:
第一类包括gmail、hotmail、sohu,这类邮箱,邮件内容是被布局在整个邮箱页面中的某个div中。

第二类,包括163、sina,这类邮箱,邮件内容被布局在独立的iframe中。

熟悉HTML的朋友都知道,iframe内容是作为独立的document,与父页面的元素和CSS是互不相干的,几乎可以作为一个独立的页面来对待。而如果如果邮件内容是在div中,那么邮件内容是作为整个邮箱页面的一个组成部分。显然,以iframe作为展现方式的邮箱,对邮件内容就会宽容许多,因为它给了你一个足够独立的表现空间。而div就不是那么客气了。试想一下,如果你在你的邮件里写上这么一句CSS,是不是整个邮箱的展现页面上字体都变成20px而因此乱了套:
<style type=”text/css”>
body {font-size:20px}
</style>
我们需要写兼容各邮箱的统一邮件模板,那么必然就要避开以上这种外联CSS写法,另外类似于float、position等成非正常内容流的style也会被过滤,假如你写了,很可能会影响到外部邮箱的表现。

下面我列出一些编写原则:
1、全局规则之一,不要写<style>标签、不要写class,所有CSS都用style属性,什么元素需要什么样式就用style写内联的CSS。
2、全局规则之二,少用图片,邮箱不会过滤你的img标签,但是系统往往会默认不载入陌生来信的图片,如果用了很多图片的邮件,在片没有载入的情况下,丑陋无比甚至看不清内容,没耐心的用户直接就删除了。图片上务必加上alt。
3、不要在style里面写float、position这些style,因为会被过滤。那么如何实现左右布局或者更复杂的布局呢?用table。
4、 style内容里面background可以设置color,但是img会被过滤,就是说不能通过CSS来设置背景图片了。但是有一个很有意思的元素属性,也叫background,里面可以定义一个图片路径,这是个不错的替代方案,虽然这样功能有限,比如无法定位背景图片了,有总比没有好。例如要给一个单元格加一个背景,必须这样写:
<td background=”http://image1.koubei.com/images/common/logo_koubei.gif”></td>
5、div模式的邮箱不支持flash,iframe模式的有待验证。

最后提一句,sohu的邮箱很怪异,会在每个文本段后面加一个空格,导致原本正常的排版一行放不下而换行,从而使某些布局错乱。所以,如果你要兼容sohu邮箱的话,遇到一些紧凑的布局就要格外小心了,尽量减少文本段的数量,留足宽度。




HTML细节

就目前来说,如果要做一个email页面,为了保证最大的兼容性,有以下几点需要注意:

对于纯文本邮件:


  1. 邮件标题不要超过18个字;
  2. 每行不要超过34个字。


对于HTML邮件:

  1. 邮件标题不要超过18个字;
  2. HTML代码和图片尽量不要超过50kb;
  3. 页面宽度推荐500px,最大不要超过600px;
  4. 避免使用边缘的、非主流的HTML技术;
  5. 不使用css来布局,应该使用表格来布局;
  6. 不使用外联的css样式,而使用font标签来定义样式,定义链接颜色时也是如此,写法如下: <font style="font-family:arial,helvetica; font-size:10pt; color:#000000">
    ...
    </font>
  7. 不使用Flash、Java、Javascript、frames、i-frames、ActiveX 以及 DHTML ;
  8. body和meta之类的标签是可以无视的,因为在很多邮箱系统里它会被过滤;
  9. 如果整个邮件有用到背景色或背景图,建议用以下方式处理:<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%">
    <tr>
    <td width="100%" height="100%" bgcolor=".....">
    <!--- 邮件内容 -->
    </td>
    </tr>
    </table>
  10. 有背景图片的时候,我们要采用这种写法:<table background="background.gif" cellspacing="0" cellpadding="0">


原文[http://dengminhui.javaeye.com/blog/664457]

网页图片无缝循环滚动html代码

图片循环滚动代码
图片无缝滚动代码

先介绍一下它的实现思路:一个设定宽度并且隐藏超出它宽度的内容的容器demo,里面放demo1和demo2,demo1是滚动内容,demo2为demo1的直接克隆,通过不断改变demo1的scrollTop或者scrollLeft达到滚动的目的,当滚动至demo1与demo2的交界处时直接跳回初始位置,因为demo1与demo2一样,所以分不出跳动的瞬间,从而达到“无缝”滚动的目的。

先了解一下对象的几个的属性:
innerHTML:设置或获取位于对象起始和结束标签内的 HTML
scrollHeight: 获取对象的滚动高度。
scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
scrollWidth:获取对象的滚动宽度
offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
offsetLeft:获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
offsetTop:获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置
offsetWidth:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的宽度

向上滚动的代码:
<div id=demo style=overflow:hidden;height:400;width:160;background:#214984;color:#ffffff><table align=top cellpadding=0 cellspace=0 border=0><tr><td id=demo1 valign=top><img src=”pic/1.jpg” width=”156″ height=”200″ /><br><img src=”pic/2.jpg” width=”160″ height=”198″ /><br><img src=”pic/3.jpg” width=”155″ height=”200″ /><br><img src=”pic/4.jpg” width=”157″ height=”200″ /></td></tr><tr><td id=demo2 valign=top></td></tr></table></div>
<script>
var speed=30
demo2.innerHTML=demo1.innerHTML//克隆demo1为demo2
function Marquee(){
if(demo2.offsetHeight-demo.scrollTop<=0)//当滚动至demo1与demo2交界时
demo.scrollTop-=demo1.offsetHeight//demo跳到最顶端
else{
demo.scrollTop++
}
}
var MyMar=setInterval(Marquee,speed)//设置定时器
demo.onmouseover=function() {clearInterval(MyMar)}//鼠标移上时清除定时器达到滚动停止的目的
demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)}//鼠标移开时重设定时器
</script>

向下滚动:
<div id=demo style=overflow:hidden;height:400;width:160;background:#214984;color:#ffffff><table align=top cellpadding=0 cellspace=0 border=0><tr><td id=demo1 valign=top><img src=”pic/1.jpg” width=”156″ height=”200″ /><br><img src=”pic/2.jpg” width=”160″ height=”198″ /><br><img src=”pic/3.jpg” width=”155″ height=”200″ /><br><img src=”pic/4.jpg” width=”157″ height=”200″ /></td></tr><tr><td id=demo2 valign=top></td></tr></table></div>
<script>
var speed=30
demo2.innerHTML=demo1.innerHTML
function Marquee(){
if(demo.scrollTop<=0)
demo.scrollTop+=demo2.offsetHeight
else{
demo.scrollTop–
}
}
var MyMar=setInterval(Marquee,speed)
demo.onmouseover=function() {clearInterval(MyMar)}
demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)}
</script>

向左滚动:
<div id=demo style=overflow:hidden;height:200;width:500;background:#214984;color:#ffffff><table align=left cellpadding=0 cellspace=0 border=0><tr><td id=demo1 valign=top><img src=”pic/1.jpg” width=”156″ height=”200″ /><img src=”pic/2.jpg” width=”160″ height=”198″ /><img src=”pic/3.jpg” width=”155″ height=”200″ /><img src=”pic/4.jpg” width=”157″ height=”200″ /></td><td id=demo2 valign=top></td></tr></table></div>
<script>
var speed=30
demo2.innerHTML=demo1.innerHTML
function Marquee(){
if(demo2.offsetWidth-demo.scrollLeft<=0)
demo.scrollLeft-=demo1.offsetWidth
else{
demo.scrollLeft++
}
}
var MyMar=setInterval(Marquee,speed)
demo.onmouseover=function() {clearInterval(MyMar)}
demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)}
</script>

向右滚动:
<div id=demo style=overflow:hidden;height:200;width:500;background:#214984;color:#ffffff><table align=left cellpadding=0 cellspace=0 border=0><tr><td id=demo1 valign=top><img src=”pic/1.jpg” width=”156″ height=”200″ /><img src=”pic/2.jpg” width=”160″ height=”198″ /><img src=”pic/3.jpg” width=”155″ height=”200″ /><img src=”pic/4.jpg” width=”157″ height=”200″ /></td><td id=demo2 valign=top></td></tr></table></div>
<script>
var speed=30
demo2.innerHTML=demo1.innerHTML
function Marquee(){
if(demo.scrollLeft<=0)
demo.scrollLeft+=demo2.offsetWidth
else{
demo.scrollLeft–
}
}
var MyMar=setInterval(Marquee,speed)
demo.onmouseover=function() {clearInterval(MyMar)}
demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)}
</script>

<!–无缝向左循环代码开始–>
<div id=”mhmove” style=”overflow:hidden;width:800px;margin:0 auto 0;”>
<table width=”800px” border=”0″ cellspacing=”0″ cellpadding=”0″>
<tr>

<td width=”800px” id=”mhmove1″><table width=”800px” border=”0″ cellpadding=”0″ cellspacing=”0″>
<tr>

<td width=”166″ align=”center”><img src=”tupian/gumushi1538.4m.jpg” width=”166″ height=”117″ border=”0″ usemap=”#Map2″ /></td>

<td width=”166″ align=”center”> <img src=”tupian/tupian1/pingchuanghe7[1].jpg” width=”166″ height=”117″ border=”0″ usemap=”#Map”/></td>

<td width=”166″ align=”center”><img src=”tupian/tupian1/1[2].jpg” width=”166″ height=”117″ border=”0″ usemap=”#Map3″ /></td>

<td width=”166″ align=”center”><img src=”tupian/tupian1/6[1].jpg” width=”166″ height=”117″ border=”0″ usemap=”#Map4″  /></td>

<td width=”172″ align=”center”><img src=”tupian/tupian1/92[1].jpg” width=”166″ height=”117″ border=”0″ usemap=”#Map5″  /></td>

<td width=”172″ align=”center”><img src=”tupian/dujuan_da2.jpg” width=”166″ height=”117″ border=”0″ usemap=”#Map6″ /></td>
</tr>

</table></td>
<td width=”50″ id=”mhmove2″>&nbsp;</td>
</tr>
</table>
</div>

<script>
var speed=40 ;
mhmove2.innerHTML=mhmove1.innerHTML;
function Marquee3(){
if(mhmove2.offsetWidth-mhmove.scrollLeft<=0)
mhmove.scrollLeft-=mhmove1.offsetWidth;
else{
mhmove.scrollLeft++;
}
}
function Marquee4(){
if(mhmove2.offsetHeight-mhmove.scrollTop<=0)
mhmove.scrollTop-=mhmove1.offsetHeight;
else{
mhmove.scrollTop++;
}
}
var MyMar2=setInterval(Marquee3,speed);
mhmove.onmouseover=function() {clearInterval(MyMar2)}
mhmove.onmouseout=function() {MyMar2=setInterval(Marquee3,speed)}
</script>
<!–无缝循环代码结束–>

源文件下载:imgcold (122)

DOM标准与IE的html元素事件模型区别

事件

HTML元素事件是浏览器内在自动产生的,当有事件发生时html元素会向外界(这里主要指元素事件的订阅者)发出各种事件,如click,onmouseover,onmouseout等等。

DOM事件流

DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。

主流浏览器的事件模型

早在2004前在HTML元素事件的订阅,发送,传播,处理模型上各浏览器实现并不一致,直到DOM Level3中规定后,多数主流浏览器才陆陆续续支持DOM标准的事件处理模型 – 捕获型与冒泡型。
目前除IE浏览器外,其它主流的Firefox, Opera, Safari都支持标准的DOM事件处理模型。IE仍然使用自己的模型,即冒泡型,它模型的一部份被DOM采用,这点对于开发者来说也是有好处的,只使用 DOM标准,IE都共有的事件处理方式才能有效的跨浏览器。

冒泡型事件(Bubbling)

这是IE浏览器对事件模型的实现,也是最容易理解的,至少笔者觉得比较符合实际的。冒泡,顾名思义,事件像个水中的气泡一样一直往上冒,直到顶端。从 DOM树型结构上理解,就是事件由叶子结点沿祖先结点一直向上传递直到根结点;从浏览器界面视图HTML元素排列层次上理解就是事件由具有从属关系的最确定的目标元素一直传递到最不确定的目标元素.

捕获型事件(Capturing)

Netscape Navigator的实现,它与冒泡型刚好相反,由DOM树最顶层元素一直到最精确的元素,这个事件模型对于开发者来说(至少是我..)有点费解,因为直观上的理解应该如同冒泡型,事件传递应该由最确定的元素,即事件产生元素开始。
但这个模型在某些情况下也是很有用的,接下来会讲解到。

DOM标准事件模型

因为两个不同的模型都有其优点和解释,DOM标准支持捕获型与冒泡型,可以说是它们两者的结合体。它可以在一个DOM元素上绑定多个事件处理器,并且在处理函数内部,this关键字仍然指向被绑定的DOM元素,另外处理函数参数列表的第一个位置传递事件event对象。

首先是捕获式传递事件,接着是冒泡式传递,所以,如果一个处理函数既注册了捕获型事件的监听,又注册冒泡型事件监听,那么在DOM事件模型中它就会被调用两次。

注册与移除事件监听器

注册事件监听器,或又称订阅事件,当元素事件发生时浏览器回调该监听函数执行事件处理。目前主流浏览器中有两种注册事件的方法,一种是IE浏览器的,另一种是DOM标准的。

1.直接JS或HTML挂载法

1 <div onclick="alert(this.innerHTML);">
1 element.onclick = function(){alert(this.innerHTML);}

移除时将事件属性设为null即可,这个也是最常用的方法了,优缺点也是显然的:

  • 简单方便,在HTML中直接书写处理函数的代码块,在JS中给元素对应事件属性赋值即可
  • IE与DOM标准都支持的一种方法,它在IE与DOM标准中都是在事件冒泡过程中被调用的。
  • 可以在处理函数块内直接用this引用注册事件的元素
  • 要给元素注册多个监听器,就不能用这方法了

2. IE下注册多个事件监听器与移除监听器方法

IE浏览器中HTML元素有个attachEvent方法允许外界注册该元素多个事件监听器,例如

1 element.attachEvent('onclick', observer);

attachEvent接受两个参数。第一个参数是事件名称,第二个参数observer是回调处理函数。这里得说明一下,有个经常会出错的地方,IE下利用attachEvent注册的处理函数调用时this指向不再是先前注册事件的元素,这时的this为window对象了,笔者很奇怪IE为什么要这么做,完全看不出好处所在。
要移除先前注册的事件的监听器,调用element的detachEvent方法即可,参数相同。

1 element.detachEvent('onclick', observer);

3. DOM标准下注册多个事件监听器与移除监听器方法

实现DOM标准的浏览器与IE浏览器中注册元素事件监听器方式有所不同,它通过元素的addEventListener方法注册,该方法既支持注册冒泡型事件处理,又支持捕获型事件处理。

1 element.addEventListener('click', observer, useCapture);

addEventListener方法接受三个参数。第一个参数是事件名称,值得注意的是,这里事件名称与IE的不同,事件名称是没’on’开头的;第二个参数observer是回调处理函数;第三个参数注明该处理回调函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用

移除已注册的事件监听器调用element的removeEventListener即可,参数不变.

1 element.removeEventListener('click', observer, useCapture);

跨浏览器的注册与移除元素事件监听器方案

弄清楚DOM标准与IE的注册元素事件监听器之间的异同后,就可以实现一个跨浏览器的注册与移除元素事件监听器方案:

01 //注册
02 function addEventHandler(element, evtName, callback, useCapture) {
03 //DOM标准
04 if (element.addEventListener) {
05 element.addEventListener(evtName, callback, useCapture);
06 } else {
07 //IE方式,忽略useCapture参数
08 element.attachEvent('on' + evtName, callback);
09 }
10 }
11
12 //移除
13 //注册
14 function removeEventHandler(element, evtName, callback, useCapture) {
15 //DOM标准
16 if (element.removeEventListener) {
17 element.removeEventListener(evtName, callback, useCapture);
18 } else {
19 //IE方式,忽略useCapture参数
20 element.dettachEvent('on' + evtName, callback);
21 }
22 }

如何取消浏览器事件的传递与事件传递后浏览器的默认处理

先说明取消事件传递与浏览器事件传递后的默认处理是两个不同的概念,可能很多同学朋友分不清,或者根本不存在这两个概念。

取消事件传递是指,停止捕获型事件或冒泡型事件的进一步传递。例如上图中的冒泡型事件传递中,在body处理停止事件传递后,位于上层的document的事件监听器就不再收到通知,不再被处理。

事件传递后的默认处理是指,通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作)。例如,如果表单中input type 属性是 “submit”,点击后在事件传播完浏览器就自动提交表单。又例如,input 元素的 keydown 事件发生并处理后,浏览器默认会将用户键入的字符自动追加到 input 元素的值中。

要取消浏览器的件传递,IE与DOM标准又有所不同。

在IE下,通过设置event对象的cancelBubble为true即可。

1 function someHandle() {
2 window.event.cancelBubble = true;
3 }

DOM标准通过调用event对象的stopPropagation()方法即可。

1 function someHandle(event) {
2 event.stopPropagation();
3 }

因些,跨浏览器的停止事件传递的方法是:

1 function someHandle(event) {
2 event = event || window.event;
3 if(event.stopPropagation)
4 event.stopPropagation();
5 else event.cancelBubble = true;
6 }

取消事件传递后的默认处理,IE与DOM标准又不所不同。

在IE下,通过设置event对象的returnValue为false即可。

1 function someHandle() {
2 window.event.returnValue = false;
3 }

DOM标准通过调用event对象的preventDefault()方法即可。

1 function someHandle(event) {
2 event.preventDefault();
3 }

因些,跨浏览器的取消事件传递后的默认处理方法是:

1 function someHandle(event) {
2 event = event || window.event;
3 if(event.preventDefault)
4 event.preventDefault();
5 else event.returnValue = false;
6 }

捕获型事件模型与冒泡型事件模型的应用场合

标准事件模型为我们提供了两种方案,可能很多朋友分不清这两种不同模型有啥好处,为什么不只采取一种模型。
这里抛开IE浏览器讨论(IE只有一种,没法选择)什么情况下适合哪种事件模型。

1. 捕获型应用场合

捕获型事件传递由最不精确的祖先元素一直到最精确的事件源元素,传递方式与操作系统中的全局快捷键与应用程序快捷键相似。当一个系统组合键发生时,如果注册了系统全局快捷键监听器,该事件就先被操作系统层捕获,全局监听器就先于应用程序快捷键监听器得到通知,也就是全局的先获得控制权,它有权阻止事件的进一步传递。所以捕获型事件模型适用于作全局范围内的监听,这里的全局是相对的全局,相对于某个顶层结点与该结点所有子孙结点形成的集合范围。

例如你想作全局的点击事件监听,相对于document结点与document下所有的子结点,在某个条件下要求所有的子结点点击无效,这种情况下冒泡模型就解决不了了,而捕获型却非常适合,可以在最顶层结点添加捕获型事件监听器,伪码如下:

1 function globalClickListener(event) {
2 if(canEventPass == false) {
3 //取消事件进一步向子结点传递和冒泡传递
4 event.stopPropagation();
5 //取消浏览器事件后的默认执行
6 event.preventDefault();
7 }
8 }

这样一来,当canEventPass条件为假时,document下所有的子结点click注册事件都不会被浏览器处理。

2. 冒泡型的应用场合

可以说我们平时用的都是冒泡事件模型,因为IE只支持这模型。这里还是说说,在恰当利用该模型可以提高脚本性能。在元素一些频繁触发的事件中,如 onmousemove, onmouseover,onmouseout,如果明确事件处理后没必要进一步传递,那么就可以大胆的取消它。此外,对于子结点事件监听器的处理会对父层监听器处理造成负面影响的,也应该在子结点监听器中禁止事件进一步向上传递以消除影响。

综合案例分析

最后结合下面HTML代码作分析:

01 <body onclick="alert('current is body');">
02 <div id="div0" onclick="alert('current is '+this.id)">
03 <div id="div1" onclick="alert('current is '+this.id)">
04 <div id="div2">
05 <div id="event_source"
06 onclick="alert('current is '+this.id)"
07 style="height:200px;width:200px;background-color:red;">
08 </div>
09 </div>
10 </div>
11 </div>
12 </body>

HTML运行后点击红色区域,这是最里层的DIV,根据上面说明,无论是DOM标准还是IE,直接写在html里的监听处理函数是事件冒泡传递时调用的,由最里层一直往上传递,所以会先后出现
current is event_source
current is div2
current is div1
current is div0
current is body

添加以下片段:

1 var div2 = document.getElementById('div2');
2 addEventHandler(div2, 'click', function(event){
3 event = event || window.event;
4 if(event.stopPropagation)
5 event.stopPropagation();
6 else event.cancelBubble = true;
7 }, false);

当点击红色区域后,根据上面说明,在泡冒泡处理期间,事件传递到div2后被停止传递了,所以div2上层的元素收不到通知,所以会先后出现:
current is event_source
current is div2

在支持DOM标准的浏览器中,添加以下代码:

1 document.body.addEventListener('click', function(event){
2 event.stopPropagation();
3 }, true);

以上代码中的监听函数由于是捕获型传递时被调用的,所以点击红色区域后,虽然事件源是ID为event_source的元素,但捕获型选传递,从最顶层开始,body结点监听函数先被调用,并且取消了事件进一步向下传递,所以只会出现
current is body

转自:http://tonyqiu.javaeye.com/blog/668129

FF(火狐)下如何使连续长字段自动换行

众所周知IE中直接使用 word-wrap:break-word 就可以了, 这里FF中我们使用JS插入 的方法来解决


提示:你可以先修改部分代码再运行。