JavaScript 事件监听, 事件冒泡, 事件捕获, 阻止默认的事件

余生长醉 提交于 2019-12-09 07:34:15

目录

事件冒泡, 事件捕获, 阻止默认的事件
—这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(事件名称,事件函数);
    1. 没有捕获
    2. 事件名称有on
    3. this指向window
  • 标准:obj.addEventListener(事件名称,事件函数,是否捕获);
    1. 有捕获
    2. 事件名称没有on
    3. 事件执行的顺序是正序
    4. 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 : 不冒泡,并且不捕获
//不冒泡并且不捕获的意思是 父级与子级同级事件互不干扰

这里写图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!