JavaScript中綁定事件監聽函數的通用方法addEvent() 和 事件綁定之bindEvent()與 unBindEvent()函數

下面綁定事件的代碼,進行了兼容性處理,可以被全部瀏覽器支持:javascript

function addEvent(obj,type,handle){
    try{  // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
        obj.addEventListener(type,handle,false);
    }catch(e){
        try{  // IE8.0及其如下版本
            obj.attachEvent('on' + type,handle);
        }catch(e){  // 早期瀏覽器
            obj['on' + type] = handle;
        }
    }
}

這裏使用 try{ ... } catch(e){ ... } 代替 if ... else... 語句,避免瀏覽器出現錯誤提示。css

bindEvent(element, eventName, func) —— 綁定func到element的eventName事件上(不重複綁定)html

unBindEvent(element, eventName, func) —— 刪除element上的eventName事件上的func函數。前端

下面是這兩個函數的源碼:java

// ---------- 事件綁定與刪除綁定 ---------- //
function bindEvent(element, eventName, func) {
    var events = element['the'+eventName];    //用於保存某個事件序列
    if(!events) {  //若是不存在一個序列,則建立它,並加入HTML標記當中的onEvent = function(){}形式的綁定
        events = element['the'+eventName] = [];
        if (element['on'+eventName]) { events.push(element['on'+eventName]); }
    }
    
    //檢測是否爲重複綁定
    for(var i=0; i<events.length; i++) {
        if(events[i] === func) { flag = true; break; }
    }
    
    // 非重複綁定,則加入該函數事件
    if(i >= events.length) { events.push(func); }
    
    // 從新定義這個事件的執行方式
    element['on'+eventName] = function(event) {
        event = event || (function() { //修復IE的事件對象
            var e = window.event;
            e.preventDefault = function() { e.returnValue = false; }
            e.stopPropagation = function() { e.cancelBubble = true; }
            //根據須要繼續修復
            return e;
        })();
        //順序執行這些函數
        for(var i=0; i<events.length; i++) { events[i].call(element, event); }
    }
}

// 刪除事件綁定
function unBindEvent(element, eventName, func) {
    var events = this['the'+eventName];
    //若是不存在一個事件序列
    if(!events) { return false; }
    
    //檢測該函數是否存在該事件序列當中
    for(var i=0; i<events.length; i++) {
        if(func === events[i]) {
            [].splice.call(events, i, 1);
            return true;
        }
    }
    
    // 函數不存在該事件序列當中
    return false;
}

該事件綁定函數具備以下特色:web

一、在事件函數中,this指向的是當前元素瀏覽器

二、每一個事件實際上是一個有序列,按順序執行這個序列。函數

三、正確的傳遞了event對象。對於event對象在W3C標準與IE中的不一樣之處能夠作出修復,本例修復了事件冒泡與阻止默認行爲。測試

四、本機測試經過IE、Firefox、Chrome、Opera、Safari(能夠說通用主流瀏覽器)ui

五、支持刪除事件綁定

固然,還得拿來作一個測試,下面是測試的代碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無標題文檔</title>
<style type="text/css">
#test {background-color: #f00; }
</style>
<script type="text/javascript" src="event.js"></script>
<script type="text/javascript">
bindEvent(window, 'load', function() {
    var ul = document.getElementById("test");
    var a = document.getElementById("baidu");
    
    bindEvent(ul, 'click', function(e){
        alert("我是" + this + "元素, 你點擊了我!");
    });
    
    
    bindEvent(a, 'click', function(e) {
        alert("我是" + this + ",你點擊了我!");
    });
    
});
</script>
</head>

<body>
<ul id="test">
  <p class="t">Hello,world!</p>
  <p>Hello,<a href="http://www.baidu.com" id="baidu">百度</a>!</p>
  <li id="haha" class="t">afasdfsa</li>
  <li>sfk</li>
  <li class="t">sdklfajsfjk</li>
  <li>end</li>
  <li class="te">of</li>
</ul>
<ol id="test2">
  <li class="t">附加的第一項</li>
  <li class="t">附加的第二項</li>
  <li class="t">附加的第三項</li>
</ol>
</body>
</html>

首先,點擊紅色的UL試試看 —— 將預期彈出:你好,我是HTMLUListElement元素,你點擊了我!

好的,再點一下其中的百度連接 ——

        預期彈出:你好,我是http://www.baidu.com/,你點擊了我!

        非預期彈出:你好,我是HTMLULlistElement元素,你點擊了我?

爲何非預期彈出?——對,這就是事件的冒泡,當咱們點擊百度的連接後,該事件將產生冒泡,過程如:<a> -- <li> -- <ul> -- <body> -- document。而ul咱們綁定了一個單擊事件,因此這時將觸發其click事件,而出了非預期彈出。

那麼如何阻止?在綁定百度連接的函數體後追加一行:e.stopPropagation(),再次測試:非預期彈出已經沒有了。

若是我只想在點擊百度連接時,彈出對話框,而不跳轉到百度去呢?在綁定百度連接的函數體再次追加一行:e.preventDefault();

測試完畢!具備懷疑精神的朋友能夠Copy以後,另作其它測試!!!!

轉載自web前端開發

相關文章
相關標籤/搜索