API之事件的綁定和事件的冒泡

目錄

  • 事件綁定的兩種方法
  • 事件綁定的兼容代碼
  • 綁定事件的區別
  • 解綁
  • 綁定事件和解綁事件的兼容代碼
  • 事件冒泡
  • 阻止事件冒泡
  • 事件的三個階段
  • 爲同一個元素註冊不一樣的事件,指向相同的事件處理函數

元素綁定的兩種方法

  • 第一種:addEventListener('事件類型', 事件處理函數, false)-----谷歌火狐支持,IE8不支持
  • attachEvent('帶on的事件類型',事件處理函數)-----谷歌火狐不支持,IE8支持
<body>
    <input type="button" value="按鈕" id="btn">
    <script>
        var btn = document.getElementById('btn');
        //爲按鈕綁定點擊事件: DOM中,只有一種,可是不兼容,因此有兩種
        //第一種:addEventListener('事件類型', 事件處理函數, false)-----谷歌火狐支持,IE8不支持
        //參數1: 事件的類型----也就是事件的名字,沒有on
        //參數2:  事件處理函數----也就是函數(命名函數或匿名函數)
        //參數3:  Boolean類型,暫時爲false
        //第二種: attachEvent('帶on的事件類型',事件處理函數)-----谷歌火狐不支持,IE8支持
        //參數1: 事件類型----帶on
        //參數2: 事件處理函數-----函數(命名或匿名)


        btn.addEventListener('click', function() {
            console.log('明智之舉');
        }, false);
        btn.addEventListener('click', function() {
            console.log('做詞:許嵩');
        }, false);
        btn.addEventListener('click', function() {
            console.log('做曲:許嵩');
        }, false);
        btn.addEventListener('click', function() {
            console.log('演唱:許嵩');
        }, false);

        // btn.attachEvent('onclick', function() {
        //     console.log('明智之舉');
        // });
        // btn.attachEvent('onclick', function() {
        //     console.log('如約而至');
        // });
        // btn.attachEvent('onclick', function() {
        //     console.log('許嵩');
        // });
    </script>
</body>

事件綁定的兼容代碼

//爲任意一個元素,綁定任意事件    任意元素, 事件的類型,事件處理函數
        function addEventListener(element, type, fn) {
            if (element.addEventListener) { //判斷這個瀏覽器是否支持這個方法
                element.addEventListener(type, fn, false);
            } else if (element.attachEvent) {
                element.attachEvent('on' + type, fn); //element.attachEvent('onclick',function(){})
            } else {
                element['on' + type] = fn; // element.onclick = function() {}
            }
        }

事件綁定的區別

相同點數組

  • 均可覺得元素綁定事件瀏覽器

    不一樣點函數

  • 方法名不同
    • addEventListener
    • attachEvent
  • 參數個數不同
    • addEventListener有三個參數
    • attachEvent只有兩個參數
  • 瀏覽器支持不同
    • addEventListener 谷歌、火狐、IE11支持,IE8不支持
    • attachEvent IE不支持,谷歌、火狐、IE11不支持
  • this不一樣
    • addEventListener中的this指的是當前綁定事件的對象
    • attachEvent中的this指的是window
  • 事件類型不一樣
    • addEventListener中的事件類型沒有on
    • attachEvent中的事件類型有on

解綁

注意用什麼方式綁定事件,就用什麼方式解綁事件this

第一種code

  • 對象.on事件名= 事件處理函數------------綁定事件
  • 對象.on事件名 = null; -------------解綁事件
//點擊第二個按鈕,解除第一個按鈕的綁定事件
        var btn = document.getElementById('btn');
        var btn1 = document.getElementById('btn1');
        btn.onclick = function() {
            console.log('Worth it');
        }
        btn1.onclick = function() {
            //解綁事件
            btn.onclick = null;
        }

第二種對象

  • 對象.addEventListener('事件類型', 命名函數, false)----------綁定事件
  • 對象.removeEventListener('事件類型', 命名函數, false)-------解綁事件
var btn = document.getElementById('btn');
        var btn1 = document.getElementById('btn1');

        function f3() {
            console.log('明智之舉');
        }

        function f4() {
            console.log('做詞:許嵩');
        }
        btn.addEventListener('click', f3, false);
        btn.addEventListener('click', f4, false);


        btn1.onclick = function() {

            //這種方式解綁的時候須要使用命名函數
            btn.removeEventListener('click', f4, false);
        }

第三種索引

  • 對象.attachEvent('帶on的事件類型', 命名函數);
  • 對象.detachEvent('帶on的事件類型', 命名函數);
var btn = document.getElementById('btn');
        var btn1 = document.getElementById('btn1');

        function f3() {
            console.log('明智之舉');
        }

        function f4() {
            console.log('做詞:許嵩');
        }
 btn.attachEvent('onclick', f3);
        btn.attachEvent('onclick', f4);

        btn1.onclick = function() {
            btn.detachEvent('onclick', f3);
        };

綁定事件和解綁時間的兼容代碼

<input type="button" value="歌曲" id="btn">
<input type="button" value="清空歌曲" id="btn1">

<body>
    <script src='common.js'></script>
    <script>
        //綁定事件的兼容代碼
        function addEventListener(element, type, fn) {
            if (element.addEventListener) {
                element.addEventListener(type, fn, false);
            } else if (element.attachEvent) {
                element.attachEvent('on' + type, fn);
            } else {
                element['on' + type] = fn;
            }
        }
        //解綁事件的兼容代碼
        function removeEventListener(element, type, fnName) {
            if (element.removeEventListener) {
                element.removeEventListener(type, fnName, false);
            } else if (element.detachEvent) {
                element.detachEvent('on' + type, fnName);
            } else {
                element['on' + type] = null;
            }
        }
        //test
        function f1() {
            console.log('明智之舉');
        }

        function f2() {
            console.log('做詞:許嵩');
        }
        addEventListener(my$("btn"), "click", f1);
        addEventListener(my$("btn"), "click", f2);
        my$("btn1").onclick = function() {
            removeEventListener(my$("btn"), "click", f1);
        };
    </script>

事件冒泡

多個元素嵌套,有層次關係,這些元素都註冊了相同的事件,若是裏面的元素的事件被觸發了,外面元素的事件自動被觸發seo

<style>
        #dv1 {
            width: 300px;
            height: 400px;
            background-color: #def;
        }
        
        #dv2 {
            width: 250px;
            height: 350px;
            background-color: #edf;
        }
        
        #dv3 {
            width: 200px;
            height: 300px;
            background-color: #fed;
        }
    </style>
</head>

<body>
    <div id="dv1">
        <div id="dv2">
            <div id="dv3"></div>
        </div>
    </div>
    <script>
        //事件冒泡:多個元素嵌套,有層次關係,這些元素都註冊了相同的事件,若是裏面的元素的事件觸發了,外面的元素的該事件自動觸發   
        var dv1 = document.getElementById('dv1');
        var dv2 = document.getElementById('dv2');
        var dv3 = document.getElementById('dv3');

        dv1.onclick = function() {
            console.log('dv1');//dv1
        }
        dv2.onclick = function() {
            console.log('dv2');//dv2 dv1
        }
        dv3.onclick = function() {
            console.log('dv3');//dv3 dv2 dv1
        }
    </script>

阻止事件冒泡

  1. window.event.cancelBubble = true;//谷歌,IE8支持,但火狐不支持
  2. e.stopPropagation();//谷歌、火狐支持,可是IE8不支持
<style>
        #dv1 {
            width: 300px;
            height: 400px;
            background-color: #def;
        }
        
        #dv2 {
            width: 250px;
            height: 350px;
            background-color: #edf;
        }
        
        #dv3 {
            width: 200px;
            height: 300px;
            background-color: #fed;
        }
    </style>
</head>

<body>
    <div id="dv1">
        <div id="dv2">
            <div id="dv3"></div>
        </div>
    </div>
    <script>
        var dv1 = document.getElementById('dv1');
        var dv2 = document.getElementById('dv2');
        var dv3 = document.getElementById('dv3');
        // 在事件被觸發時會產生一個事件處理對象參數
        //如何阻止事件冒泡
        //1. window.event.cancelBubble = true;//谷歌,IE8支持,但火狐不支持
        //2.  e.stopPropagation();//谷歌、火狐支持,可是IE8不支持
        dv1.onclick = function() {
            console.log(this.id);
        }
        dv2.onclick = function(e) { //這裏的e就是事件觸發時產生的事件處理對象參數
            console.log(this.id);
            //阻止事件冒泡
            e.stopPropagation();
        }
        dv3.onclick = function() {
            console.log(this.id);
            //阻止事件冒泡
            window.event.cancelBubble = true;
        }
    </script>

</body>

事件的三個階段

  • 1表示事件捕獲階段----------> 從外向內
  • 2表示事件目標階段
  • 3表示事件冒泡階段----------> 從內向外
  • 案例
<style>
        #dv1 {
            width: 300px;
            height: 400px;
            background-color: #def;
        }
        
        #dv2 {
            width: 250px;
            height: 350px;
            background-color: #edf;
        }
        
        #dv3 {
            width: 200px;
            height: 300px;
            background-color: #fed;
        }
    </style>
</head>

<body>
    <div id='dv1'>
        <div id="dv2">
            <div id="dv3"></div>
        </div>
    </div>
    <script>
     
        //同時註冊點擊事件
        var objs = [document.getElementById('dv1'),
            document.getElementById('dv2'),
            document.getElementById('dv3')
        ];


        //遍歷註冊事件
        objs.forEach(function(ele) { //傳一個參數的時候,這個參數是元素
            //爲每一個元素綁定事件;
            //   ele.addEventListener('click', function() {
            //     console.log(this.id + '--------->' + window.event.eventPhase);
            // }, false);
            ele.addEventListener('click', function() {
                console.log(this.id + '--------->' + window.event.eventPhase);
            }, true);
        });

        //array.forEach(function(數組當前項的值, 數組當前的索引,數組對象自己){

        //});
    </script>
  • 總結
爲元素綁定事件
            addEventLinstener('沒有on的事件類型',事件處理函數,控制事件階段的)
            false------>表示事件冒泡階段(從內向外 或者 從上到下)
            true-------> 表示事件捕獲階段(從外向內 或者 從下到上)
            事件觸發的過程當中可能會出現事件冒泡的效果,爲了阻止事件冒泡----->
            1. window.event.cancelBubble = true;谷歌,IE8支持,火狐不支持
            window.event就是一個對象,是IE的標準
            2. e.stopPropagation();
            window.event 和 e 都是事件參數對象,一個是IE標準,一個是火狐標準
            事件參數e在IE8中的瀏覽器中是不存在的,此時用window.event來代替

            addEventLinstener中的第三的參數是用來控制事件階段的
            事件階段有三個
            1-----》事件捕獲階段
            2-----》事件目標階段
            3-----》事件冒泡階段
            通常默認用冒泡階段,不多用捕獲階段

爲同一個元素註冊不一樣的事件,指向相同的事件處理函數

<body>
    <input type="button" value="nice!" id='btn'>

    <script>
        var btn = document.getElementById('btn');
        btn.onclick = f1;
        btn.onmouseover = f1;
        btn.onmouseout = f1;

        function f1(e) {
            switch (e.type) {
                case 'click':
                    alert("nice!");
                    break;
                case 'mouseover':
                    this.style.backgroundColor = '#def';
                    break;
                case 'mouseout':
                    this.style.backgroundColor = '#fed';
                    break;
            }
        }
    </script>
</body>
相關文章
相關標籤/搜索