二级事件模型

全部代码: 

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>二级事件模型</title>
        <style>
            p, li {
                line-height: 150%;
            }
            
            div {
                padding: 10px 5px;
            }
            
            .ul {
                width: 50%;
                background: #ccc;
                padding: 30px;
                margin: 0;
            }
            
            .ul li {
                margin: 15px;
                background: #84cf39;
                color: #fff;
                list-style: none;
                padding: 5px;
            }
        </style>
        <script type="text/javascript">
            var $ = function(elmID){
                return document.getElementById(elmID);
            }
            
            var getNodeName = function(e){
                var e = e || window.event;
                return e.toElement.nodeName;
            }
            
            window.onload = function(){
                var ul = $('eventUl');
                var result = $('result').getElementsByTagName('span')[0];
                var attachEventName = window.addEventListener ? 'addEventListener' : 'attachEvent';
                var mouseoverName = window.addEventListener ? 'mouseover' : 'onmouseover';
                
                var fn1 = function(e){
                    result.innerHTML += ' <br/>绑定在ul上的mouseover,事件的触发来自' + getNodeName(e) + '标签(冒泡),';
                }
                var fn2 = function(e){
                    result.innerHTML += ' <br/>绑定在ul上的mouseover,事件的触发来自' + getNodeName(e) + '标签(捕获),';
                }
                ul[attachEventName](mouseoverName, fn1);
                ul[attachEventName](mouseoverName, fn2, true);
                
                var lis = ul.getElementsByTagName('li');
                var fn3 = function(e){
                    result.innerHTML += ' <br/>绑定在li上的mouseover,终止向上冒泡(冒泡),';
                    if (e) {
                        e.stopPropagation();
                    }
                    else {
                        window.event.cancelBubble = true;
                    }
                }
                
                var fn4 = function(e){
                    result.innerHTML += ' <br/>LI事件的捕获,';
                    if (e) {
                        e.stopPropagation();
                    }
                    else {
                        window.event.cancelBubble = true;//IE的享元模式
                    }
                }
                
                lis[0][attachEventName](mouseoverName, fn3, false);
                
            };
        </script>
    </head>
    <body>
        <div>
            <p>
                先通过demo展示: 为ul分别绑定mouseover的捕获与冒泡事件,为第一个li绑定mouseover的冒泡事件,并终止向上冒泡(stopPropagation)
            </p>
        </div>
        <div>
            Demo:
        </div>
        <ul class="ul" id="eventUl">
            <li>
                第一条(不再向上冒泡)
            </li>
            <li>
                第二条
            </li>
            <li>
                第三条
            </li>
        </ul>
        <div id="result">
            监听结果:<span></span>
        </div>
        <div>
            <p>
                当鼠标移到灰色区域(ul),再逐渐移到第一条绿色区域(li),再移回到灰色区域 就会看到有意思的一组记录了。
            </p>
            <p>
                绑定在ul上的mouseover,事件的触发来自UL标签(冒泡), 
                绑定在ul上的mouseover,事件的触发来自UL标签(捕获), 
                <br/>
                绑定在ul上的mouseover,事件的触发来自LI标签(捕获), 
                绑定在li上的mouseover,终止向上冒泡(冒泡), 
                <br/>
                绑定在ul上的mouseover,事件的触发来自UL标签(冒泡), 
                绑定在ul上的mouseover,事件的触发来自UL标签(捕获),
            </p>
            <p>
                当然还可以从灰色区域(ul)移到第二条绿色区域(li)看一下向上冒泡的展示结果,下面是相关的原理解释(关于浏览器兼容处理细节就查看源代码吧):
            </p>
            <ul>
                <li>
                    二级事件模型:
                    <br/>
                    [document -> <body> -> ... ->] [<a;></a>] [ -> ... -> <body> -> document] 
                    <br/>
                    [捕获] -> [命中] -> [冒泡]
                </li>
                <li>
                    事件监听的最后一个参数可选,不传默认是false冒泡,true绑定捕获。
                </li>
                <li>
                    浏览器支持情况良好,我测试了IE6和chrome都符合上面事件模型,但是事件的监听和事件参数的处理需要做兼容性处理。
                    非IE:队列式,addEventListener,removeEventListener,事件无on  ---- IE:堆栈式,attachEvent,detachEvent,事件有on
                </li>
                <li>
                    在命中的元素上,高级浏览器(chrome,IE9等)先触发冒泡再触发捕获,而IE6,7,8则是先捕获后冒泡,这个现象我个人觉得比较奇怪。
                </li>
                <li>
                    鼠标从内层元素一道外层元素时任然会触发外层元素的监听事件。
                </li>
                <li>
                    事件的向上冒泡可以用e.stopPropagation()或window.event.cancelBubble = true来终止事件向上冒泡。
                </li>
            </ul>
            <p>
            </p>
        </div>
    </body>
</html>
  

  

原理介绍(如果要验证原理的正确性,可以直接运行上面代码):

先通过demo展示: 为ul分别绑定mouseover的捕获与冒泡事件,为第一个li绑定mouseover的冒泡事件,并终止向上冒泡(stopPropagation)。

监听结果:

当鼠标移到灰色区域(ul),再逐渐移到第一条绿色区域(li),再移回到灰色区域 就会看到有意思的一组记录了。

绑定在ul上的mouseover,事件的触发来自UL标签(冒泡), 绑定在ul上的mouseover,事件的触发来自UL标签(捕获), 
绑定在ul上的mouseover,事件的触发来自LI标签(捕获), 绑定在li上的mouseover,终止向上冒泡(冒泡), 
绑定在ul上的mouseover,事件的触发来自UL标签(冒泡), 绑定在ul上的mouseover,事件的触发来自UL标签(捕获),

当然还可以从灰色区域(ul)移到第二条绿色区域(li)看一下向上冒泡的展示结果,下面是相关的原理解释(关于浏览器兼容处理细节就查看源代码吧):

  • 二级事件模型: 
    [document -> <body> -> ... ->] [<a;></a>] [ -> ... -> <body> -> document] 
    [捕获] -> [命中] -> [冒泡]
  • 事件监听的最后一个参数可选,不传默认是false冒泡,true绑定捕获。
  • 浏览器支持情况良好,我测试了IE6和chrome都符合上面事件模型,但是事件的监听和事件参数的处理需要做兼容性处理。 非IE:队列式,addEventListener,removeEventListener,事件无on ---- IE:堆栈式,attachEvent,detachEvent,事件有on
  • 在命中的元素上,高级浏览器(chrome,IE9等)先触发冒泡再触发捕获,而IE6,7,8则是先捕获后冒泡,这个现象我个人觉得比较奇怪。
  • 鼠标从内层元素一道外层元素时任然会触发外层元素的监听事件。
  • 事件的向上冒泡可以用e.stopPropagation()或window.event.cancelBubble = true来终止事件向上冒泡。

 

 jq停止向上冒泡:

$('span').bind("click",function(event){
        var txt = $('#msg').html() + "<p>内层span元素被点击.<p/>";
        $('#msg').html(txt);
        event.stopPropagation();    //  阻止事件冒泡
    });

  

 

 

posted @ 2013-11-12 18:09  龙则  阅读(489)  评论(0编辑  收藏  举报