纯牛奶645
纯牛奶645
  • 发布:2018-05-26 17:36
  • 更新:2018-05-26 17:36
  • 阅读:4570

事件冒泡与事件捕获

分类:Native.js

1.什么是冒泡
在页面上可以有多个事件,也可以多个元素同时响应一个事件。假设网页上有两个元素,其中一个元素<span>嵌套在另一个元素<div>里,并且都被绑定了click事件,同时<body>元素上也绑定了click事件。
当单击span元素时,即触发span元素的click事件,同时触发div和body的click事件,这就是由事件冒泡引起的。
span--->div---->body
之所以称为冒泡,是因为事件会按照DOM的层次结构像水泡一样不断向上直至顶端。


2.事件冒泡引发的问题
例如:我们本来只想span元素的slick事件,结果div和body的事件也同时被触发了。因此,我们有必要对事件的作用范围进行限制。
在jquery中提供了stopPropagation()方法来停止事件冒泡

$('span').on('click',fuction(event){  
  var txt = $('#msg').html() + "<p>内层元素被单击。</p>";  
  $('#msg).html(txt);  
  event.stopPropagation(); //停止事件冒泡  
})

3.阻止默认行为
网页中的元素由自己的默认行为,例如:单击超链接后会跳转、单击“提交”按钮后表单会提交,有时需要阻止元素的默认行为。
在jquyer中,提供了preventDefault()方法来阻止元素的默认行为。

$('#sub').on('click', function(event){  
  var username = $('#username').val();  
  if(username === "") {  
    $('#msg').html('<p>文本框的值不能为空</p>');  
    event.preventDefault();  
  }  
})

如果想同时对事件对象停止冒泡和默认行为,可以在事件处理函数中返回false。这是对事件对象上同时调用stopPrapagation()方法和perventDefault()方法的一种简写方式。

return false;

4.事件捕获
事件捕获和事件冒泡是两个刚好相反的过程,事件捕获是从最顶端往下开始触发。
body--->div--->span
事件捕获是从最外层元素开始,然后再到最里层,因此绑定的click事件,首先会传递给body元素,再到div,再到span。
遗憾的是,并非所有的主流浏览器都支持事件捕获。并且这个缺陷无法通过javascript来修复。jquery不支持事件捕获,如果需要使用事件捕获,请直接使用JavaScript。

延伸:阻止默认行为
1.<a></a>标签
a是超文本链接,没js也可以点击,这是浏览器赋予的功能,而js只是一个语言,增强了html的能力。
a标签设计的时候就是能点击,点击了能跳转,js只是能改变这些行为罢了
1.1阻止a标签默认行为的方法
a标签只有一个默认方法,就是跳转。
(1) <a href="javascript:void(0);" onclick= "myjs( )"> Click Me </a>
onclick方法负责执行js函数,而void是一个操作符,void(0)返回undefined,地址不发生跳转。
<a href="javascript:;" > Click Me </a>
和void(0)一样,都返回"undefined"
(2) <a href="#"> Click Me </a>
是网上很常见的代码,#是标签内置的一个方法,用这种方法点击后网页后返回到页面的最顶端所以又有了“##”“#!”等,尽管解决了返回顶部的问题但仍存在其他缺陷
(3)事件处理函数的工作机制中,在给某元素添加事件处理函数后,一旦事件发生,相应JavaScript代码就会执行,所调用的JavaScript代码的返回值被传递给事件处理函数。当我们给a标签添加onclick事件处理函数并点击a触发其后,
如果相应JavaScript代码返回true,onclick事件处理函数就会认为这个链接被点击了,同样的若返回false即会认为链接
未被点击
<a href="http://www.baidu.com" onclick=" myjs(); return false; "> Click Me </a>
<a href="http://www.baidu.com" onclick=" return false; "> Click Me </a>
当点击a标签时,JavaScript代码返回值为false,故此链接默认行为未被触发。
(4)preventDefault()阻止事件的默认行为但不支持IE,所以在IE中使用returnValue阻止事件默认行为

<a href="http://www.baidu.com" id="test">  Click Me  </a>   
<script type="text/javascript">   
var test = document.getElementById('test');   
function stopDefault( e )  
{   
   if ( e && e.preventDefault )   
      e.preventDefault();   
     else   
        window.event.returnValue = false;    
}   
test.onclick = function(e)   
{   
     stopDefault(e);   
}   
</script>

2.一些事件的默认行为

Submit按钮: 在form表单中的,提交form表单中的数据到服务器
Button: 在PC中不做任何事情, 在手机浏览器中, 若是在form中,则是submit
a标签: 默认将当前页面跳转为a标签中href的地址
通过event.preventDefaut();来阻止默认行为如:

var evt = evt || window.event; //获取event对象  
    if (evt.preventDefault) {  
        evt.preventDefault();  
    } else {  
        evt.returnValue = false; //在早期的IE版本中  
}

事件传播[事件冒泡模型 / 事件捕获模型]

事件冒泡(早期浏览器支持,DOM0)

在早期的浏览器, 对于事件的处理主要采用了事件冒泡模型, 也就是:当在触发元素(如:button)的事件(onclick)时候, 事件(onclick)会随着元素向父级元素(各个父节点)冒泡穿过整个DOM层次,依次触发事件(onclick),事件会从最内层的元素开始发生,一直向上传播,直到document对象。
因此上面的例子在事件冒泡的概念下发生click事件的顺序应该是p -> div -> body -> html -> document

事件捕获模型,在后期(DOM2规范,W3C规范中)

当点击元素(button)触发事件(click)的时候, 事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递。在这个过程中,事件会被从文档根到事件目标元素之间各个继承派生的元素所捕获.
与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。
上面的例子在事件捕获的概念下发生click事件的顺序应该是document -> html -> body -> div -> p

DOM2级事件可原则采用何种方式触发事件(冒泡模型或者捕获模型)

“DOM2级事件”中规定的事件流同时支持了事件捕获阶段和事件冒泡阶段,而作为开发者,我们可以选择事件处理函数在哪一个阶段被调用。
addEventListener方法用来为一个特定的元素绑定一个事件处理函数,是JavaScript中的常用方法。addEventListener有三个参数:

element.addEventListener(event, function, useCapture)
1
第一个参数是需要绑定的事件,第二个参数是触发事件后要执行的函数。而第三个参数默认值是false,表示在事件冒泡的阶段调用事件处理函数,如果参数为true,则表示在事件捕获阶段调用处理函数。请看例子。

function stopEvent (evt) {  
    var evt = evt || window.event;  
    if (evt.stopPropagation) {   
        evt.stopPropagation();   
    } else {  
        evt.cancelBubble = true;  
    }   
}
1 关注 分享
HRK_01

要回复文章请先登录注册

移动达人

移动达人

不错
2018-05-27 00:21
uniapp视频教程

uniapp视频教程

厉害了
2018-05-26 19:06