这是第一篇技术性博客。

因为最近做的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. cf B. Fox Dividing Cheese

    http://codeforces.com/contest/371/problem/B #include <cstdio> #include <iostream> #inclu ...

  2. 如何关闭Altium Designer联网功能(图文教程)

    画PCB电路板的人们都知道Altium Designer这款软件,本文介绍如何避免收到Attorney,关掉Altium Designer 的自动联网功能,需要两步,介绍如下 打开AD软件, DXP- ...

  3. rcp命令

    rcp命令 rcp代表“remote file copy”(远程文件拷贝).该命令用于在计算机之间拷贝文件.rcp命令有两种格式.第一种格式用于文件到文件的拷贝:第二种格式用于把文件或目录拷贝到另一个 ...

  4. 易pc,1G容量以上的u盘,另外还要一台装了windows系统的电脑。

    一.硬件:易pc,1G容量以上的u盘,另外还要一台装了windows系统的电脑. 二.软件: 1.windows xp的安装包.考虑到易PC的硬盘容量,还是用精简版的吧,比如“Deepin XP Li ...

  5. bzoj3995[SDOI2015]道路修建

    http://www.lydsy.com/JudgeOnline/problem.php?id=3995 线段树维护连通性. 我们发现,对于一个区间[L,R],我们只需要知道(1,L),(2,L),( ...

  6. 笔记:java并发编程实践1

    Java 5.0 adds ConcurrentHashMap, a replacement for synchronized hash-based Map implementations, and ...

  7. 精美实用的jQuery插件精选

    jQuery的确是一款相当强大的Javascript框架,同时jQuery的插件就多入牛毛,如果你善于收集,那么你在写前端页面的时候肯定会更加方便.本文精选了一些精美实用的jQuery插件供大家参考. ...

  8. Android:ImageView应用之图片浏览器

    ImageView控件实现的简单图片浏览器 一.纯显示图片: 引言: 读者在做这个东西的时候,需要自己把图片在源程序中导入. 读者要注意:所有导入的图片之前,图片的命名只可以是小写英文和数字. 效果图 ...

  9. 带’*’号字符串的匹配

    目标: 判断源字符串中是否含有指定子串,子串可能会有*号通配符. 初步测试没问题.记录下来.后面要是有问题再来纠正. #include <string> using namespace s ...

  10. vmware vms migration to openstack

    Converting a VMware Workstation virtual machine to KVM Leave a commentPosted by rbgeek on August 13, ...