(补充)jQuery事件
.bind()
介绍:bind() 方法向被选元素添加一个或多个事件处理程序,以及当事件发生时运行的函数。
语法:.bind(eventType [,eventData],handler)
- eventType :string
包含一个或多个DOM事件类型或自定义事件名称的字符串。
$("p").bind("click ",function(){
alert("这个段落被点击了。");
});
注意:从jQuery 3.0开始,.bind()已弃用
.delegate()
介绍:为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)。
语法:.delegate( selector, eventType[, eventData], handler )
$( "table" ).delegate( "td", "click", function() {
$( this ).toggleClass( "chosen" );
});
// 等价于
$( "table" ).on( "click", "td", function() {
$( this ).toggleClass( "chosen" );
});
注意:从jQuery 3.0开始,.bind()已弃用
.on()
介绍:将一个或多个事件的事件处理程序功能附加到所选元素。
语法:
.on( events [, selector ] [, data ], handler )
- events :
string
一种或多种以空格分隔的事件类型和可选的命名空间,例如“ click”或“ keydown.myPlugin”。 - selector :
string
一个选择器字符串,用于过滤触发事件的所选元素的后代。如果选择器被省略或为null,则事件在到达所选元素时始终被触发。 - data :
any
触发事件时通过event.data
传递给处理程序的数据 - handler:
Function
触发事件时执行的功能。该值false
也可以用作简单函数的简写形式return false
。
- events :
$( "#dataTable tbody" ).on( "click", function() {
console.log( $( this ).text() );
});
2..on( events [, selector ] [, data ] )
- events :
Object
一个对象,其中的字符串键表示一个或多个用空格分隔的事件类型和可选的名称空间,并且值表示要为事件调用的处理函数。 - selector :
string
一个选择器字符串,用于过滤触发事件的所选元素的后代。如果选择器被省略或为null,则事件在到达所选元素时始终被触发。 - data :
any
触发事件时通过event.data
传递给处理程序的数据
$( "div.test" ).on({
click: function() {
$( this ).toggleClass( "active" );
},
mouseenter: function() {
$( this ).addClass( "inside" );
},
mouseleave: function() {
$( this ).removeClass( "inside" );
}
})
注意:自 jQuery 版本 1.7 起,on() 方法是 bind()、live() 和 delegate() 方法的新的替代品。该方法给 API 带来很多便利,我们推荐使用该方法,它简化了 jQuery 代码库。
.trigger()
介绍:方法触发被选元素上指定的事件以及事件的默认行为
语法:.trigger(eventType [,extraParameters])
- eventType: string
包含JavaScript事件类型的字符串,例如click或submit。
- extraParameters:Array
传递给事件处理程序的其他参数。
$( "#foo" ).on( "click", function() {
alert( $( this ).text() );
});
$( "#foo" ).trigger( "click" );
$( "#foo" ).on( "custom", function( event, param1, param2 ) {
alert( param1 + "\n" + param2 );
});
$( "#foo").trigger( "custom", [ "Custom", "Event" ] );
「课堂练习」
实现点击按钮触发其他按钮
要求:
- 两个按钮
#1
和#2
实现点击#2
的同时触发按钮#1
- 创建两个div元素分别显示两个按钮被点击的次数
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YW83SjHj-1629508134066)(./trigger练习.gif)]
.off()
介绍:.off()方法将删除.on()方法附加到元素上的事件处理程序。
语法:
.off( events [, selector ] [, handler ] )
可以通过在handler参数中指定函数名称来删除处理程序。当jQuery添加事件处理程序时,它将为处理程序函数分配一个唯一的ID。注意:.off可能会删除比预期数量更多的处理程序。在这种情况下,最好使用命名空间添加和删除事件处理程序。
var foo = function() {
// 处理某种事件的代码
};
// ... 当段落被点击时foo会被调用 ...
$( "body" ).on( "click", "p", foo );
// ... foo将不再被调用。
$( "body" ).off( "click", "p", foo );
-
.off( events [, selector ] )
提供 selector 参数可以删除特定的委托事件处理程序。注意:选择器字符串必须与.on()附加事件处理程序时传递的字符串完全匹配。要从元素中删除所有委托事件而又不删除未委托事件,请使用特殊值
"**"
。
// 从所有段落中删除所有委托的单击处理程序
$( "p" ).off( "click", "**" );
-
.off( event )
删除jQuery集合的元素中所有这种类型的事件(包括直接和委派)。注意:在编写jq插件的代码时,或者只是在使用大型代码库时,最好的方法是使用命名空间添加和删除事件,以使该代码不会无意中删除其他代码添加的事件处理程序
// 从所有段落中删除单击处理程序
$( "p" ).off( "click");
.off()
不带参数的调用将删除所有附加到元素的处理程序。
$( "p" ).off();
例子:
var validate = function() {
// 处理某种事件的代码
};
// 委托事件在".validator"命名空间
$( "form" ).on( "click.validator", "button", validate );
$( "form" ).on( "keypress.validator", "input[type='text']", validate );
// 移除在 ".validator"命名空间的事件处理程序
$( "form" ).off( ".validator" );
「课堂练习」
实现给按钮添加和删除事件绑定
要求:
- 创建三个按钮
- 第一个按钮会根据自身是否绑定点击事件显示对应UI:绑定显示
Can Click
未绑定时显示Does noting
- 在绑定click事件时点击按钮,实现页面元素闪烁效果
- 第二个按钮点击给第一个按钮添加点击事件
- 第三个按钮点击删除第一个按钮点击事件
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tshtlcz3-1629508134068)(./off练习.gif)]
事件名称和命名空间
概念:任何事件名称都可以用于events参数。当浏览器生成用户操作(如单击)导致的事件时调用handler函数时,jQuery将传递浏览器的标准JavaScript事件类型。此外.trigger()
方法可以同时触发标准的浏览器事件名和自定义事件名来调用附加的处理程序。
语法:事件名称应该只包含字母数字、下划线和冒号字符。
$( "p" ).on( "myCustomEvent", function( event, myName ) {
$( this ).text( myName + ", hi there!" );
$( "span" )
.stop()
.css( "opacity", 1 )
.text( "myName = " + myName )
.fadeIn( 30 )
.fadeOut( 1000 );
});
$( "button" ).click(function () {
$( "p" ).trigger( "myCustomEvent", [ "John" ] );
});
命名空间
概念:事件名称可以由事件命名空间
限定,该命名空间简化了删除或触发事件的过程。例如,"click.myPlugin.simple"为这个特定的click事件定义myPlugin和simple的命名空间。
通过该字符串连接的Click事件处理程序可以用.off("click.myPlugin ")
或.off("click.simple")
删除,而不会干扰绑定到元素上的其他click处理程序。命名空间类似于CSS类,因为它们没有层次结构;只需要匹配一个名字。
语法:命名空间只能包含大小写字母和数字。
$('.datalist')
.on('click.checked','tr',function(){
$(this).find('input').prop('checked',!$(this).find('input').prop('checked'))
}).on('click.selected','tr',function(){
$(this).toggleClass('selected')
})
在.on()的第二种形式中,events参数是一个普通对象。键是与events参数相同形式的字符串,具有空格分隔的事件类型名称和可选名称空间。每个键的值都是一个函数(或false值),它被用作处理程序,而不是方法的最终参数。在其他方面,这两种形式的行为是相同的,如下所述。
jQuery重要概念
链式编程
介绍:链式编程是为了节省代码量,看起来更优雅。实际上链式操作仅仅是通过对象上的方法最后
return this
,通常情况下,只有设置操作才能把链式编程延续下去。因为获取操作的时候,会返回获取到的相应的值,无法返回 this。
隐式迭代
概念:遍历内部 DOM 元素(伪数组形式存储)的过程就叫做隐式迭代。 简单理解:给匹配到的所有元素进行循环遍历,执行相应的方法,而不用我们再 进行循环,简化我们的操作,方便我们调用。
插件
概念:插件(Plugin)也称为jQuery的扩展。以jQuery核心代码为基础编写的符合一定规范的应用程序。通过js文件的方式引用。
介绍:jQuery插件大致可以分为:UI类、表单及验证类、输入类、特效类、Ajax类、滑动类、图形图像类、导航类、综合工具类、动画类等等
常用插件:
-
jqueryUI 官方插件,功能多且全面,官网:www.jqueryui.com
-
jquery.validation 表单验证插件,官网:https://jqueryvalidation.org/
-
jquery.easyUI 是一组基于jQuery的UI插件集合,官网:http://www.jeasyui.net/
-
bootstrap 是最受欢迎的 HTML、CSS 和 JS 框架,用于开发响应式布局、移动设备优先的 WEB 项目,官网:https://www.bootcss.com/
插件的使用
步骤:
- 引入jquery.js文件,必须在所有插件之前引入
- 引入插件
- 引入插件相关文件,比如样式、语言包等
jQuery.validation
介绍:jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求。该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证,同时提供了一个用来编写用户自定义方法的 API。所有的捆绑方法默认使用英语作为错误信息,且已翻译成其他 37 种语言。
使用:
- 引入插件
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/lib/jquery.js"></script>
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/dist/jquery.validate.min.js"></script>
jQuery Validate 插件提供了本地化信息文件,位于下载包的
dist/localization/messages_zh.js
- 引入本地化信息文件(可选)
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/dist/localization/messages_zh.js"></script>
- 使用
- 将校验规则写到控件中
<script>
$.validator.setDefaults({
submitHandler: function() {
alert("提交事件!");
}
});
$().ready(function() {
$("#commentForm").validate();
});
</script>
<form class="cmxform" id="commentForm" method="get" action="">
<fieldset>
<legend>输入您的名字,邮箱,URL,备注。</legend>
<p>
<label for="cname">Name (必需, 最小两个字母)</label>
<input id="cname" name="name" minlength="2" type="text" required>
</p>
<p>
<label for="cemail">E-Mail (必需)</label>
<input id="cemail" type="email" name="email" required>
</p>
<p>
<label for="curl">URL (可选)</label>
<input id="curl" type="url" name="url">
</p>
<p>
<label for="ccomment">备注 (必需)</label>
<textarea id="ccomment" name="comment" required></textarea>
</p>
<p>
<input class="submit" type="submit" value="Submit">
</p>
</fieldset>
</form>
- 将校验规则写到 js 代码中
<script>
$().ready(function() {
// 在键盘按下并释放及提交后验证提交表单
$("#signupForm").validate({
rules: {
firstname: "required",
lastname: "required",
username: {
required: true,
minlength: 2
},
password: {
required: true,
minlength: 5
},
confirm_password: {
required: true,
minlength: 5,
equalTo: "#password"
},
email: {
required: true,
email: true
},
topic: {
required: "#newsletter:checked",
minlength: 2
},
agree: "required"
},
// messages 处,如果某个控件没有 message,将调用默认的信息
messages: {
firstname: "请输入您的名字",
lastname: "请输入您的姓氏",
username: {
required: "请输入用户名",
minlength: "用户名必需由两个字符组成"
},
password: {
required: "请输入密码",
minlength: "密码长度不能小于 5 个字符"
},
confirm_password: {
required: "请输入密码",
minlength: "密码长度不能小于 5 个字符",
equalTo: "两次密码输入不一致"
},
email: "请输入一个正确的邮箱",
agree: "请接受我们的声明",
topic: "请选择两个主题"
}
})
});
</script>
<form class="cmxform" id="signupForm" method="get" action="">
<fieldset>
<legend>验证完整的表单</legend>
<p>
<label for="firstname">名字</label>
<input id="firstname" name="firstname" type="text">
</p>
<p>
<label for="lastname">姓氏</label>
<input id="lastname" name="lastname" type="text">
</p>
<p>
<label for="username">用户名</label>
<input id="username" name="username" type="text">
</p>
<p>
<label for="password">密码</label>
<input id="password" name="password" type="password">
</p>
<p>
<label for="confirm_password">验证密码</label>
<input id="confirm_password" name="confirm_password" type="password">
</p>
<p>
<label for="email">Email</label>
<input id="email" name="email" type="email">
</p>
<p>
<label for="agree">请同意我们的声明</label>
<input type="checkbox" class="checkbox" id="agree" name="agree">
</p>
<p>
<label for="newsletter">我乐意接收新信息</label>
<input type="checkbox" class="checkbox" id="newsletter" name="newsletter">
</p>
<fieldset id="newsletter_topics">
<legend>主题 (至少选择两个) - 注意:如果没有勾选“我乐意接收新信息”以下选项会隐藏,但我们这里作为演示让它可见</legend>
<label for="topic_marketflash">
<input type="checkbox" id="topic_marketflash" value="marketflash" name="topic">Marketflash
</label>
<label for="topic_fuzz">
<input type="checkbox" id="topic_fuzz" value="fuzz" name="topic">Latest fuzz
</label>
<label for="topic_digester">
<input type="checkbox" id="topic_digester" value="digester" name="topic">Mailing list digester
</label>
<label for="topic" class="error">Please select at least two topics you'd like to receive.</label>
</fieldset>
<p>
<input class="submit" type="submit" value="提交">
</p>
</fieldset>
</form>
编写jquery插件
介绍:插件形式分为3类:
- 封装对象方法插件
- 封装全局函数插件,如 . e a c h , .each, .each,.map,$.makeArray…
- 选择器插件(类似于.find())
自定义插件的规范
目的:降低各种插件之间的冲突,减少错误机率
- 命名规范:jquery.插件名.js
- 把你的代码全部放在闭包里面
(function($) {
//这里写插件代码
})(jQuery);
- 插件中的this应该指向jQuery实例
- 使用this.each()迭代元素
- 插件内部必须返回jQuery实例(this),便于链式调用
- 所有的对象法附加在jquery.fn对象(jquery.prototype)上面,所有全局函数附加在jquery上
- 所有的方法或插件必须用分号结尾,避免出问题
- 避免插件内部使用 , 如 果 要 使 用 , 请 传 递 j Q u e r y ( ,如果要使用,请传递jQuery( ,如果要使用,请传递jQuery(并不是总等于jQuery,另外其他js框架也可能使用$)
开发方法
介绍:jQuery插件开发方式主要有三种:
- 通过$.extend()来扩展jQuery,
- 通过$.fn 向jQuery添加新的方法
- 通过$.widget()应用jQuery UI的部件工厂方式创建
第三种方法过于复杂,我们不在本课程中学习
$.extend()
介绍:将两个或更多对象的内容合并到第一个对象中。
语法:
$.extend([deep],target,obj1 [,objN])
- deep:
boolean
是否深拷贝 - target:
Object
要扩展的对象。它将接收新的属性 - obj1-objN对:
Object
象来扩展target对象
$.extend(object)
将参数对象合并到jQuery命名空间。
例子:实现一个简单的jQuery插件
(function($) {
$.extend({
sayHello: function(name) {
console.log('Hello,' + (name ? name : 'Tom') + '!');
}
})
})(jQuery);
$.sayHello(); //调用
$.sayHello('Wayou'); //带参调用
上面的例子通过 . e x t e n d ( ) 向 j Q u e r y 添 加 了 一 个 s a y H e l l o 函 数 , 然 后 通 过 .extend()向jQuery添加了一个sayHello函数,然后通过 .extend()向jQuery添加了一个sayHello函数,然后通过直接调用。这种模式开发的插件无法利用jQuery的选择器,要处理DOM元素以及将插件更好地运用于所选择的元素身上,需要使用第二种开发方式。我们常见的插件大多是通过此种方式开发。
$.fn
介绍:使用
.
f
n
开
发
插
件
就
是
往
.fn开发插件就是往
.fn开发插件就是往.fn上面添加一个方法,命名为的插件名称。并将插件代码写入在这个方法内部。
语法:
(function($) {
$.fn.setOpacity = function(num) {
//在这里面,this指的是用jQuery选中的jQuery元素
if(num >=0 && num <= 1) {
this.css('opacity', num);
}
// 为了保证插件支持链式操作一定要return this
return this
}
})(jQuery);
注意:如果需要在插件代码里处理每个具体的元素,而不是对一个集合进行处理,需要使用.each()方法进行迭代操作,并且要注意在each方法内部,this指带的是普通的DOM元素了,如果需要调用jQuery的方法那就需要用$来重新包装一下。
例子:
(function($) {
$.fn.setOpacity = function(num) {
this.each(function() {
//对每个元素进行操作
$(this).append(' ' + $(this).attr('class'));
}))
// 为了保证插件支持链式操作一定要return this
return this
}
})(jQuery);
插件的参数:一个强劲的插件是可以让使用者随意定制的,这要求我们提供在编写插件时就要考虑得全面些,尽量提供合适的参数。另一方面,为了灵活,使用者可以不传递参数,插件里面会给出参数的默认值。
(function($) {
$.fn.myPlugin = function(options) {
var defaults = {
color: 'red',
fontSize: '12px',
opacity: 0.8
};
// 若用户没有传递某项配置值,使用默认值
var settings = $.extend({},defaults, options);
// 支持链式操作
return this.css({
color: settings.color,
fontSize: settings.fontSize,
opacity: settings.opacity
});
}
})(jQuery);
注意:在插件开发中我们应该保护好默认参数,让插件应有的东西应该维持原样,保证后续代码仍可以正常使用,所以在使用$.extend()的时将一个新空对象作为第一个参数,拿到合并对象的同时保护了默认配置对象。
面向对象的插件开发
介绍:使用面向对象的方式开发插件可以使得代码更清晰并方便维护。
例子:将上述myPlugin使用面向对象的形式开发
//定义Beautifier的构造函数
var Beautifier = function(ele, opt) {
this.$element = ele,
this.defaults = {
color: 'red',
fontSize: '12px',
opacity: 0.8
},
this.options = $.extend({}, this.defaults, opt)
}
//定义Beautifier的方法
Beautifier.prototype = {
beautify: function() {
return this.$element.css({
color: this.options.color,
fontSize: this.options.fontSize,
opacity: this.options.opacity
});
}
}
//在插件中使用Beautifier对象
$.fn.myPlugin = function(options) {
//创建Beautifier的实体
var beautifier = new Beautifier(this, options);
//调用其方法
return beautifier.beautify();
}
使用面向对象形式开发后,代码更易维护和理解,以后要加新功能新方法,只需向对象添加新变量及方法,并在插件里实例化后即可调用新添加的功能方法。
使用事件命名空间
概念:在jQuery插件的开发,我们在给任何DOM元素绑定事件时时都应该注意的一点是给事件绑定命名空间。因为插件库可以认为是三方库,开发者使用的插件库同时,开发者自己同样可能会给元素绑定事件,若插件库包含解绑自身事件功能而没有使用命名空间是,会解绑掉开发人员或其他插件库中的事件别人写的代码产生冲突。
所以在插件开发中绑定事件始终需要给事件添加命名空间