浏览器事件的思考

标签: IT技术 前端 浏览器 | 发表时间:2012-11-14 12:08 | 作者:
出处:http://blog.jobbole.com

来源: 一淘 UX

先看下面的代码:

var $ = KISSY.all;

$(‘a’).on(‘click’,function(e){

doSomeThing();//这个方法貌似很有名

e.halt();

});

上面的代码看起来像是很好的完成了我们交给它的工作, 浏览器不会再将我们重定向到href中的链接,但这么做到底有什么不对呢?

在解释有什么不对前,我们来看看浏览器中事件中的几个概念

浏览器默认行为

当我们点击某一个链接的时候,浏览器会直接跳转,在表单中按回车,表单会自动提交,这些都是浏览器的默认行为。

Javascript事件传播的机制

什么是事件冒泡?

比如点击了一个按钮,这个元素上的事件被触发,同时该事件将会传播到它的所有父级元素中被触发。(a->div->body->document->window)这一过程被称为事件冒泡。事件冒泡是从子级元素到父级元素。

注意:不是所有的事件都能冒泡,blur、focus、load和unload不能像其它事件一样冒泡

什么是事件捕获?

和事件冒泡恰恰相反,事件捕获是从父级元素到子级元素。

什么是事件目标?

简单的说也就是事件开始的那个元素,也就是上面说的a

  浏览器事件的思考

不同浏览器下的事件模型

● 支持W3C标准的浏览器:先捕获在冒泡。在添加事件时用addEventListener(event,fn,useCapture)方法,基中第3个参数useCapture是一个Boolean值,为true,则采用事件捕获,为false,则采用事件冒泡。

● 不兼容W3C的浏览器(IE):IE只支持事件冒泡,它也不支持addEventListener函数,不过提供了attachEvent()方法来处理事件。

看完上文,是否有感觉什么地方不对?没有?那再看看下文。

”halt“到底做了什么?

当你每次调用”halt“的时候,它实际上做了2件事情:

● e.preventDefault();//阻止浏览器执行默认行为

● e.stopPropagation();//取消事件冒泡

preventDefault和stopPropagation翻译成原生js后

function preventDefault(e) {
//如果提供了事件对象,则这是一个非IE浏览器
if(e && e.preventDefault) {
  //阻止默认浏览器动作(W3C)
  e.preventDefault();
} else {
  //IE中阻止函数器默认动作的方式
  window.event.returnValue = false;
}
return false;
}

function stopPropagation(e) {
//如果提供了事件对象,则这是一个非IE浏览器
if(e && e.stopPropagation) {
  //因此它支持W3C的stopPropagation()方法
  e.stopPropagation();
} else {
  //否则,我们需要使用IE的方式来取消事件冒泡
  window.event.cancelBubble = true;
}
return false;
}

不是吧,我写最开始的代码只是想阻止浏览器的默认行为,不需要取消事件冒泡。

但是,这样写也没有什么问题啊!(嘴硬,啪啪……)。

确实,大多数情况下,这样的代码没有任何问题,那如果我们把这段代码放大到一个大环境中,会出现什么状况

<div>
<h2><a href="http://etao.com/page1">Page1</a></h2>
<div>
    Teaser text...
</div>
</div>
<div>
<h2><a href="http://etao.com/page2">Page2</a></h2>
<div>
    Teaser text...
 </div>
</div>

现在假设我们想要在用户点击文章标题时,将文章动态载入到div.content中(也就是doSomeThing做的事情),

哈哈:上文的js代码也还是会执行啊(年轻人太急)。

我们顺着这个思路继续,如果我想要在用户点击了一个div.post元素(或者任何一个它的子元素)时,给它加上一个active类,我就需要给div.post绑定click

var posts = $('div.post');
posts.on('click',function () {
posts.removeClass("active");
$(this).addClass("active");
});

这个代码就会有时候执行有时候不执行,因为你在点击a的时候取消了事件冒泡。

我们把这个代码的执行范围再次放大,产品提了一个需求,要求监听页面上所有的点击情况,一个同学接到需求,开心的在document上用了事件代理,向服务端发送了数据,回头数据一统计,似乎少了什么。回头一看,有人在a标签的点击事件中用了halt。

其实这就是本文想传递的信息,大多数情况下,当你使用halt时,你其实真正需要的是e.preventDefault(),在你写通用的组件时候这个问题尤其突出。

 

相关文章

相关 [浏览器 事件 思考] 推荐:

浏览器事件的思考

- - 博客 - 伯乐在线
doSomeThing();//这个方法貌似很有名. 上面的代码看起来像是很好的完成了我们交给它的工作, 浏览器不会再将我们重定向到href中的链接,但这么做到底有什么不对呢. 在解释有什么不对前,我们来看看浏览器中事件中的几个概念. 当我们点击某一个链接的时候,浏览器会直接跳转,在表单中按回车,表单会自动提交,这些都是浏览器的默认行为.

跨浏览器resize事件分析

- - CSDN博客Web前端推荐文章
window一次resize事件:. IE7 触发3次, IE8 触发2次, IE9 触发1次, IE10 触发1次. window resize时,部分组件需要重置大小(一次);部分组件不需要重置大小;. 优点:分Debounced和Throttled两种类型,类型明确. 大多数场景使用jquery-smartresize的Debounced即可满足一次调用即可.

浏览器中关于事件的那点事儿

- - 博客园_知识库
  在前端中,有一个很重要的概念就是事件. 我对于事件的理解就是使用者对浏览器进行的一个动作,或者说一个操作.   本文会介绍很多与事件有关的东西,虽然我的出发点有那么点一网打尽的意思m不过也难以盖全,所以就把最常用,最基本也相对重要的内容拿出来记录一下.   Javascript绑定事件的方式.   因为各种历史原因,事件的绑定在不同的浏览器总是有不同的写法,当然现在可能大多数人都已经习惯于jQuery的事件绑定,而不清楚javascript的原生事件绑定是什么样子.

JavaScript单线程和浏览器事件循环简述

- - 破狼 Blog
JavaScript单线程. 在上篇博客 《Promise的前世今生和妙用技巧》的开篇中,我们曾简述了JavaScript的单线程机制和浏览器的事件模型. 应很多网友的回复,在这篇文章中将继续展开这一个话题. 当然这里是博主的一些理解,如果还存在什么纰漏的话,请不吝指教. JavaScript这门语言运行在浏览器中,是以单线程的方式运行的.

兼容所有浏览器的 DOM 载入事件

- - Harttle Land
本文就页面载入问题讨论 DOMContentLoaded、 load、 readyState等DOM事件的浏览器兼容性, 并给出怎样绑定DOM载入事件以兼容所有的浏览器. 接着介绍jQuery对该问题的实现源码,以及jQuery中 $(document).ready()和 $(window).load()方法的区别.

javaScript跨浏览器事件处理程序

- - SegmentFault 最新的文章
最近在阅读 javascript高级程序设计,事件这一块还是有很多东西要学的,就把一些思考和总结记录下. 在事件处理,事件对象,阻止事件的传播等方法或对象存在着浏览器兼容性问题,开发过程中最好编写成一个通用的事件处理工具. //在这里添加一些通用的事件处理方法. 事件的绑定主要为IE8以下浏览器做兼容处理:.

兼容各个浏览器版本的事件监听器工具

- - CSDN博客推荐文章
作者:kingwolf_JavaScript 发表于2012-5-15 19:12:15 原文链接. 阅读:6 评论:0 查看评论.

[译]跨浏览器的多点触控与鼠标事件处理

- Stanley - UED TEAM,用户体验设计,web前端开发
原作者Ted Johnson, Graphics Program Manager Lead, Internet Explorer. 译者sunnylqm,转发请注明. 本文主要解释了Web开发者如何通过使用IE10中新引入的pointer事件模型、iOS上的touch事件模型以及W3C标准的扩展鼠标事件模型来编写普适的跨浏览器的触控事件处理代码.

各种浏览器全屏模式的方法、属性和事件介绍

- - Web前端 - ITeye博客
requestFullscreen仍然需要附带各浏览器的js方言前缀,相信下面这段代码需要你花大量的搜索才能凑齐:. // 判断各种浏览器,找到正确的方法 function launchFullscreen(element) { if(element.requestFullscreen) {. element.msRequestFullscreen(); } } // 启动全屏.

浏览器事件模型中捕获阶段、目标阶段、冒泡阶段实例详解

- - SegmentFault 最新的文章
如果对事件大概了解,可能知道有事件冒泡这回事,但是冒泡、捕获、传播这些机制可能还没有深入的研究实践一下,我抽时间整理了一下相关的知识. 本文主要对事件机制一些细节进行讨论,过于基础的事件绑定知识方法没有介绍. 特别少的篇幅关注浏览器兼容问题,毕竟原理了解了,兼容性问题可以自己想办法解决了. 在浏览器相对标准化之前,各个浏览器厂商都是自己实现的事件模型,有的用了冒泡,有的用了捕获,W3C为了兼顾之前的标准,将事件发生定义成如下三个阶段:.