前端事件綁定知識點(面試常考)

簡介

事件是能夠被 JavaScript 偵測到的行爲。html

網頁中的每一個元素均可以產生某些能夠觸發 JavaScript 函數或程序的事件。node

事件一般與函數配合使用,當事件發生時函數纔會執行。瀏覽器

執行JS 事件的方式:函數

  • HTML 事件屬性能夠直接執行 JavaScript 代碼測試

  • HTML 事件屬性能夠調用 JavaScript 函數this

  • 你能夠爲 HTML 元素指定本身的事件處理程序spa

  • 你能夠阻止事件的發生。代理

  • 等等 ...code

經常使用的JS事件 type
鼠標單擊事件 onclick
鼠標通過事件 onmouseover
鼠標移開事件 onmouseout
聚焦事件 onfocus
失焦事件 onblur
加載事件 onload
刷新頁面 onunload(貌似只對IE有效)
關閉頁面 onbeforeunload(貌似只對IE有效)

事件流

事件流描述的是從頁面中接受事件的順序。htm

  • IE 的事件流是事件冒泡流,事件由子元素獲取並沿DOM樹向上傳播。即事件最開始由最具體的元素(文檔中嵌套層次最深的那個節點)接收,而後逐級向上轉播至最不具體的節點(document),用 stopPropagation() 方法終止冒泡。

  • Netscape 的事件流是事件捕獲流,事件由根元素獲取並沿DOM樹向下分發。與事件冒泡流相反,事件捕獲的思想是不太具體的節點(document)應該更早接收到事件,而最具體的節點最後接收到事件。已經不適用了

Event 對象

HTML DOM Event 對象

header 1 header 2
事件 event
事件目標 event.target
添加事件 element.addEventListener(type, listener, false)
移除事件 element.removeEventListener(type, listener, false)
阻止事件冒泡 event.stopPropagation()
取消默認行爲 event.preventDefault()

IE 中的 Event 對象

header 1 header 2
事件 window.event
事件目標 event.srcElement
添加事件 element.attachEvent('on' + type, listener)
移除事件 element.detachEvent('on' + type, listener)
阻止事件冒泡 event.cancelBubble = true
取消默認行爲 event.returnValue = false

事件處理程序

HTML 事件處理程序

事件直接寫在html的元素裏面,缺點:html和js代碼緊密的耦合在一塊兒。

<a href="" onclick="alert('msg');">測試</a>

0級 DOM事件處理程序

把一個函數賦值給一個事件的處理程序屬性,優勢:比較簡單,跨瀏覽器支持。缺點:不能添加多個事件處理程序,最後一個事件會覆蓋前面的事件

document.getElementById('id').onclick = function () {
    alert(1);
}

2級 DOM事件處理程序

經過 addeventlistener() 添加事件,只能用 removeEventlistener() 刪除此事件。它們都接收三個參數:要處理的事件名event(不加'on')、做爲事件處理程序的函數function(優勢:能夠添加多個事件處理程序,)和一個布爾值useCapture。布爾參數僅僅在現代瀏覽器最近的幾個版本中是可加可不加的,而且true表明該事件在捕獲階段執行,false表明在冒泡階段執行,建議寫false,由於有些瀏覽器只有冒泡階段。

target.addEventListener(type, listener[, useCapture]);
target.removeEventListener(type, listener[, useCapture]);

IE 事件處理程序

IE8 及更早IE版本不支持 addEventListener() 方法,Opera 7.0 及 Opera 更早版本也不支持。 可是,對於這些不支持該函數的瀏覽器,你可使用 attachEvent() 方法來添加事件句柄。經過 attachEvent() 添加事件,只能用 detachEvent() 刪除此事件。這兩個方法接收相同的兩個參數:事件處理程序名稱 type 與事件處理函數 function,不支持第三個參數的緣由:IE8--只支持冒泡冒泡流。

element.attachEvent(type, function)
element.detachEvent(type, function)

事件代理和委託

當咱們須要對不少元素添加事件的時候,能夠經過將事件添加到它們的父節點而將事件委託給父節點來觸發處理函數。這主要得益於瀏覽器的事件冒泡機制。

<div id="box">
    <p>Lorem ipsum dolor sit amet.</p>
    <p>Lorem ipsum dolor sit amet.</p>
    <p>Lorem ipsum dolor sit amet.</p>
</div>

<script>
    let box = document.getElementById('box');
    box.addEventListener('click', function (e) {
        // 檢查事件源e.targe是否爲P
        if (e.target.nodeName === 'P') {
            // 真正的處理過程在這裏
            alert('p');
        }
    })
</script>

跨瀏覽器兼容的事件處理程序(能力檢測)

/*
 * @Author: bxm09
 * @Date:   2017-03-24 15:51:37
 * @Last Modified by:   bxm09
 * @Last Modified time: 2017-07-24 13:16:04
 * @Desc 跨瀏覽器兼容的事件處理程序(能力檢測)
 */

var eventshiv = {
    // event兼容
    getEvent: function(event) {
        return event ? event : window.event;
    },

    // type兼容
    getType: function(event) {
        return event.type;
    },

    // target兼容
    getTarget: function(event) {
        return event.target ? event.target : event.srcelem;
    },

    /**
     * 添加事件句柄
     * 2級 DOM -> IE -> 0級 DOM
     */
    addHandler: function(elem, type, listener) {
        if (elem.addEventListener) {
            elem.addEventListener(type, listener, false);
        } else if (elem.attachEvent) {
            elem.attachEvent('on' + type, listener);
        } else {
            // 在這裏因爲.與'on'字符串不能連接,只能用 []
            elem['on' + type] = listener;
        }
    },

    // 移除事件句柄
    removeHandler: function(elem, type, listener) {
        if (elem.removeEventListener) {
            elem.removeEventListener(type, listener, false);
        } else if (elem.detachEvent) {
            elem.detachEvent('on' + type, listener);
        } else {
            elem['on' + type] = null;
        }
    },

    /**
     * 添加事件代理
     */
    addAgent: function (elem, type, agent, listener) {
        elem.addEventListener(type, function (e) {
            if (e.target.matches(agent)) {
                listener.call(e.target, e); // this 指向 e.target
            }
        });
    },

    /**
     * 取消默認行爲
     * 非IE -> IE
     */
    preventDefault: function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    /**
     * 阻止事件冒泡
     * 非IE -> IE
     */
    stopPropagation: function(event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    }
};

console.log('eventshiv.js 文件加載成功!');
相關文章
相關標籤/搜索