美文网首页前端开发让前端飞Web前端之路
基础知识--javascript事件机制与事件委托

基础知识--javascript事件机制与事件委托

作者: Husbin | 来源:发表于2018-01-22 21:18 被阅读82次

事件:

事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。javascript与HTML之间的交互就是通过事件来实现的。观察者模型:使用侦听器或处理程序要预定时间,以便时间发生时执行相应的代码,这种模型支持页面的行为(javascript)与页面的外观(HTML和CSS)之间的松散耦合。

事件监听器与处理程序:

  • 响应某个事件的函数就叫做事件处理程序或事件监听器。在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息,包括导致事件的元素,事件 的类型以及其他与特定事件相关的信息,这个对象不需要定义,可以直接使用。
  • 事件处理程序:事件处理程序的名字以on开头,类似click、load、和 mouseover都是事件的名字,因此,click的事件处理程序就是onclick。案例如下:onclick就是事件处理程序
<div id="child" style="width: 90px;height:90px;background-color: cyan;margin: 0 auto;" onclick="showMessage(event)" >孩子</div>
<script type="text/javascript">
    function showMessage(event){
        alert(event.target.id);
    }
 </script> 
  • 事件监听器:例子如下:child.addEventListener("click",function (),true)是将指定的监听器注册到child上,当该对象触发指定的事件时,指定的回调函数就会被执行。
<div id="child" style="width: 90px;height:90px;background-color: cyan;margin: 0 auto;" >孩子</div>
<script type="text/javascript">
    let child = document.getElementById("child");
    /**
     *  事件监听器
     *  addEventListener(eventName , dealEventFunc , boolean)
     *  eventName: 要处理的事件名
     *  dealEventFunc: 作为事件处理程序的函数
     *  boolean: true表捕获事件,false表冒泡事件
     * */
    // 捕获事件流
    child.addEventListener("click",function () {
        //取消冒泡
        //event.stopPropagation();          //IE
        //event.cancelBubble = true;        //w3c
        console.log("捕获事件流:click child!");
    },true);
    //冒泡事件流
    child.addEventListener("click",function () {
        console.log("冒泡事件流:click child!");
    },false);
</script>

事件流:

  • 构建一棵dom树如下:
image.png
  1. IE事件流:事件冒泡流。

事件开始时由最具体的元素(文档中嵌到层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。

image.png
  • 点击child<div>,显示如下:
image.png
  • 点击parent<div>,显示如下:
image.png
  1. NetSpace事件流:事件捕获流。

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件,事件捕获的用意在于在事件到达预定目标之前捕获他。

image.png
  • 点击child<div>,显示如下:
image.png
  • 点击parent<div>,显示如下:
image.png
  1. DOM事件流:包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。

DOM2级事件规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会,然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。

下图,捕获阶段:1,2,3,4

处于目标阶段在事件处理中被看成是冒泡阶段的一部分

然后冒泡事件发生:5,6,7,8,9

image.png

阻止事件冒泡

        event.stopPropagation();          //IE
        event.cancelBubble = true;        //w3c
image.png

事件委托

  • 内存和性能:在javascript中,添加到页面上的时间处理程序数量将直接影响到页面的整体运行性能。导致这一问题的原因是多方面的,首先,每个函数都是对象,都会占用内存;内存中的对象越多,性能就越差。其次,必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。
  • 事件委托:事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。使整个页面只有少量的函数,从而优化页面性能。实例代码如下:
<!DOCTYPE html>
<html lang="en" id="html" onclick="clickDiv(event)">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body id="body">
<div id="grandparent" style="width: 270px;height:270px;background-color: blue; margin: 0 auto; text-align: center;line-height: 3">祖父
    <div id="parent" style="width: 180px;height:180px;background-color: cadetblue;margin: 0 auto;">父亲
        <div id="child" style="width: 90px;height:90px;background-color: cyan;margin: 0 auto;" >孩子
        </div>
    </div>
</div>
</body>
<script type="text/javascript">
    let child = document.getElementById("child");
    let parent = document.getElementById("parent");
    let grandparent = document.getElementById("grandparent");
    let body = document.getElementById("body");
    let html = document.getElementById("html");
    function clickDiv(event){
        switch (event.target.id){
            case 'child':console.log("click child!");break;
            case 'parent':console.log("click parent!");break;
            case 'grandparent':console.log("click grandparent!");break;
            case 'body':console.log("click body!");break;
            case 'html':console.log("click html!");break;
        }
    }
</script>
</html>
  • <html>标签中添加了onclick(event)事件处理程序。由于其他标签都是<html>的子节点,而且他们的事件会冒泡,所以单击事件终会被这个函数处理,点击各个点的输出情况如下所示。与给每个节点加一个处理程序相比,这种方法需要占用的内存更少,只添加了一个处理程序,虽然对用户来说最终结果都相同,但这种技术需要占用的内存更少,所有用到按钮的事件都适合采用事件委托技术
image.png
  • 如果可行的话,也可以考虑为document对象添加一个事件处理程序,用以处理页面上发生的某种特定类型的事件,这样做与传统的做法相比具有如下优点:
    1. document对象很快就可以访问,而且可以在生命周期的任何时间点上为它添加事件处理程序。‘
    2. 在页面中设置事件处理程序所需的时间更少,只添加体格事件处理程序所需的DOM引用更少,所花的时间也更少。
    3. 真个页面占用的内存空间更少,能够提升整体性能。
  • 整个demo代码:
<!DOCTYPE html>
<html lang="en" id="html" onclick="clickDiv(event)">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body id="body">
<div id="grandparent" style="width: 270px;height:270px;background-color: blue; margin: 0 auto; text-align: center;line-height: 3">祖父
    <div id="parent" style="width: 180px;height:180px;background-color: cadetblue;margin: 0 auto;">父亲
        <div id="child" style="width: 90px;height:90px;background-color: cyan;margin: 0 auto;" >孩子
        </div>
    </div>
</div>
<!--<div id="child" style="width: 90px;height:90px;background-color: cyan;margin: 0 auto;" onclick="showMessage(event)" >孩子-->
<!--</div>-->
</body>
<script type="text/javascript">
    let child = document.getElementById("child");
    let parent = document.getElementById("parent");
    let grandparent = document.getElementById("grandparent");
    let body = document.getElementById("body");
    let html = document.getElementById("html");

    //采用事件委托优化性能
    function clickDiv(event){
        switch (event.target.id){
            case 'child':console.log("click child!");break;
            case 'parent':console.log("click parent!");break;
            case 'grandparent':console.log("click grandparent!");break;
            case 'body':console.log("click body!");break;
            case 'html':console.log("click html!");break;
        }
    }
    // function showMessage(event){
    //     alert(event.target.id);
    // }
    /**
     *  事件监听器
     *  addEventListener(eventName , dealEventFunc , boolean)
     *  eventName: 要处理的事件名
     *  dealEventFunc: 作为事件处理程序的函数
     *  boolean: true表捕获事件,false表冒泡事件
     * */
    // 捕获事件流
    // child.addEventListener("click",function () {
    //     console.log("捕获事件流:click child!");
    // },true);
    // parent.addEventListener("click",function () {
    //     console.log("捕获事件流:click parent!");
    // },true);
    // grandparent.addEventListener("click",function () {
    //     console.log("捕获事件流:click grandparent!");
    // },true);
    // body.addEventListener("click",function () {
    //     console.log("捕获事件流:click body!");
    // },true);
    // html.addEventListener("click",function () {
    //     console.log("捕获事件流:click html!");
    // },true);
    // document.addEventListener("click" , function () {
    //     console.log("捕获事件流:click document!")
    // },true);
    // window.addEventListener("click" , function (ev) {
    //     console.log("捕获事件流:click window!")
    // },true);

    //冒泡事件流
    // child.addEventListener("click",function (event) {
    //     console.log("冒泡事件流:click child!");
    //     //阻止冒泡行为
    //     //event.stopPropagation();          //IE
    //     event.cancelBubble = true;        //w3c
    // },false);
    // parent.addEventListener("click",function () {
    //     console.log("冒泡事件流:click parent!");
    // },false);
    // grandparent.addEventListener("click",function () {
    //     console.log("冒泡事件流:click grandparent!");
    // },false);
    // body.addEventListener("click",function () {
    //     console.log("冒泡事件流:click body!");
    // },false);
    //
    // html.addEventListener("click",function () {
    //     console.log("冒泡事件流:click html!");
    // },false);
    // document.addEventListener("click" , function () {
    //     console.log("冒泡事件流:click document!");
    // },false);
    // window.addEventListener("click" , function (ev) {
    //     console.log("冒泡事件流:click window!");
    // },false);
</script>
</html>

相关文章

  • JavaScript的事件机制

    在JavaScript的学习中,我们经常会遇到JavaScript的事件机制,例如,事件绑定、事件监听、事件委托(...

  • 基础知识--javascript事件机制与事件委托

    事件: 事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。javascript与HTML之间的交互就是通过事件来...

  • js事件深入学习

    JavaScript的事件机制包含,事件绑定、事件监听、事件委托(事件代理)等 js中的事件流 ① .冒泡:当下级...

  • JavaScript的事件代理和事件委托

    JavaScript中的事件委托是很重要的一个东西,事件委托依靠的就是事件冒泡和捕获的机制。 事件冒泡怎么实现,先...

  • JavaScript事件委托机制

    概念 事件委托是依靠事件冒泡,只需要指定一个事件处理程序,绑定一次就可以处理一类的事件。举个例子:假如有一个旅游团...

  • 关于事件冒泡、事件捕获和事件委托

    在javascript里,事件委托是很重要的一个东西,事件委托依靠的就是事件冒泡和捕获的机制,我先来解释一下事件冒...

  • 2019-08-01(转)事件捕获、事件冒泡和事件委托

    在javascript里,事件委托是很重要的一个东西,事件委托依靠的就是事件冒泡和捕获的机制,我先来解释一下事件冒...

  • 前端问(面试)题

    dom执行顺序 事件委托原理 原型链的作用,与作用域链的区别 js事件轮询原理、JavaScript的运行机制 结...

  • JQuery事件委托

    JavaScript(jQuery)中的事件委托 一:什么是事件委托? 事件委托是利用事件冒泡,只指定一个事件...

  • Javascript的事件委托机制

    事件绑定 直接在dom元素上绑定一个事件,这是最简单的方法,也是最不好的方法,比如在多个js文件中有可能会覆盖掉之...

网友评论

    本文标题:基础知识--javascript事件机制与事件委托

    本文链接:https://www.haomeiwen.com/subject/myvraxtx.html