NO END FOR LEARNING

Writing blog if you feel tired | 学海无涯 苦写博客

JS 改变默认行为 e.preventDefault() e.returnValue e.stopPropagation e.cancelBubble Return False

| Comments

事件对象有一些方法可以改变一个元素的默认行为,以及它的祖先元素如何对这个事件作出响应。

有一些事件,比如点击链接或提交表单,会把用户导向另一个页面。为了阻止这类元素的这种默认行为,比如在用户点击链接或提交表单之后还是停留在当前页面,而不是导向新的页面,可以使用事件对象e的preventDefault()。

IE5~IE8有一个同样功能的属性returnValue,如果将其设置为false,就能达到同样的效果。

1
2
3
4
5
if (e.preventDefault) {
  e.preventDefault();
} else {
  e.returnValue = false;
}

处理完某个元素上的事件之后,可能需要阻止这个事件向其祖先元素继续冒泡传播。这时候,可以使用e.stopPropagation()方法。

IE8或更早的IE版本中,使用拥有同样功能的属性e.cancelBubble,将其设置为true可以达到同样的效果。

1
2
3
4
5
if (e.stopPropagation) {
  e.stopPropagation();
} else {
  e.cancelBubble = true;
}

如果你想要同时实现,preventDefault和stopPropagation,可以使用return false。

1
2
3
4
$("a").click(function() {
   $("body").append($(this).attr("href"));
   return false;
}

参考资料:
1.《JavaScript&jQuery交互式Web前端开发》

JavaScript事件流和事件代理/委托

| Comments

HTML元素都位于另一些。如果鼠标移动到某一个链接,或者点击了链接,同样鼠标也移动到了它的父元素上,并点击了那个父元素。

当你点击某个元素时,产生了一个点击事件,从而产生了一个事件流。

事件流分为两种:

事件冒泡:事件从最具体的节点开始向外传播到最宽泛的节点。这是事件流的默认类型,被绝大多数浏览器所支持。

事件捕获:事件从最宽泛的节点开始向内传播到最具体的节点。这种方式在IE8和更早版本的IE中不被支持。

Alt text

See the Pen Bubbling Event by Benwei (@benweizhu) on CodePen.

看一个codepen的例子

什么时候事件冒泡或者说事件流会变得如此重要?

当代码在一个元素和其祖先元素或者后代元素上都有事件处理程序时,事件流就会变得非常重要。

事件代理/委托

为大量的元素创建事件监听器会造成页面速度下降,事件流允许你在父元素上监听事件。

如果用户可以和页面中的大量元素进行交互,比如:大量的按钮,很长列表,表格中每一个单元格。如果想这些元素分别添加事件监听器就会使用大量的内存,从而降低性能。

事件可以影响到容器元素(祖先元素),因此可以将事件处理程序放置在一个元素容器上,然后使用事件对象的target属性找到它的后代中是哪一个发生了事件,因此只需要响应一个元素上的事件(而不是在每一个子元素上分别响应事件)。

看一个codepen的例子

See the Pen WwaqyP by Benwei (@benweizhu) on CodePen.

参考资料:
1.《JavaScript&jQuery交互式Web前端开发》