事件归纳 | 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