这是第一篇技术性博客。

因为最近做的web版前端求职简历算是告一段落了(点此看简历)。(稍微记录下吧:自从确定简历的简笔画风格后(因为刚开始设想的蓝天白云大树啥的不仅图片特难找而且做着做着就觉得有点俗了,简笔画这种黑白风格对PS技术要求就很低了),大概花了写这篇博客前的4、5天做好的(额,上班时间也在做,因为最近公司不忙))总之就是在做简历的过程中感觉对js事件了解多了一点,所以先记下来,以后争取能再完善。

  • 避免重复注册事件

这是我曾经在QQ群里求助的一个问题,感觉看过的书里也没有特意提到。具体来说就是一个元素相同的事件处理程序注册多次的话,每次执行时会把以前累计注册的事件都执行。这个问题在以下情况最常见:在元素aa的事件里创造了元素bb并给它添加了事件,如此一来每次a相应事件发生时都会给bb添加事件。

<!DOCTYPE html>
<html>
<style type="text/css">
#aa{background-color:lightgreen;}
#bb{background-color:pink;}
</style>
<body>
<p id="aa" >aa</p>
<p id="bb" >bb</p>

</body>
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"> </script>
<script type="text/javascript"> $(function(){
var i=0;
$('#aa').click(function(){
i++;
$('#bb').click(function(){
alert(i);
})
})
}) </script> </html>

运行代码

如#aa和#bb为兄弟节点:

$(function(){ var i=0;
$('#aa').click(function(){
i++;
$('#bb').click(function(){
alert(i);
})
})
})

如上,则第一次click #aa再click #bb时,  弹出1;

    第二次click #aa再click #bb时,连续弹出2、2;

    第三次click #aa再click #bb时,连续弹出3、3、3.

解决办法:先删除事件再添加,unbind以后再bind。

  • 重要的事件对象

我们知道在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息,包括导致事件的元素、事件类型等。其中的常用有:

1. event.type(被触发的事件的类型,如“click”);

2.event.eventPhase(调用事件处理程序的阶段:1表示捕获阶段,2表示"处于目标",3表示冒泡阶段)

3.event.target和event.currentTarget

4.event.stopPropagation()

这就涉及到事件流了,"DOM2级事件“规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。捕获阶段从document往下到目标节点的父元素就停止,然后是处于目标阶段,事件发生,在事件处理中也看成冒泡阶段的一部分,在冒泡阶段可以对事件作出响应。在事件处理程序内部,this始终等于event.currentTarget,表示注册事件的对象,而由于事件流导致冒泡阶段也会触发事件,而 event.target就表示实际的事件目标。(2013-8-21添加:并不是只在冒泡阶段响应,由于Netscape和IE的事件发生顺序不同,W3C综合了二者,可以选择是在捕获阶段还是冒泡阶段绑定事件处理函数,这是通过addEventListener()方法实现的,如果这个函数的最后一个参数是true,则在捕获阶段绑定函数,反之false,在冒泡阶段绑定函数。

"DOM2级事件“中添加事件处理程序:

var btn=document.getElementById('myBtn');

btn.addEventListener("click",function(){alert(this.id);},false);

大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器,不建议事件捕获阶段注册事件处理程序。W3C默认是绑定在冒泡阶段。)

比如一个元素包含一个子元素,为父元素添加事件:

    <div id='father'>
<p id='son' >aaaaa</p>
</div>
$('#father').click(function(event){
console.log(event.eventPhase);
     console.log("event.target:"+event.target+",event.currentTarget:"+event.currentTarget);
})

在不包含son的father区域click时为:

2  event.target:[object HTMLDivElement],event.currentTarget:[object HTMLDivElement];

在son上click时:

3 event.target:[object HTMLParagraphElement],event.currentTarget:[object HTMLDivElement]。
这也就解释了为什么event.target的含义,有动作发生时是从document向下捕获到event.target而不是event.currentTarget,然后向上冒泡到document,在捕获阶段不触发事件。可以通过event.stopPropagation()来取消冒泡(2013-8-21添加:IE中的是event.cancelBubble()来取消事件冒泡(jQuery已经统一用event.stopPropagation()来兼容了吧);DOM中的event.preventDefault()可以用来取消默认行为,如超链接的跳转,IE中的是要设置event.returnValue=false。)。
同样是上面的两个父子节点,可以看看下面这个例子的结果:
    $('#father').click(function(event){
alert ('father:'+event.eventPhase);
})
$('#son').click(function(event){
alert ('son:'+event.eventPhase);
})

在不包含son的father区域click时为:father:2

在son上click时:son:2 father:3

为son的click事件里添加event.stopPropagation()后就可以只son:2了。

(以上若有错恳请指正)

附注:如果想根据具体情况来执行某些语句,可以利用if(event.target == this)。或event.target.tagName.toUpperCase()来获取标签名(当然这办法对有多层子元素的很不好)。

判断一个对象是否为jQuery对象:if(obj instanceof jQuery),jQuery中比较两个对象是否为同一个对象:$('#son')==$('p')这样总是false,这样是在比较引用地址?还是jQuery没有这个办法?(

2013-8-21添加:在js中当比较两个使用值存储的数据时,若它们的值相同,等值比较的结果是true;如果比较两个使用引用存储的数据,当且仅当它们引用同一个值时,等值比较的结果才是true,比较的是引用(对应存储地址)。如

var a={x:1,y:2};

var b=a;

var c={x:1,y:2};

alert(a==b);//true

alert(a==c);//false

alert(a>=c);//不确定

)不过可以使用$(event.target).is($('p'))来判断。

  • 对含有子元素的节点对象的mouseenter、mouseleave和mouseover、mouseout

先来看一个例子:

$('#father').mouseover(function(event){
console.log(event.target+'eovered');
    $('#son').text(event.target+'overed').css('background','white');
}).mouseout(function(event){
console.log(event.target+'outed');
$('#son').text(event.target+'outed').css('background','red');
})

结果就是几十从father移入son、从son移除father,都会触发mouseover和mouseout啊。(页面从移出到移入的瞬间太快,效果不明显,从console.log里面看啊),这样是不是很烦哪?

如果你试试把mouseover和mouseout换成mouseenter和mouseleave,在IE8和最新版的grome和firefox里面一切就正常了啊,用IETester测试,连IE6都表现正常啊,IE9没有任何反应啊,就像没有加载js一样,IETester是不是坏了啊,我的IETester里的IE7一向都是打不开测试页面的,所以不知都IE7会怎么样啊,IETester很不好用啊,有木有推荐的其他工具啊?(欢迎补充更正具体的测试结果啊)

好吧,回正题,为什么会这样呢?

其实是就是因为DOM3级事件中定义的mouseenter、mouseleave都不冒泡,在光标移动到后代元素上不会触发。但DOM2级事件并没有定义这个事件,DOM3级事件将它纳入了规范,IE、Firefox9+和Opera支持这个事件。

就是这个样子啊。

但是非要用mouseover和mouseout的话,

W3C在mouseover和mouseout这两个触发的事件对象里添加了一个叫relatedTarget的属性,来表示与事件相关的DOM元素。event.mouseover中event.relatedTarget指向鼠标来自的元素,而mouseout中的relatedTarget指向的是鼠标去向的那个元素。据说在IE里对应的分别是event.fromElement和event.toElement(没测试过啦,jQuery都统一成event.relatedTarget)。

吐槽:原来写稍微技术一点的博客这么费时间啊, 从上午8点写到现在14:00,上午不过是打了2、3个小电话,填了些资料,中午都木有午休啊,原计划还要写一些UI事件的(UI事件是指那些不一定与用户操作有关的事件,如load、resize、scroll等,有时间再补充啊)。

总结:写技术博客最好还是放在晚上吧。

俺要工作了啊,看见有错的地方恳请指正啊,谢恩。

关于js中的事件的更多相关文章

  1. 怎么理解js中的事件委托

    怎么理解js中的事件委托 时间 2015-01-15 00:59:59  SegmentFault 原文  http://segmentfault.com/blog/sunchengli/119000 ...

  2. js中冒泡事件和捕获事件

    js中冒泡事件和捕获事件: 冒泡事件:冒泡事件是从里向外,即是从被绑定元素开始一直向外到达页面的所有祖先元素都会被触发,这 一过程被称为事件冒泡.这个事件从原始元素开始一直冒泡到DOM树的最上层 捕获 ...

  3. 看懂此文,不再困惑于 JS 中的事件设计

    看懂此文,不再困惑于 JS 中的事件设计 今天刚在关注的微信公众号看到的文章,关于JS事件的,写的很详细也很容易理解,相关的知识点都有总结到,看完就有种很舒畅的感觉,该串起来的知识点都串起来了.反正一 ...

  4. js中冒泡事件

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. DOM 以及JS中的事件

    [DOM树节点] DOM节点分为三大节点:元素节点,文本节点,属性节点. 文本节点,属性节点为元素节点的两个子节点通过getElment系列方法,可以去到元素节点 [查看节点] 1 document. ...

  6. 从零开始的JS生活(二)——BOM、DOM与JS中的事件

    上回书说道,JS中变量.运算符.分支结构.循环和嵌套循环等内容.本回就由本K给大伙唠唠JS中的BOM.DOM和事件. 一."花心大萝卜"--BOM 1.震惊,FFF团为何对BOM举 ...

  7. js中的事件,内置对象,正则表达式

    [JS中的事件分类] 1.鼠标事件: click/dbclick/mouseover/mouseout/mousemove/mousedown/mouseup 2.键盘事件: keydown: 键盘按 ...

  8. JS中的事件以及DOM 操作

    [DOM树节点] DOM节点分为三大节点:元素节点,文本节点,属性节点. 文本节点,属性节点为元素节点的两个子节点通过getElment系列方法,可以去到元素节点 [查看节点] 1 document. ...

  9. JS中的事件&对象

    一.JS中的事件 (一)JS中的事件分类 1.鼠标事件 click/dblclick/onmouseover/onmouseout 2.HTML事件 onload/onscroll/onsubmit/ ...

  10. JS学习五(js中的事件)

    [JS中的事件分类] 1.鼠标事件 click/bdlclick/onmouseover/onmouseout 2. HTML事件 onload/onscroll/onsubmit/onchange/ ...

随机推荐

  1. ui router digest 10 time

    refer : https://github.com/angular-ui/ui-router/issues/600 $urlRouterProvider.when("/", &q ...

  2. 【转】Android:控件Spinner实现下拉列表

    原文网址:http://www.cnblogs.com/tinyphp/p/3858920.html 在Web开发中,HTML提供了下拉列表的实现,就是使用<select>元素实现一个下拉 ...

  3. 深入 JavaScript(6) - 一静一动

    这里是JavaScript核心的内容了. 挺多的JavaScript测试题也是围绕这个出的. 这里的一静一动指的是: 静, 词法作用域 - Lexical scoping 动, 动态绑定this的值 ...

  4. hdu 4585 Shaolin(STL map)

    Problem Description Shaolin temple is very famous for its Kongfu monks.A lot of young men go to Shao ...

  5. Linux网络配置相关

    路由相关 #添加到主机的路由 route add -host 192.168.1.2 dev eth0 route add -host 192.168.1.2 gw 192.168.1.1 注1:添加 ...

  6. INSERT command denied to user

    问题分析: 网站运行突然出现下面的 MySQL 错误: 645297 [http-88-13] ERROR com.mes.cart.dao.impl.CartDAOImpl - CartDAOImp ...

  7. Xcode开启gcc/g++

    Apple announced Xcode 4.3 for OSX Lion and 4.4 for OSX Mountain Lion last week. The major difference ...

  8. 你需要知道的九大排序算法【Python实现】之选择排序

    一.选择排序 基本思想:选择排序的思想非常直接,不是要排序么?那好,我就从所有序列中先找到最小的,然后放到第一个位置.之后再看剩余元素中最小的,放到第二个位置--以此类推,就可以完成整个的排序工作了. ...

  9. Javascript:DOM表格操作

    需求说明: /* *需求说明: *获取元素:tBodies,tHead,tFoot,rows,cells *表格的创建 *数据添加 *隔行变色 *删除操作,剩余表格重新计算,实现隔行变色 */ HTM ...

  10. 10个热门IT证书

    MCP (微软专家认证) CCNA (思科认证网络支持工程师) MCPD (微软认证开发专家) SCJP (SUN认证Java程序员) CISSP (信息系统安全认证专家) CompTIA A+认证 ...