天天看點

javascript 事件的捕獲和冒泡

1、說明

對于“捕獲"與"",我們可能對冒泡更熟悉一些,因為在所有的浏覽器中,都支援事件冒泡,即事件由子元素向祖先元素傳播,

如氣泡從水底向水面上浮一樣,而在firefox,chrome這種标準的浏覽器中,事件傳播還有一個階段,那就是捕獲階段,這個很少有人用,是以常常被人疏忽,

捕獲就是與冒泡完全相反的過程,即事件有祖先元素,向子元素傳播,如同将一個石子從水面沉到水底一樣,但是在IE,opera浏覽器中,是不存在這個階段的,

這個可以從各個浏覽器提供的注冊事件監聽方法中可知(具體的可以去了解注冊事件監聽)

測試代碼如下:

<span style="font-family:Comic Sans MS;font-size:12px;"><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    
</head>
<body>

    <div id="obj_level0" style="height:100px;background-color:green;">
        <h2>第一層</h2>
        <div id="obj_level1_0" style="background-color:gray;">
            <h2>第二層</h2>
            <div id="obj_level2_0" style="position:absolute;left:100px;top:150px;background-color:blue;width:300px;height:100px;">
                <h2>第三層</h2>
            </div>
        </div>
        <div id="obj_level1_1" style="background-color:darkgreen;margin-top:200px;height:60px;">
            <h2>第二層-元素二</h2>

        </div>
    </div>
    <script type="text/javascript">
        //綁定事件
        function bindEvent(elem, type, fn) {
            if (elem.attachEvent) {
                var typeRef = "_" + type;
                if (!elem[typeRef]) {
                    elem[typeRef] = [];
                }
                for (var i in elem[typeRef]) {
                    if (elem[typeRef][i] == fn) {
                        return;
                    }
                }
                elem[typeRef].push(fn);
                elem["on" + type] = function () {
                    for (var i in this[typeRef]) {
                        this[typeRef][i].apply(this, arguments);
                    }
                }
            } else {
                elem.addEventListener(type, fn, false);//false冒泡,true 捕獲
            }
        }
        //移除事件綁定
        function removeEvent(elem, type, fn) {
            if (elem.detachEvent) {
                if (elem["_" + type]) {
                    for (var i in elem["_" + type]) {
                        if (elem["_" + type][i] == fn) {
                            elem["_" + type].splice(i, 1);
                            break;
                        }
                    }
                }
            } else {
                elem.removeEventListener(type, fn, false);
            }
        }

        var divs = document.getElementsByTagName("div");
        var count = 1;
        for (var i = 0; i < divs.length; i++) {
            bindEvent(divs[i], "click", function () {
                var obj = document.createTextNode("->" + count++);
                this.getElementsByTagName("h2")[0].insertBefore(obj, null);
            });
        }

    </script>
    

</body>
</html></span>
           

在執行個體中,我們注冊事件監聽預設發生在冒泡階段,第一層,第二層,第三層有嵌套關系,

為了更好的測試冒泡,我們首先點選第三層,會看到在各個浏覽器中的效果是一緻的,說明所有的浏覽器都支援冒泡

另外事件冒泡與視覺上的布局沒有任何關系,這個冒泡僅僅依賴于dom元素的html結構,浏覽器示範效果如下:

javascript 事件的捕獲和冒泡

說完了冒泡,我們下面說捕獲,将代碼中的

 elem.addEventListener(type, fn, false);//false冒泡,true 捕獲,修改為true,就變成了捕獲,

 捕獲需要在firefox,chrome浏覽器下運作,檢視效果,同上面一樣,點選第三層檢視效果,效果圖如下:

javascript 事件的捕獲和冒泡

繼續閱讀