webApi(二)事件高級(jí)

事件高級(jí)

1 綁定和解綁事件

1.1 綁定事件

給元素添加事件,稱為注冊(cè)事件或者綁定事件。注冊(cè)事件有兩種方式:傳統(tǒng)方式和方法監(jiān)聽(tīng)注冊(cè)方式

(1)傳統(tǒng)注冊(cè)方式: 利用 on 開(kāi)頭的事件 onclick
特點(diǎn):注冊(cè)事件唯一性,同一個(gè)元素同一個(gè)事件只能設(shè)置一個(gè)處理函數(shù),最后注冊(cè)的處理函數(shù)將會(huì)覆蓋前面注冊(cè)的處理函數(shù)
(2)addEventListener 方法監(jiān)聽(tīng)注冊(cè)方式: addEventListener() 方法
特點(diǎn):同一個(gè)元素同一個(gè)事件可以注冊(cè)多個(gè)監(jiān)聽(tīng)器按注冊(cè)順序依次執(zhí)行

方法和參數(shù)

eventTarget.addEventListener(type, listener, useCapture);

  • type:事件類型字符串,比如 click 、mouseover ,注意這里不要帶 on
  • listener:事件處理函數(shù),事件發(fā)生時(shí),會(huì)調(diào)用該監(jiān)聽(tīng)函數(shù)
  • useCapture:可選參數(shù),是一個(gè)布爾值,默認(rèn)是 false。
btn.addEventListener('click', function() {
    alert('hello world');
});

1.2 解綁事件

傳統(tǒng)的監(jiān)聽(tīng)解綁用eventTarget.onclick = null;, 方法監(jiān)聽(tīng)注冊(cè)方式用removeEventListener

eventTarget.removeEventListener(type, listener, useCapture)

<body>
    <div>點(diǎn)我</div>
    <div>點(diǎn)我</div>

    <script>
        var divList = document.getElementsByTagName('div');
        divList[0].onclick = function() {
            alert(111);
            this.onclick = null;
        }

        divList[1].addEventListener('click', fun);
        function fun() {
            alert(222);
            this.removeEventListener('click', fun);
        }
    </script>
</body>

1.3 DOM 事件流

事件發(fā)生時(shí)會(huì)在元素節(jié)點(diǎn)之間按照特定的順序傳播,這個(gè)傳播過(guò)程即 DOM 事件流。

比如我們給一個(gè)div 注冊(cè)了點(diǎn)擊事件,DOM 事件流分為3個(gè)階段:

  • 捕獲階段: 由 DOM 最頂層節(jié)點(diǎn)開(kāi)始,然后逐級(jí)向下傳播到到最具體的元素接收的過(guò)程
  • 當(dāng)前目標(biāo)階段
  • 冒泡階段 : 事件開(kāi)始時(shí)由最具體的元素接收,然后逐級(jí)向上傳播到到 DOM 最頂層節(jié)點(diǎn)的過(guò)程
在這里插入圖片描述

注意:

  • JS 代碼中只能執(zhí)行捕獲或者冒泡其中的一個(gè)階段
  • onclick 和 attachEvent 只能得到冒泡階段
  • addEventListener第三個(gè)參數(shù)如果是 true,表示在事件捕獲階段。用事件處理程序;如果是 false(不寫(xiě)默認(rèn)就是false),表示在事件冒泡階段調(diào)用事件處理程序
  • 實(shí)際開(kāi)發(fā)中我們很少使用事件捕獲,我們更關(guān)注事件冒泡
  • 有些事件是沒(méi)有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
  • 事件冒泡有時(shí)候會(huì)帶來(lái)麻煩,有時(shí)候又會(huì)幫助很巧妙的做某些事件

下面是先son后father, 因?yàn)槭敲芭莸?/p>

<body>
    <div class="father">
        <div class="son"></div>
    </div>

    <script>
        var son = document.querySelector('.son');
        var parent = son.parentElement;
        son.addEventListener('click', function() {
            alert('son');
        });

        parent.addEventListener('click', function() {
            alert('father');
        });
    </script>
</body>

是先f(wàn)ather后son, 因?yàn)槭敲芭莸?/p>

<body>
    <div class="father">
        <div class="son"></div>
    </div>

    <script>
        var son = document.querySelector('.son');
        var parent = son.parentElement;
        son.addEventListener('click', function() {
            alert('son');
        }, true);

        parent.addEventListener('click', function() {
            alert('father');
        }, true);
    </script>
</body>

2 事件對(duì)象

2.1 什么是事件對(duì)象

代碼里的event 就是事件對(duì)象,我們還喜歡的寫(xiě)成 e 或者 evt

        div.onclick = function(event) {
            console.log(event);
        }
        div.addEventListener('click', function(event) {
            console.log(event);
        })

event 對(duì)象代表事件的狀態(tài),比如鍵盤按鍵的狀態(tài)、鼠標(biāo)的位置、鼠標(biāo)按鈕的狀態(tài)

事件對(duì)象有兼容性問(wèn)題,ie678通過(guò)windows.event, 兼容性寫(xiě)法:e = event || windows.event

2.2 事件對(duì)象的常見(jiàn)屬性和方法

在這里插入圖片描述

例如,阻止鏈接跳轉(zhuǎn)

      // 阻止默認(rèn)行為,讓鏈接不跳轉(zhuǎn),或讓提交按鈕不提交
        var a = document.querySelector('a');
        a.addEventListener('click', function(e) {
            // 阻止跳轉(zhuǎn)行為
            e.preventDefault();
        })

阻止鏈接冒泡
e.stopPropagation()

2.3 事件委托(代理、委派)

原理:不是每個(gè)子節(jié)點(diǎn)單獨(dú)設(shè)置事件監(jiān)聽(tīng)器,而是事件監(jiān)聽(tīng)器設(shè)置在其父節(jié)點(diǎn)上,然后利用冒泡原理影響設(shè)置每個(gè)子節(jié)點(diǎn)

    <ul>
        <li>知否知否,應(yīng)是綠肥紅瘦</li>
        <li>知否知否,應(yīng)是綠肥紅瘦</li>
        <li>知否知否,應(yīng)是綠肥紅瘦</li>
        <li>知否知否,應(yīng)是綠肥紅瘦</li>
        <li>知否知否,應(yīng)是綠肥紅瘦</li>
    </ul>

如果要點(diǎn)擊每個(gè) li 都會(huì)彈出對(duì)話框,以前需要給每個(gè) li 注冊(cè)事件,是非常辛苦的,而且訪問(wèn) DOM 的次數(shù)越多,這就會(huì)延長(zhǎng)整個(gè)頁(yè)面的交互就緒時(shí)間。利用事件委托可以給 ul 注冊(cè)點(diǎn)擊事件,然后利用事件對(duì)象的 target 來(lái)找到當(dāng)前點(diǎn)擊的 li,因?yàn)辄c(diǎn)擊 li,事件會(huì)冒泡到 ul 上,ul 有注冊(cè)事件,就會(huì)觸發(fā)事件監(jiān)聽(tīng)器

    <script>
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            alert('知否知否,應(yīng)是綠肥紅瘦');
            e.target.style.backgroundColor = 'pink';
        })
    </script>

2.4 常用的鼠標(biāo)事件

2.4.1 基礎(chǔ)鼠標(biāo)事件
在這里插入圖片描述
2.4.2 禁止鼠標(biāo)選中文字和右鍵菜單
    <script>
        // 禁用右鍵菜單
        document.addEventListener('contextmenu', function(e) {
            e.preventDefault();
        });
        document.addEventListener('selectstart', function(e) {
            e.preventDefault();
        });
    </script>
2.4.3 鼠標(biāo)事件對(duì)象

event對(duì)象代表事件的狀態(tài),跟事件相關(guān)的一系列信息的集合?,F(xiàn)階段主要是用鼠標(biāo)事件對(duì)象PointerEvent 和鍵盤事件對(duì)象 KeyboardEvent

2.4.3.1 e.target和this區(qū)別

e.target返回的是觸發(fā)事件的對(duì)象, this返回的是綁定事件對(duì)象

    <script>
        // e.target返回的是觸發(fā)事件的對(duì)象, this返回的是綁定事件對(duì)象
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            console.log(e.target);   // li
            console.log(this);    // ul
        })
    </script>
2.4.3.2 鼠標(biāo)事件對(duì)象屬性
在這里插入圖片描述
2.4.3.3 跟隨鼠標(biāo)的天使
    <style>
        img {
            position: absolute;
        }
    </style>
<body>
    <img src="images/angel.gif">

    <script>
        var img = document.querySelector('img');
        document.addEventListener('mousemove', function(e) {
            var x = e.pageX;
            var y = e.pageY;
            img.style.left = x - 50 + 'px';
            img.style.top = y - 40 + 'px';
        })
    </script>
</body>

2.5 常用的鍵盤事件

2.5.1 常用的鍵盤事件
  • keyup : 某個(gè)鍵盤彈起時(shí)
  • keydown: 某個(gè)鍵盤按下時(shí)
  • keypress: 非功能鍵按下時(shí)

三個(gè)鍵盤事件執(zhí)行順序是:keydown -- keypress --- keyup

<body>
    <script>
        document.addEventListener('keyup', function() {
            console.log('鍵盤彈起');
        });
        document.addEventListener('keydown', function() {
            console.log('鍵盤按下');
        });
        document.addEventListener('keypress', function() {
            console.log('非功能鍵按下');
        });
    </script> 
</body>
2.5.2 鍵盤事件對(duì)象

keyCode: 返回該鍵的ascall值

  • keyup和keydown的keyCode不區(qū)分大小寫(xiě),'a'和'A'都是65
  • keypress的keyCode區(qū)分大小寫(xiě),'a'是65, 'A'是97
  • 在我們實(shí)際開(kāi)發(fā)中,我們更多的使用keydown和keyup, 它能識(shí)別所有的鍵(包括功能鍵)
2.5.3 模擬京東按鍵輸入內(nèi)容

當(dāng)按下 s 鍵, 光標(biāo)就定位到搜索框

<body>
    <div class="search">
        <input placeholder="打印機(jī)">
        <button>搜索</button>
    </div>

    <script>
        var input = document.querySelector('input');
        document.addEventListener('keyup', function(e) {
            if(e.keyCode === 83) {
                input.focus();
            }
        })
    </script>
</body>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容