目录
事件冒泡, 事件捕获, 阻止默认的事件
—这3者密不可分
JS事件
函数的调用 :
1.直接调用: 函数名() :demo();
2.在标签内通过事件调用: 事件="函数名()" :onclick="demo()";
事件处理机制 :(IE只支持事件冒泡)
http://www.jb51.net/article/42492.htm
- 事件传递 :
- 捕获、目标、冒泡三个阶段
- 冒泡型事件:
- IE6.0: div -> body -> html -> document
Mozilla 1.0: div -> body -> html -> document -> window - 捕获型事件:
- 事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)。
- DOM事件流:
- 同时支持两种事件模型:捕获型事件和冒泡型事件,但是,捕获型事件先发生。两种事件流会触及DOM中的所有对象,从document对象开始,也在document对象结束。
- DOM事件模型最独特的性质是,文本节点也触发事件(在IE中不会)。
简而言之:
- 事件捕获
- 当你使用事件捕获时,父级元素先触发,子级元素后触发。
- 事件冒泡
- 当你使用事件冒泡时,子级元素先触发,父级元素后触发。
W3C模型
W3C模型是将两者进行中和,在W3C模型中,任何事件发生时,先从顶层开始进行事件捕获,直到事件触发到达了事件源元素。然后,再从事件源往上进行事件冒泡,直到到达document。
即: 捕获> 目标 >冒泡
捕获
—(父元素事件先发生, 子元素事件后发生;
事件从发生的目标(event.srcElement||event.target)开始,沿着文档逐层向上冒泡,到document || window为止。)
- IE下没有捕获
function bind(obj, evname, fn) {
if (obj.addEventListener) {
obj.addEventListener(evname, fn, false); //false采用事件冒泡 ,默认
} else {
obj.attachEvent('on' + evname, function() { //事件名称需要on , 此代码之前IE不支持事件捕获,使用call方法后支持
fn.call(obj);
});
}
}
bind(document, 'click', fn1);
冒泡
—(子元素事件先发生, 父元素事件后发生)
使用JQ阻止事件冒泡:(即阻止父级事件再发生)
$(".son").click(function(e){ alert(1); e.stopPropagation();//参数e 和这行代码是重点 }) $(".father").click(function(){ alert(2);// 子元素使用stopPropagation()方法后, 父级事件不再发生 })
事件监听
1 . IE只支持事件冒泡,不支持事件捕获,它也不支持addEventListener函数,不会用第三个参数来表示是冒泡还是捕获,它提供了另一个函数 attachEvent 。
2 . 原生js普通的事件监听方法:
document.getElementById("div").onclick = function(){
alert("div被点击");
}
document.getElementById("div").onclick = function(){
alert("div再次被点击");
}
// 只有第二个监听器会生效, 第一个会被覆盖
3 . 事件的监听器(attachEvent || addEventListener)可以多次添加,不会覆盖;
- ie:obj.attachEvent(事件名称,事件函数);
- 没有捕获
- 事件名称有on
- this指向window
- 标准:obj.addEventListener(事件名称,事件函数,是否捕获);
- 有捕获
- 事件名称没有on
- 事件执行的顺序是正序
- this触发该事件的对象
demo:
function demo(objs,event,fn){
if(objs.attachEvent){
objs.attachEvent("on"+event,fn);
//IE下;注意2点:一个需要“on”,一个是不需要写第三个参数
}else{
objs.addEventListener("event",fn,false);
//其他浏览器,在用addEventListener时,不需要“on”
}
}
程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡 (默认为fasle):
ele.addEventListener('click',doSomething2,true)
1 || true=捕获
0 || false=冒泡
移出事件句柄 (原生JS,有兼容):
removeEventListener() 方法用于移除由 addEventListener() 方法添加的事件句柄。
- 语法:element.removeEventListener(event, function, useCapture)
其中:useCapture 可选。布尔值,指定移除事件句柄的阶段。分别为:true - 在捕获阶段移除事件句柄;false- 默认。在冒泡阶段移除事件句柄
兼容:
var x = document.getElementById("myDIV");
if (x.removeEventListener) { // 所有浏览器,除了 IE 8 及更早IE版本
x.removeEventListener("mousemove", myFunction);
} else if (x.detachEvent) { // IE 8 及更早IE版本
x.detachEvent("onmousemove", myFunction);
}
阻止事件的默认行为 :
例如click a标签后的跳转~
在W3c中,使用 preventDefault()方法;
在IE下设置window.event.returnValue = false;
**jq:**
$("div").click(function(){
alert("div被点击");
// preventDefault方法jq有, 原理在见下面文档
event.preventDefault();
})
**js:**
// jQuery封装的preventDefault方法, 查看全部搜索preventDefault:
jQuery.Event.prototype = {
// 阻止元素发生默认的行为。
preventDefault: function() {
var e = event || window.event;
// 如果preventDefault存在, 则运行preventDefault事件
if ( e.preventDefault ) {
e.preventDefault();
// 否则事件的ReturnValue属性为false(IE)
} else {
e.returnValue = false;
}
},
}
阻止事件的传播(阻止事件冒泡) :
- 在W3c中,使用 stopPropagation()方法
- 在IE下设置 cancelBubble = true;
在捕获的过程中stopPropagation();后,后面的冒泡过程也不会发生了~
**jq:**
$("div").click(function(){
alert("div被点击");
// stopPropagation方法jq有封装
event.stopPropagation();
})
**js:**
// jQuery封装的stopPropagation方法, 查看全部搜索stopPropagation:
jQuery.Event.prototype = {
// 阻止元素发生默认的行为。
stopPropagation: function() {
var e = event || window.event;
// 如果stopPropagation存在, 则运行stopPropagation事件
if ( e.stopPropagation) {
e.stopPropagation();
// 否则事件的cancelBubble 属性为true(IE)
} else {
e.cancelBubble = true;
}
},
}
其他:
通过addeventlister添加事件: IE必须要on
在一个支持W3C DOM的浏览器中,像这样一般的绑定事件方式,是采用的事件冒泡方式:
ele.onclick = doSomething2
initEvent() 初始化新创建的 Event 对象的属性。
preventDefault() // 通知浏览器不要执行与事件关联的默认动作。
stopPropagation() //阻止事件再发生
值得注意的是:
// 鼠标移入事件
onmousemove : 冒泡,并且捕获;
onmouseenter: 不冒泡.并且不捕获
// 鼠标移出事件
onmouseout : 冒泡,并且捕获
onmouseleave : 不冒泡,并且不捕获
//不冒泡并且不捕获的意思是 父级与子级同级事件互不干扰
来源:CSDN
作者:Raymond_q
链接:https://blog.csdn.net/qq_36649716/article/details/56276725