发表于: 2019-08-19 20:43:11

1 966


今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin) 
明天计划的事情:(一定要写非常细致的内容) 
遇到的问题:(遇到什么困难,怎么解决的) 
收获:(通过今天的学习,学到了什么知识)


回顾之前的知识,准备复盘评审的ppt

事件传播的三个阶段是:事件捕获、事件冒泡和目标。

·         事件捕获阶段:事件从最上一级标签开始往下查找,直到捕获到事件目标 target。(从祖先元素往子元素查找,DOM树结构)。在这个过程中,事件相应的监听函数是不会被触发的。

·         事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

·         事件冒泡阶段:事件从事件目标 target 开始,往上冒泡直到页面的最上一级标签。(从子元素到祖先元素冒泡)

事件捕获:

addEventListener可以捕获事件:

    box1.addEventListener("click"function () {

        alert("捕获 box3");

    }, true);

上面的方法中,参数为true,代表事件在捕获阶段执行。

说明

捕获阶段,事件依次传递的顺序是:window --> document --> html--> body --> 父元素、子元素、目标元素。

PS1:第一个接收到事件的对象是 window(有人会说body,有人会说html,这都是错误的)。

PS2JS中涉及到DOM对象时,有两个对象最常用:windowdoucument。它们俩也是最先获取到事件的。

补充一个知识点:

 js中:

     html节点,方法是document.documentElement

     body 节点,方法是:document.body

二者不要混淆了。

事件冒泡:

事件冒泡当一个元素上的事件被触发的时候(比如说鼠标点击了一个按钮),同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。

通俗来讲,冒泡指的是:子元素的事件被触发时,父盒子的同样的事件也会被触发。取消冒泡就是取消这种机制。

冒泡顺序

一般的浏览器(除IE6.0之外的浏览器):div -> body -> html -> document -> window

IE6.0div -> body -> html -> document

当我点击子元素box时 其父元素box2box1body上的的点击效果都依次被触发了。触发顺序是按照冒泡书序来的。不会因为代码顺序而改变冒泡冒泡顺序。

如果用 addEventListener 这种 DOM2的写法,第三个参数要写 false,或者不写。

注意以下事件不冒泡的:

blurfocusloadunloadonmouseenteronmouseleave。   意思是,事件不会往父元素那里传递。

检查一个元素是否会冒泡,可以通过事件的以下参数:

    event . bubbles

如果返回值为true,说明该事件会冒泡;反之则相反。

阻止冒泡的方法

w3c的方法:(火狐、谷歌、IE11

    event . stopPropagation();

IE10以下则是:

Event . cancelBubble = true

兼容代码如下:

   box3.onclick = function (event) {

 

        alert("child");

 

        //阻止冒泡

        event = event || window.event;

 

        if (event && event.stopPropagation) {

            event.stopPropagation();

        } else {

            event.cancelBubble = true;

        }

    }

上方代码中,我们对box3进行了阻止冒泡,产生的效果是:事件不会继续传递到 fathergrandfatherbody了。

事件委托:

事件委托,通俗讲就是把一个元素的响应事件(比如点击 click)的函数委托到另一个元素

举例:

比如一个列表ul 列表中有大量的li 现在需要在鼠标移动到li上时(或点击时)能获取到此li 的相关信息并飘出悬浮窗以显示详细信息,通常的写法是为每个li 都绑定一个监听事件,但这样会消耗内存和性能。如果有冒泡的思路来做,哪么比较好的方法就是把点击事件绑定到他的父层上,然后在执行事件的时候再去匹配判断目标元素,如下: 
  // 获取父节点,并为它注册click事件。 false 表示事件在冒泡阶段触发(默认)

    document.getElementById("parent-list").addEventListener("click"function (e) {

        // event.target 代表的是子元素。toUpperCase 指的是转换为大写字母

        if (e.target && e.target.nodeName.toUpperCase == "LI") {

            // 真正的处理过程在这里

            console.log("List item ", e.target.id" was clicked!");

        }

    }, false);

上方代码,为父节点注册click事件,当子节点被点击的时候,click事件会从子节点开始向上冒泡。父节点捕获到事件之后,开始执行方法体里的内容:通过判断 e.target 拿到了被点击的子节点li。从而可以获取到相应的信息,并作处理。

换而言之,事件是在父节点上注册的,参数为false,说明事件是在冒泡阶段触发(往上传递),那就只有父节点能拿到事件,子节点是不可能拿到事件的。

所以事件委托可以减少大量的内存消耗,提高效率。



返回列表 返回列表
评论

    分享到