• 深入理解DOM事件机制系列第一篇——事件流


    前面的话

      javascript操作CSS称为脚本化CSS,而javascript与HTML的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间,而事件流(又叫事件传播)描述的是从页面中接收事件的顺序。本文将详细介绍该部分的内容

    历史

      当浏览器发展到第四代时(IE4及Netscape4),浏览器开发团队遇到了一个很有意思的问题:页面的哪一部分会拥有某个特定的事件?想象画在一张纸上的一组同心圆。如果把手指放在圆心上,那么手指指向的不是一个圆,而是纸上的所有圆

      两家公司的浏览器开发团队在看待浏览器事件方面还是一致的。如果单击了某个按钮,他们都认为单击事件不仅仅发生在按钮上,甚至也单击了整个页面

      但有意思的是,IE和Netscape开发团队居然提出了差不多是完全相反的事件流的概念。IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流

    事件冒泡

      IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)

      以下列HTML结构为例,说明事件冒泡、事件捕获及事件流

    <!DOCTYPE HTML>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <body>
    <div></div>
    </body>    
    </html>

      如果单击了页面中的<div>元素,那么这个click事件沿DOM树向上传播,在每一级节点上都会发生,按照如下顺序传播:

    (1)    <div>
    (2)    <body>
    (3)    <html>
    (4)    document

      [注意]所有现代浏览器都支持事件冒泡,但在具体实现在还是有一些差别。IE9、Firefox、Chrome、Safari将事件一直冒泡到window对象

    (1)    <div>
    (2)    <body>
    (3)    <html>
    (4)    document
    (5)    window
    <!DOCTYPE HTML>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <body>
    <div id="box" style="height:100px;300px;background-color:pink;"></div>
    <button id="reset">还原</button>
    <script>
    //IE8-浏览器返回div body html document
    //其他浏览器返回div body html document window
    reset.onclick = function(){history.go();}
    box.onclick = function(){box.innerHTML += 'div
    ';}
    document.body.onclick = function(){box.innerHTML += 'body
    ';}
    document.documentElement.onclick = function(){box.innerHTML += 'html
    ';}
    document.onclick = function(){box.innerHTML += 'document
    ';}
    window.onclick = function(){box.innerHTML += 'window
    ';}
    </script>
    </body>    
    </html>

    事件捕获

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

      以同样的HTML结构为例,说明事件捕获

    <!DOCTYPE HTML>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <body>
    <div></div>
    </body>    
    </html>

      在事件捕获过程中,document对象首先接收到click事件,然后事件沿DOM树依次向下,一直传播到事件的实际目标,即<div>元素

    (1)    document
    (2)    <html>
    (3)    <body>
    (4)    <div>

      [注意]IE9、Firefox、Chrome、Safari等现代浏览器都支持事件捕获,但是从window对象开始捕获

    (1)    window
    (2)    document
    (3)    <html>
    (4)    <body>
    (5)    <div>

      addEventListener()方法中的第三个参数设置为true时,即为事件捕获阶段

    <!DOCTYPE HTML>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <body>
    <div id="box" style="height:100px;300px;background-color:pink;"></div>
    <button id="reset">还原</button>
    <script>
    //IE8-浏览器不支持
    //其他浏览器返回window document html body div
    reset.onclick = function(){history.go();}
    box.addEventListener('click',function(){box.innerHTML += 'div
    '},true)
    document.body.addEventListener('click',function(){box.innerHTML += 'body
    ';},true);
    document.documentElement.addEventListener('click',function(){box.innerHTML += 'html
    ';},true);
    document.addEventListener('click',function(){box.innerHTML += 'document
    ';},true);
    window.addEventListener('click',function(){box.innerHTML += 'window
    ';},true);
    </script>
    </body>    
    </html>

    事件流

      事件流又称为事件传播,DOM2级事件规定的事件流包括三个阶段:事件捕获阶段(capture phase)、处于目标阶段(target phase)和事件冒泡阶段(bubbling phase)

      首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件,最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应

  • 相关阅读:
    记录使用cx_Freeze打包Python成exe可执行程序
    jquery plug-in DataTable API中文文档参考
    java.lang.UnsatisfiedLinkError: dlopen failed: /data/app/xxx/lib/arm/liblame.so: has text relocations
    CocoaPods的安装及使用
    Android 贝塞尔曲线的浅析
    GUI学习中错误Exception in thread "main" java.lang.NullPointerException
    线程
    12月13日
    今天开始学习java编程
    UVA10140 Prime Distance
  • 原文地址:https://www.cnblogs.com/xiaohuochai/p/5859476.html
Copyright © 2020-2023  润新知