js中事件冒泡与事件捕获

784 阅读4分钟

什么是事件?

js中的事件指的是文档与浏览器窗口发生交互的瞬间,该阶段执行的事件叫做事件处理程序。例如;文档中按钮被点击,窗口缩放,文档进行滚动。

事件流

事件流指的是事件接收事件的顺序,Ie9、Chrome、Firefox,Opera,Safari均实现了Dom2级规范中定义的标准Dom事件,
而Ie8及低版本仍然保留着专有的事件处理方式;说到事件流,就不得说2种事件处理方式,事件冒泡流(微软Ie提出的),事件捕获流 (网景Netscape)。

事件冒泡

Ie提出的事件流叫做事件冒泡,事件冒泡指的是事件由最具体的元素的接收,然后逐级向上传播到最不具体的元素节点。例如;给文档的div添加了
一个click事件,事件冒泡执行的顺序为:div->父级元素->body->html->document;

事件捕获

Netscape提出的事件流叫做事件捕获,时间捕获指的事件由不具体的元素节点更早的接收事件,然后由外及内,一直到最具
体的元素节点接收事件。同样的例子,为文档中div添加了点击事件,执行顺序为:document->html->body->父级元素->div。

DOM事件流

'DOM2级事件'规定了事件流包括3个阶段,顺序为事件捕获->目标阶段->事件冒泡

事件处理程序

响应某个事件的函数叫做事件处理程序,Html事件处理程序、DOM0级事件处理程序
、IE事件处理程序均以‘on’开头;

HTML事件处理程序

    <script type="text/javascript">
        function confirmTest() {
            alert('我被点击了');
        }
    </script>
    <input type='button' value='confirm' onclick='confirmTest()'>

DOM0级事件处理程序

通过javascript为dom元素添加事件处理程序,所有的浏览器都支持,但是必须在DOM节点加载后才会生效。
    <script type="text/javascript">
        var test = document.getElementById('test');
        test.onclick = fucntion(){
            alert('test被点击了');
        }
    </script>
使用DOM0级事件制定的事件处理程序被认为是元素节点的方法,是在元素的作用域中执行,this引用的是当前作用域;而要删除DOM0级事件处理程序可通过div.onclick = null,即指定事件处理程序为null。

DOM2级事件处理程序

DOM2级事件处理程序规定事件绑定方法: 
绑定事件addEventListener('事件名', ‘执行的事件’, boolean值);
删除事件removeEventListener('事件名', ‘执行的时间’, boolean值)。
3个参数分别指的是,事件名称,例如'click','change';事件处理函数,可以为匿名函数,
若后面要删除事件处理程序,则不能为匿名函数,最后一个参数是关键,指的是事件是在
捕获阶段还是在冒泡阶段执行,当为false时,表明是在冒泡阶段执行,当为true时,则为事件捕获阶段执行,默认为false。
    <script type="text/javascript">
        var test = document.getElementById('test');
        // 绑定事件
        function test() {
            alert('点击了test');
        }
        test.addEventListener('click', test, false)
        // 删除事件
        test.removeEventListener('click', test, false);
    </script>

IE事件处理程序

IE8以及IE8以下的版本都不支持addEventListener,仅支持attachEvent,IE9同时支持addEventListener和attachEvent;
使用attachEvent有点不同;
        <script type="text/javascript">
        var test2 = document.getElementById('test2');
        function test2(){
            alert('ie8版本添加了绑定事件');
        })
        test2.attachEvent('onclick', test2);
        // 删除事件
        test2.detachEvent('click', test2);
    </script>
    <script type="text/javascript">
        var div = document.getElementById("myDiv");
        div.attachEvent("onclick", function(event) {
            alert("1");
        });
        div.attachEvent("onclick", function(event) {
            alert("2");
        });
    </script>
IE9和IE10先输出“1”,再输出“2”,而IE8和IE7先输出“2”,再输出“1”。
总结:attachEvent()采用冒泡方式,而addEventListener()可以采用冒泡或事件捕获方式。

阻止事件冒泡

谈到事件冒泡,就不得提阻止事件冒泡了,例如;
     <form id="form1" runat="server">
        <div id="divOne" onclick="alert('我是最外层');">
        <div id="divTwo" onclick="alert('我是中间层!')">
            <a id="hr_three" href="http://www.baidu.com" href="http://www.baidu.com"onclick="alert('我是最里层!')">
                点击我
            </a>
       </div>
       </div>
     </form>
运行页面,点击“点击我”,会依次弹出:我是最里层---->我是中间层---->我是最外层--->然后再链接到百度.
事件冒泡过程(以标签ID表示):hr_three----> divTwo----> divOne 。从最里层冒泡到最外层。
如何来阻止?
1.event.stopPropagation(); 
      <script type="text/javascript">
        $(function() {
            $("#hr_three").click(function(event) {
                event.stopPropagation();
            });
        });
     <script>
再点击“点击我”,会弹出:我是最里层,然后链接到百度
2.return false;
    如果头部加入的是以下代码
    <script type="text/javascript">
       $(function() {
        $("#hr_three").click(function(event) {
        return false;
        });
    });
     <script>
再点击“点击我”,会弹出:我是最里层,但不会执行链接到百度页面
最后总结下阻止事件冒泡的方法:
1.event.stopPropagation(); 
事件处理过程中,阻止了事件冒泡,但是没法阻止默认行为。
2.return false
事件处理过程中,既阻止了事件冒泡,又阻止了默认行为。
3.event.preventDefault();
从其名字就可知道,该方法没有阻止事件冒泡,但是阻止了默认行为。