您的位置:首页 > Web前端 > JQuery

jQuery 自定义事件以及命名空间

2017-10-21 14:15 267 查看
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<script type="text/javascript" src=""></script>
<title>Document</title>
<style type="text/css">
.main {
width: 200px;
height: 200px;
border: 1px solid red;
background: green;
}

.add {
background: red;
}
</style>
<script type="text/javascript">
$(function() {
$(".clk").on('haha', function() {
$(".main").toggleClass('add');
});
setInterval(function() {
$(".clk").trigger('haha');
},1000);
})
</script>
</head>

<body>
<div class="main"></div>
<button class="clk">click</button>
</body>

</html>


事件是 Web 应用中不可或缺的一个东西,用户在应用中执行一个操作的时候,比如鼠标单击时要触发执行一些事情,就可以给该事件绑定一个事件处理程序(event handler)。使用 jQuery 的
.on()
方法可以为选中的元素绑定任意的 DOM 事件,并添加事件处理程序。假设有如下 HTML 结构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<button id="example" type="button">Click me!</button>
<script src="http://code.jquery.com/jquery-1.11.2.js"></script>
<script>
// code here
</script>
</body>
</html>


<script>
元素内添加如下代码,其中,事件名称是
.on()
方法的第一个参数,事件处理程序的回调函数作为第二个参数:
$('#example').on('click', function(e) {
alert('Clicked!');
});


这样当该按钮元素触发鼠标单击(click)事件的时候就会执行绑定的事件处理程序,弹出一个对话框!回调函数的第一个参数
e
为事件对象,通过该对象可以得到很多事件相关的信息,比如事件类型,事件发生的坐标点等以及一些事件方法。回调函数除了可以像这样使用一个匿名函数,也可以使用一个变量标识的函数引用:
$('#example').on('click', clickHandler);


同时绑定多个事件

另外,jQuery 还支持使用空格分隔多个事件名称来同时绑定多个事件,比如
mouseenter mouseleave
,同时给元素绑定鼠标移入和鼠标移出事件。可以通过事件对象的
type
属性来判断发生的是哪个事件:
$('#example').on('mouseenter mouseleave', function(e) {
if (e.type === 'mouseenter') {
// mouseenter
} else {
// mouseleave
}
});


除了上面这种方法外,还可以传入一个键值对来绑定多个事件:
$('#example').on({
mouseleave: function() {
// mouseleave
},
mouseenter: function() {
// mouseenter
}
});


事件上下文

同时给多个元素绑定事件处理程序的时候可以使用事件执行的上下文来简化代码:
$('li').on('click', function() {
var $this = $(this);
$this.addClass('active');
});


上下文关键字
this
引用的是原生 DOM 元素,所以如果要使用 jQuery 的方法需要先包装成 jQuery 对象。

事件委托

事件会经过一个捕捉和冒泡的过程,为了兼容,jQuery 只使用了事件的冒泡,即目标元素触发事件后会逐级冒泡直到顶级元素节点。利用事件的冒泡可以将目标元素的事件处理程序绑定到其祖先元素上统一处理,可以给
.on()
方法传入一个可选的选择器字符串作为第二个参数:
$(document).on('click', '#example', clickHandler);


此时表示将
id="example"
的元素的鼠标单击事件委托绑定到了
document
元素上,当目标元素(即
id="example"
的元素)触发鼠标单击事件的时候,该事件就会冒泡到
document
元素上,从而触发事件处理程序。使用事件委托的好处是如果页面上有很多列表,每个列表都去绑定一个鼠标单击事件,那么就会有很多事件处理程序,会对性能造成影响。利用事件冒泡的原则,将事件处理程序绑定到目标元素的父元素或者祖先元素上,可以明显地减少事件处理程序的数量,改善性能:
$('ul').on('click', 'li', clickHandler);


使用事件委托另外一个好处是那些动态添加的
<li>
元素也会具有事件处理程序。个人比较侵向于将事件都委托到
document
元素上方便管理,而且也不用等到
DOM 准备就绪:
$(document)
.on('click', 'selector-1', clickHandler)
.on('focusin', 'selector-2', focusHandler);


在 IE8 中一些事件比如
submit
或者
change
是不会冒泡的,但是 jQuery 对此做了处理,因此也可以放心使用。像
focus
blur
事件则推荐使用相应的
focusin
focusout
事件来代替。对于
mouseover
mouseout
事件,为了避免事件冒泡造成的不良影响,推荐使用
mouseenter
mouseleave
来代替。

阻止事件冒泡与默认行为

调用事件对象的
.stopPropagation()
方法可以阻止事件冒泡:
$('#example').on('click', function(e) {
e.stopPropagation();
});


这样当单击事件在该元素上发生的时候就不会冒泡了。jQuery 还有另外一个方法
.stopImmediatePropagation()
调用后事件冒泡被阻止同时该元素上后面绑定的事件处理程序也不会执行了:
$('#example').on('click', function() {
alert('Clicked-1!'); // 会执行
}).on('click', function(e) {
e.stopImmediatePropagation();
}).on('click', function() {
alert('Clicked-2!'); // 不会执行
});


调用事件对象的
.preventDefault()
方法可以阻止事件的默认行为:
$('#example').on('click', function(e) {
e.preventDefault();
});


在事件处理程序中直接返回
false
可以同时取消冒泡和阻止默认行为:
$('#example').on('click', function() {
return false;
});


相当于同时调用了事件对象上面的
.stopPropagation()
.preventDefault()
方法。如果没有其它操作,还可以进一步简写为
$('#example').on('click',
false);


应用示例,点击按钮显示弹出层,点击文档其它地方隐藏:
$(document)
.on('click', '#example', popup.show)
.on('click', popup.hide);


由于事件冒泡,所以该弹出层并不会显示出来,需要在事件处理程序中阻止事件冒泡:
$(document)
.on('click', '#example', function(e) {
e.stopPropagation();
popup.show();
}).on('click', popup.hide);


获取原生事件对象

事件处理程序中引用的事件对象实际上是经过 jQuery 包装过的,有时候需要使用浏览器原生的事件对象,要得到浏览器原生的事件对象可以通过事件对象的 originalEvent 属性获取。例如,使用拖拽事件的时候就会用到原生的事件对象:
$('#example').on('dragstart', function(e) {
var originalEvent = e.originalEvent;
originalEvent.dataTransfer.effectAllowed = 'move';
originalEvent.dataTransfer.setData('text/plain', $(this).text());
originalEvent.dataTransfer.setData('text/html', $(this).html());
originalEvent.dataTransfer.setDragImage('/images/drag.png', -10, -10);
});


传递数据

可以给事件处理程序传入数据,该数据保存在事件对象的 data 属性中:
$('#example').on('click', 1, function(e) {
console.log(e.data); // 1
});


为了区别事件代理,传递的数据貌似不能是一个直接的字符串,不过可以传入一个对象来代替:
$('#example').on('click', {str: 'xxx'}, function(e) {
console.log(e.data.str); // xxx
});


自定义事件

除了浏览器的标准事件,还可以绑定自定义事件的事件处理程序,其中事件名可以使用任意命名:
$('#example').on('sleep', function() {
alert('Sleeping!');
});


标准事件的事件处理程序可以通过浏览器原生事件去触发,而自定义事件的事件处理程序则可以使用 jQuery 的
.trigger()
方法触发,使用方式如下,传入需要触发的事件名称作为参数:
$('#example').trigger('sleep');


可以通过给
trigger()
方法传入更多参数来给事件处理程序传递数据,数据会作为回调函数的参数进行传递:
$('#example').on('sleep', function(e, time) {
alert('Sleep at' + time);
});

$('#example').trigger('sleep', '22:00');


应用示例,使用自定义事件编写异步代码:
$('#example').on('done', doHandler);

function foo() {
setTimeout(function() {
// foo 函数的逻辑比较耗时,所以使用 setTimeout 函数排队
$('#example').trigger('done'); // 执行完了,通知一声
}, 1000);
}


foo 函数执行完成后,就会触发元素的
done
事件,前面绑定的 doHandler 函数就会开始执行。

事件命名空间

无论是浏览器标准事件或是自定义事件都可以添加命名空间,添加在事件名称后面,通过一个
.
号分隔,像这样
click.widget
,也可以给一个事件添加多个命名空间
click.widget.common
,使用命名空间可以更有针对性地触发或者移除某个特定的事件处理程序。比如一个元素同时绑定了
click.tab
click.collapse
两个点击事件,当使用
.trigger()
方法触发
click.collapse
事件时会执行该事件的事件处理程序,而
click.tab
的事件处理程序则不会执行。

移除绑定事件

使用
.off()
方法可以移除绑定的事件处理程序,有下面几种情况:

不指定任何参数,移除该元素上绑定的所有事件处理程序。

指定事件名,如
.off('click')
表示移除该元素上绑定的所有单击事件处理程序。

指定事件处理程序,如
.off('click', clickHandler)
表示仅移除该事件处理程序(是的,匿名函数不能这样移除)。

指定事件命名空间,如
.off('.widget')
表示移除该命名空间下所有的事件处理程序(比如绑定的
click.widget
change.widget
事件处理程序都会被移除),该方式可以用于移除某个组件绑定的各种事件。

指定事件代理的元素,如
$(document).off('click', '#example')
,可以移除为该元素绑定的事件代理处理程序。

一次性事件

使用
.one()
方法绑定的事件处理程序只会触发执行一次,一次后自动移除:
$('#example').one('click', clickHandler);


事件节流

浏览器中有几个事件会频繁触发,比如 scroll, resize, mousemove 等,那么给这些事件绑定的事件处理程序也会跟着频繁地执行,导致页面反应迟钝,要解决这个问题,需要节流事件,减少事件处理程序执行的频率:
var timer = 0; // 使用一个定时器
$(window).on('scroll', function() {
if (!timer) {
timer = setTimeout(function() {
// Do something
timer = 0;
}, 200);
}
});



前言

在jquery的官方API中,有对命名空间的一些描述,地址是:http://api.jquery.com/on/ 这里面有一些英文介绍,题目是“Event
names and namespaces”下面有一些介绍。 假如一些朋友不是很理解的话,我在这里简单的介绍一下!


jQuery事件命名空间

我们先看一些代码:
$(“#haorooms”).on("click.a",function(){});
$(“#haorooms”).on("click.a.bb",function(){});
$(“#haorooms”).on("dbclick.a",function(){});
$(“#haorooms”).on("mouseover.a",function(){});
$(“#haorooms”).on("mouseout.a",function(){});


当然,我们也可以用bind进行事件绑定。我们看到上面的代码,我们可以在事件后面,以点号,加我们的名字,就是事件命名空间。所谓事件命名空间,就是事件类型后面以点语法附加一个别名,以便引用事件,如”click.a”,其中”a”就是click当前事件类型的别名,即事件命名空间。

假如我们要删除如下命名空间:
$(“#haorooms”).on("click.a.bb",function(){});


我们可以用:
$(“#haorooms”).off("click.a.bb");//直接删除bb命名空间 【推荐】
$(“#haorooms”).off(".bb"); //直接删除bb命名空间 【推荐】
$(“#haorooms”).off(".a"); //删除.a命名空间下面所有的子空间【包括.a.bb   .a.cc等等,.a是.bb的父级,因此.a下面的都会删掉】
$(“#haorooms”).off("click");//直接解绑click,下面的命名空间都会删除。


要注意的是:

假如我们写了如下代码:
$(“#haorooms”).on("click",function(){});
$(“#haorooms”).on("click.a",function(){});
$(“#haorooms”).on("click.a.bb",function(){});


那么我们要用trigger触发click事件,也就是触发第一个,岂不是把click.a和click.a.bb都触发了,那如何解决这个问题呢,我只想触发click,而不触发click.a及以下的命名空间?

没关系! 有如下解决办法:

如果事件类型后面附加感叹号,则表示触发不包含命名空间的特定事件类型。

假如我们只想触发click,可以这么写:
$(“#haorooms”).trigger("click!")


只触发bb,可以这么写:
$(“#haorooms”).trigger("click.a.bb");


有了命名空间,可以方便我们在同一个事件上面做管理啦!!!


自定义事件

我在这里就不多描述了!所有自定义事件都可以通过jQuery方法触发,例如下面的示例自定一个Delay事件类型,并把它绑定到input元素对象上,然后在按钮单击事件中触发自定义事件。
$("input").bind("delay",function(event){
setTimeout(function(){
alert(event.type);
},1000);
});
$("input").click(function(){
$("input").trigger("delay"); //触发自定义事件
});


自定义事件不是真正意义上的事件,可以把它理解为自定义函数,触发自定义事件就相当于调用自定义函数。

通过上面的介绍,不知道大家对jquery的事件名称和命名空间有没有更深的了解了呢!期待您留言交流!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: