事件歸納 | JavaScript中事件的綁定與解綁


要想讓 JavaScript 對用戶的操作作出響應,首先要對 DOM 元素綁定事件處理函數。所謂事件處理函數,就是處理用戶操作的函數,不同的操作對應不同的名稱。

目錄:

一. 在DOM元素中直接綁定

#點擊按鈕顯示彈出
<input type="button"  onclick="alert('原生函數觸發')" value="點我彈出警告框" />
#或者
<input type="button"  onclick="MyAlert()" value="點我彈出警告框" />
<script type="text/javascript">
    function MyAlert(){
        alert("原生函數觸發");
    }
</script>

二. 在JavaScript代碼中綁定

#為 id="demo" 的按鈕綁定一個事件,顯示它的 type 屬性:
<input id="demo" type="button" value="點我顯示 type 屬性" />
<script type="text/javascript">
    document.getElementById("demo").onclick=function(){
        alert(this.getAttribute("type")); 
    }
</script>
#解綁事件
 document.getElementById("demo").onclick= null;

如果為同一個元素同時綁定多個事件,前面的事件會被后面的事件覆蓋,需指向相同的事件處理函數 **

<body>
<input type="button" value="" id="btn"/>
<script>
    //為同一個元素綁定多個不同的事件,指向相同的事件處理函數
    document.getElementById("btn").onclick = f1;
    document.getElementById("btn").onmouseover = f1;
    document.getElementById("btn").onmouseout = f1;
 
    function f1(e) {
        switch (e.type) {
            case "click":
                alert("1");
                break;
            case "mouseover":
                this.style.backgroundColor = "red";
                break;
            case "mouseout":
                this.style.backgroundColor = "green";
                break;
        }
    }
</script>
</body>

三. 綁定事件監聽函數

使用 addEventListener() 或 attachEvent() (兼容ie8)來綁定事件監聽函數。(注:可以綁定多個事件)
addEventListener()函數語法:

elementObject.addEventListener(eventName,handle,useCapture);

參數說明:

  1. elementObject: DOM對象(即DOM元素)。
  2. eventName: 事件名稱。注意,這里的事件名稱沒有“ on ”,如鼠標單擊事件 click ,鼠標雙擊事件 doubleclick ,鼠標移入事件 mouseover,鼠標移出事件 mouseout 等。
  3. handle: 事件句柄函數,即用來處理事件的函數。 (注:函數名,不能帶小括號)
  4. useCapture: Boolean類型,是否使用捕獲,一般用false 。(默認冒泡)
function f1() {};
function f2() {};
document.getElementById("demo1").addEventListener("click", f1, false);
document.getElementById("demo2").addEventListener("click", f2, false);
    //點擊第二個按鈕把第一個按鈕的第一個點擊事件解綁
    document.getElementById("demo1").onclick = function () {
        //解綁事件的時候,需要在綁定事件的時候,使用命名函數
        document.getElementById("demo2").removeEventListener("click", f1, false);
    };

attachEvent()函數語法:(不支持捕獲)

elementObject.attachEvent(eventName,handle);

參數說明:

  1. elementObject: DOM對象(即DOM元素)。
  2. eventName: 事件名稱。注意,與addEventListener()不同,這里的事件名稱有“ on ”,如鼠標單擊事件 onclick ,鼠標雙擊事件 ondoubleclick ,鼠標移入事件 onmouseover,鼠標移出事件 onmouseout 等。
  3. handle: 事件句柄函數,即用來處理事件的函數。(注:函數名,不能帶小括號)
function f1() {};
function f2() {};
document.getElementById("demo1").attachEvent("onclick", f1);
document.getElementById("demo2").attachEvent("onclick", f2);
    //點擊第二個按鈕把第一個按鈕的第一個點擊事件解綁
    document.getElementById("demo1").onclick = function () {
        //解綁事件的時候,需要在綁定事件的時候,使用命名函數
        document.getElementById("demo2").detachEvent("onclick", f1);
    };

addEventListener()是標准的綁定事件監聽函數的方法,是W3C所支持的,Chrome、FireFox、Opera、Safari、IE9.0及其以上版本都支持該函數;但是,IE8.0及其以下版本不支持該方法,它使用attachEvent()來綁定事件監聽函數。所以,這種綁定事件的方法必須要處理瀏覽器兼容問題。

#下面綁定事件的代碼,進行了兼容性處理,能夠被所有瀏覽器支持:
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;
        }
    }

}

事件冒泡

多個元素嵌套,有層次關系,這些元素都注冊了相同的事件,如果里面的元素的事件觸發了,外面的元素的該事件自動的觸發了

#點擊dv3會一次觸發dv2、dv1

<div id="dv1">
    <div id="dv2">
        <div id="dv3"></div>
    </div>
</div>

<script>
    document.getElementById("dv1").onclick = function () {
        console.log(this.id);
    };
    document.getElementById("dv2").onclick = function () {
        console.log(this.id);
    };
    document.getElementById("dv3").onclick = function () {
        console.log(this.id);
    };

**阻止事件冒泡 **

#window.event.cancelBubble=true;
<script>
    document.getElementById("dv1").onclick = function () {
        console.log(this.id);
    };
    document.getElementById("dv2").onclick = function () {
        console.log(this.id);
        //阻止事件冒泡
        // IE特有的,谷歌支持,火狐不支持
        window.event.cancelBubble=true;
    };
    document.getElementById("dv3").onclick = function () {
        console.log(this.id);
    };
</script>
#e.stopPropagation();
<script>
    document.getElementById("dv1").onclick = function () {
        console.log(this.id);
    };
    document.getElementById("dv2").onclick = function (e) {
        console.log(this.id);
        //阻止事件冒泡
        //谷歌和火狐支持
        e.stopPropagation();
    };
    document.getElementById("dv3").onclick = function () {
        console.log(this.id);
    };
</script>

**事件階段 **
通過e.eventPhase這個屬性可以知道當前的事件是什么階段,一般默認都是冒泡階段,很少用捕獲階段,冒泡階段從里向外,捕獲階段:從外向里

  • 1---->捕獲階段

  • 2---->目標階段

  • 3---->冒泡階段

    addEventListener方法的第三個參數是false的時候是冒泡階段
    addEventListener方法的第三個參數是true的時候是捕獲階段

<div id="dv1">
    <div id="dv2">
        <div id="dv3"></div>
    </div>
</div>

<script>
    //同時注冊點擊事件
    var objs = [document.getElementById("dv3"), document.getElementById("dv2"), document.getElementById("dv1")];
    //遍歷注冊事件
    objs.forEach(function (ele) {
        //為每個元素綁定事件
        ele.addEventListener("click", function (e) {
            console.log(this.id + "====>" + e.eventPhase);
        }, false);
    });
</script>

#參數false時點擊dv3
dv3====>2,dv2====>3,dv2====>3
#參數true時點擊dv3
dv1====>1,dv2====>1,dv2====>2

jQuery事件綁定

#不具備動態綁定功能,只有點擊原始按鈕才能生成
$("elem").bind('click',function (){ }) 
$("elem").unbind('click',function (){ }) 

#委托標簽<a>,為新添加的標簽綁定上事件
$("elem").delegate('a','click',function (){ })   
$("elem").undelegate('a','click',function (){ }) 

#底層on方式
$("#elem").on('click',function(){}) 
$("#elem").off('click',function(){}) 

綁定事件on方法是jquery最底層處理方式,也是官方推薦綁定事件的一個方法
基本用法:

*.on( events ,[ selector ] ,[ data ] )*

多個事件綁定同一個函數:

$("#elem").on("mouseover mouseout",function(){ });

多個事件綁定不同函數:

$("#elem").on({
    mouseover:function(){},  
    mouseout:function(){}
});

將數據傳遞到處理程序:

#通過第二參數(對象),當一個事件被觸發時,要傳遞給事件處理函數的
function greet( event ) {
 alert( "Hello " + event.data.name ); //Hello example
}

$( "button" ).on( "click", {
  name: "example"
}, greet );

針對自己處理機制中,不僅有on方法,還有根據on演變出來的live方法(1.7后廢棄),.delegate()方法等等。這些方法的底層實現部分還是on方法,這是利用了on的另一個事件機制委托的機制衍變而來的。
delegate()委托方法

$('#box').delegate('.button', 'click', function () {
$(this).clone().appendTo('#box');
});
$('#box').undelegate('.button','click');
//支持連綴調用方式
$('div').first().delegate('.button', 'click', function () {
$(this).clone().appendTo('div:first');
});

注意:.delegate()需要指定父元素,然后第一個參數是當前元素,第二個參數是事件方式,第三個參數是執行函數。和.bind()方法一樣,可以傳遞額外參數。.undelegate()和.unbind()方法一樣可以直接刪除所有事件,比如:.undelegate('click')。也可以刪除命名空間的事件,比如:.undelegate('click.abc')。
在DOM 中很多元素綁定相同事件時,或者DOM 中尚不存在即將生成的元素綁定事件時,我們推薦使用事件委托的綁定方式,否則推薦使用.bind()的普通綁定。

底層委托機制:

.on( events ,[ selector ] ,[ data ], handler(eventObject) )

第二參數中提供了一個selector選擇器,簡單的來描述下

<div class="left">
    <p class="aaron">
        <a>目標節點</a> //點擊在這個元素上
    </p>
</div>

$("div").on("click","p",fn)

事件綁定在最上層div元素上,當用戶觸發在a元素上,事件將往上冒泡,一直會冒泡在div元素上。如果提供了第二參數,那么事件在往上冒泡的過程中遇到了選擇器匹配的元素,將會觸發事件回調函數
卸載事件off()方法
根據on綁定事件的一些特性,off方法也可以通過相應的傳遞組合的事件名,名字空間,選擇器或處理函數來移除綁定在元素上指定的事件處理函數。當有多個過濾參數時,只有與這些參數完全匹配的事件處理函數才會被移除。
綁定2個事件:

$("elem").on("mousedown mouseup",fn)

刪除一個事件:

$("elem").off("mousedown")

刪除所有事件:

$("elem").off("mousedown mouseup")

快捷方式刪除所有事件,這里不需要傳遞事件名了,節點上綁定的所有事件講全部銷毀

$("elem").off()

目前綁定事件和解綁的方法有三組共六個。由於這三組的共存可能會造成一定的混亂,為此jQuery1.7 以后推出了.on()和.off()方法徹底摒棄前面三組。

//替代.bind()方式
$('.button').on('click', function () {
alert('替代.bind()');
});
//替代.bind()方式,並使用額外數據和事件對象
$('.button').on('click', {user : 'Lee'}, function (e) {
alert('替代.bind()' + e.data.user);
});
//替代.bind()方式,並綁定多個事件
$('.button').on('mouseover mouseout', function () {
alert('替代.bind()移入移出!');
});
//替代.bind()方式,以對象模式綁定多個事件
$('.button').on({
mouseover : function () {
alert('替代.bind()移入!');
},
mouseout : function () {
alert('替代.bind()移出!');
}
});
//替代.bind()方式,阻止默認行為並取消冒泡
$('form').on('submit', function () {
return false;
});
或
$('form').on('submit', false);
//替代.bind()方式,阻止默認行為
$('form').on('submit', function (e) {
e.preventDefault();
});
//替代.bind()方式,取消冒泡
$('form').on('submit', function (e) {
e.stopPropagation();
});
//替代.unbind()方式,移除事件
$('.button').off('click');
$('.button').off('click', fn);
$('.button').off('click.abc');
//替代.live()和.delegate(),事件委托
$('#box').on('click', '.button', function () {
$(this).clone().appendTo('#box');
});
//替代.die()和.undelegate(),取消事件委托
$('#box').off('click', '.button');

注意:和之前方式一樣,事件委托和取消事件委托也有各種搭配方式,比如額外數據、命名空間等等,這里不在贅述。
不管是.bind()還是.on(),綁定事件后都不是自動移除事件的,需要通過.unbind()和.off()來手工移除。
jQuery 提供了.one()方法,綁定元素執行完畢后自動移除事件,可以方法僅觸發一次的事件。

//類似於.bind()只觸發一次
$('.button').one('click', function () {
alert('one 僅觸發一次!');
});
//類似於.delegate()只觸發一次
$('#box).one('click', 'click', function () {
alert('one 僅觸發一次!');
});

參考:https://blog.csdn.net/tswc_byy/article/details/82824798


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM