jQuery中的事件
一、加载DOM
(一). 执行时机
$(document).ready()
方法和window.onload
方法具有相似的功能,但是在执行时机方面是右边区别的window.onload
方法是在网页中所有元素(包括所有元素的关联文件)完全加载到浏览器后才执行的,即JavaScript此时可以访问网页中的任何元素- jQuery中的
$(document).ready()
方法注册的事件处理程序,在DOM完全就绪时就可以调用。此时,网页的所有元素对jQuery而言都是可以访问的,但是,并不意味着这些元素的关联文件都已下载完毕 load()
方法会在元素的onload
事件中绑定一个处理函数。如果处理函数绑定给window
对象,则会在所有内容(包括窗口、框架、对象和图像等)加载完毕后触发,如果处理函数绑定在元素上,则会在元素内容加载完毕后触发
$(window).load(function (){
//编写代码
})
//等价于JavaScript中的以下代码
window.onload=function (){
//编写代码
}
(二). 多次使用
- JavaScript的
onload
事件一次只能保存对一个函数的引用,它会自动用后面的函数覆盖前面的函数,因此它不能在现有的行为上添加新的行为
function one(){
alert("one");
}
function two(){
alert("two");
}
window.onload=one;
window.onload=two;
//当运行代码后,发现只弹出字符串"two"对话框
//为了达到两个函数顺序触发的效果
window.onload=function(){
one();
two();
}
- 每次调用
$(document).ready()
方法都会在现有的行为上追加新的行为,这些行为函数会根据注册的顺序依次执行
function one(){
alert("one");
}
function two(){
alert("two");
}
$(document).ready(function(){
one();
})
$(document).ready(function(){
one();
})
(三). 简写方式
$(document).ready()
的简写方式
$(function(){
//编写代码
})
$(document)也可以简写为$()
。当$()
不带参数时,默认参数就是"document"
$().ready(function(){
//编写代码
})
二、事件绑定
(一).相关补充
- 在文档装载完成后,如果打算为元素绑定事件来完成某些操作,则可以使用
bind()
方法来对匹配元素进行特定事件的绑定 bind()
方法的调用格式为:bind(type[,data],fn)
- 第1个参数是事件类型,类型包括:
blur
、focus
、load
、resize
、scroll
、unload
、click
、dblclick
、mousedown
、mouseup
、mousemove
、mouseover
、mouseout
、mouseenter
、mouseleave
、change
、select
、submit
、keydown
、keypress
、keyup
和error
等,当然也可以是自定义名称 - 第2个参数为可选参数,作为
event.data
属性值传递给事件对象的额外数据对象 - 第3个参数则是用来绑定的处理函数
- jQuery中的事件绑定类型比普通的JavaScript事件绑定类型少了
"on"
(二). 基本效果
bind()
方法也可以多次调用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="./jquery-3.3.1.min.js" ></script>
<style>
.head{
border: solid 1px;
background: darkgray;
width: 300px;
}
.content{
border: solid 1px;
margin-top: -24px;
width: 300px;
display: none;
}
</style>
</head>
<body>
<div id="panel">
<h5 class="head">什么是JQuery?</h5>
<div class="content">
jQuery是继承Prototype之后又一个优秀的JavaScript库,它由一个有John Resig创建于2006年
1月的开源项目。jQuery凭借简介的语法和跨平台的兼容性,极大地简化了Javascript开发人员遍历HTML
文档、操作DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了Javascript程序员的
设计思路和编写程序的方式。
</div>
</div>
<script>
</script>
</body>
</html>
$(function(){
$("#panel .head").bind("click",function(){
$(this).next().show();
})
})
//this引用的是携带相应行为的DOM元素
(三). 加强效果
- 为了判断元素是否显示,可以使用jQuery中的
is()
方法来完成
$().ready(function(){
$("#panel h5.head").bind("click",function(){
var $content=$(this).next();
if($content.is(":visible")){
$content.hide();
}else{
$content.show();
}
});
});
- 当发现相同的选择器在代码里出现多次时,请用变量把它缓存起来
$().ready(function(){
$("#panel h5.head").bind("click",function(){
var $content=$(this).next();
if($content.is(":visible")){
$content.hide();
}else{
$content.show();
}
});
});
(四). 改变绑定事件的类型
$().ready(function(){
$("#panel h5.head").bind("mouseover",function(){
$(this).next().show();
}).bind("mouseout",function(){
$(this).next().hide();
})
})
//当光标滑过的时候,就触发事件
//光标滑过标题后,相应的内容将被显示;滑出标题后,相应的内容则被隐藏
(五). 简写绑定事件
- 像
click
、mouseover
和mouseout
这类事件,在程序中经常会使用到,jQuery也提供了简写方式 - 简写方式和
bind()
方法的使用类似,实现效果也相同,唯一的区别是能够减少代码量
$(function(){
$(".head").mouseover(function(){
$(this).next().show();
}).mouseout(function(){
$(this).next().hide();
})
})
三、合成事件
(一). hover()方法
- jQuery有两个合成事件——
hover()
方法和toggle()
方法,类似前面讲过的ready()
方法,hover()
方法和toggle()
都属于jQuery自定义的 方法 - hover()方法的语法结构为:
hover(enter,leave)
hover()
方法用于模拟光标悬停事件。当光标移动到元素上,会触发指定的第1个函数(enter
);当光标移出这个元素时,会触发指定的第2个函数(leave
)- CSS中有伪类选择器,例如:
"hover"
,当用户光标悬停在元素上,会改变元素的外观。在大多数符合规范的浏览器中,伪类选择符可以用于任何元素。然而在IE 6浏览器中,伪类选择器仅可以用于超链接元素。对于其他元素,可以使用jQuery的hover()
方法 - hover()方法准确来说是替代jQuery中
bind("mouseenter")
和bind("mouseleave")
,而不是替代bind("mouseover")
和bind("mouseout")
$(function(){
$(".head").hover(function(){
$(this).next().show();
},function(){
$(this).next().hide();
})
})
(二). toggle()方法
toggle()
的语法结构为:toggle(fn1,fn2,···,fnN)
toggle()
方法用于模拟鼠标连续单击事件。第一次单击元素,触发指定的第1个函数(fn1);当再次单击同一元素后,则触发指定的第2个函数(fn2);如果 有更多函数,则依次触发,直到最后一个。随后的每次单击都重复对这几个函数的轮番调用toggle()
1.8以上被淘汰
$(function(){
$(".head").toggle(function(){
$(this).next().show();
},function(){
$(this).next().hide();
})
})
(三). 再次加强效果
$().ready(function(){
$("#panel h5.head").bind("click",function(){
var $content=$(this).next();
if($content.is(":visible")){
$content.hide();
$(this).removeClass("highlight");
}else{
$content.show();
$(this).addClass("highlight");
}
});
});
四、事件冒泡
(一). 什么是事件冒泡
- 在页面上可以有多个事件,也可以多个人元素响应同一个事件
- 冒泡:事件会按照DOM的层次结构由里向外冒泡
$().ready(function(){
//为span元素绑定click事件
$("span").bind("click",function(){
var txt=$("#msg").html()+"<p>内层span元素被单击</p>";
$("#msg").html(txt);
});
//为div元素绑定click事件
$("#content").bind("click",function(){
var txt=$("#msg").html()+"<p>外层div元素被单击</p>";
$("#msg").html(txt);
});
//为body元素绑定click事件
$("body").bind("click",function(){
var txt=$("#msg").html()+"<p>body元素被单击</p>";
$("#msg").html(txt);
});
})
(二). 事件冒泡引发的问题
1. 事件对象
- 由于IE-DOM和标准DOM实现事件对象的方法各不相同,导致在不同浏览器中获取事件对象变得困难
- 针对这个问题,jQuery进行了必要的扩展和封装,从而使得在任何浏览器中都能很轻松地获取事件对象以及事件对象的一些属性
/*在程序中使用事件对象非常简单,只需要为函数添加一个参数*/
$("element").bind("click",function(event){ //event:事件对象
//···
})
/*当单机"element"元素时,事件对象就被创建了。这个事件对象只有事件处理函数才能访问到。事件处理函数执行完毕后,事件对象就被销毁*/
2. 停止事件冒泡
- 停止事件冒泡可以阻止事件中其他对象的事件处理函数被执行
- 在jQuery中提供了
stopPropagation()
方法来停止事件冒泡
$().ready(function(){
//为span元素绑定click事件
$("span").bind("click",function(event){
var txt=$("#msg").html()+"<p>内层span元素被单击</p>";
$("#msg").html(txt);
event.stopPropagation(); //停止事件冒泡。当单击<span>元素时,只会触发<span>元素上的click事件,而不会触发<div>元素和<body>元素的click事件
});
//为div元素绑定click事件
$("#content").bind("click",function(event){
var txt=$("#msg").html()+"<p>外层div元素被单击</p>";
$("#msg").html(txt);
event.stopPropagation(); //停止事件冒泡
});
//为body元素绑定click事件
$("body").bind("click",function(){
var txt=$("#msg").html()+"<p>body元素被单击</p>";
$("#msg").html(txt);
});
})
3. 阻止默认行为
- 网页中的元素有自己的默认行为,例如,单击超链接后会跳转、单击"提交"按钮后表单会提交,有时需要阻止元素的默认行为
- 在jQuery中,提供了
preventDefault()
方法来阻止元素的默认行为
<form action="test.html">
用户名:<input type="text" id="username" />
<input type="submit" value="提交" id="sub" />
</form>
<div id="msg"></div>
<script>
$().ready(function(){
$("#sub").bind("click",function(){
var username=$("#username").val();
if(username==""){
$("#msg").html("<p>文本框的值不能为空</p>");
event.preventDefault(); //阻止默认行为(表单提交)
}
});
})
</script>
- 如果想同时对事件对象停止冒泡和默认行为,可以在事件处理函数中返回
false
。这是对在事件对象上同时调用stopPrapagation()
方法和preventDefault()
方法的一种简写模式
4. 事件捕获
- 事件捕获和事件冒泡是刚好相反的两个过程,事件捕获是从最顶端往下开始触发
- 并非所有主流浏览器都支持事件捕获,并且这个缺陷无法通过JavaScript来修复
- jQuery不支持事件捕获
五、事件对象的属性
(一). event.type
- jQuery在遵循W3C规范的情况下,对事件处理对象的常用属性进行了封装,使得事件处理在各种浏览器下都可以正常运行而不需要进行浏览器类型判断
- 该方法的作用是可以获取到事件的类型
$(function(){
$("a").click(function(event){
alert(event.type); //获取事件类型
return false; //阻止连接跳转
})
})
(二). event.preventDefault()方法
- 该方法的作用是阻止默认事件的行为
preventDefault()
方法在IE浏览器中无效,jQuery对其进行了封装,使之能兼容各种浏览器
(三). event.stopPropagation()方法
- 该方法的作用是阻止事件的冒泡
stopPropagation()
方法在IE浏览器中无效,jQuery对其进行了封装,使之能兼容各种浏览器
(四). event.target
event.target
的作用是获取到触发事件的元素- jQuery对其封装后,避免了各个浏览器不同标准之前的差异
$(function(){
$("a[href='http://google.com']").click(function(event){
var tg=event.target; //获取事件对象
alert(tg);
return false; //阻止连接跳转
})
})
(五). event.relatedTarget
- 在标准DOM中,
mouseover
和mouseout
所发生的元素可以通过event.target来访问,相关元素是通过event.relatedTarget
来访问的 event.relatedTarget
在mouseover
中相当于IE浏览器的event.fromElement
,在mouseout
中相当于IE浏览器的event.toElement
,jQuery对其进行了封装,使之能兼容各种浏览器
(六). event.pageX和event.pageY
- 该方法的作用是获取光标相对于页面的x坐标和y坐标
- 如果没有使用jQuery时,那么IE浏览器中是用
event.x/event.y
,而Firefox浏览器中是用event.pageX/event.pageY
。如果页面上有滚动条,则还要加上滚动条的宽度或高度
$(function(){
$("a").click(function(event){
//获取鼠标当前相对于页面的坐标
alert("Current mouse position: "+event.pageX+", "+event.pageY);
return false; //阻止连接跳转
})
})
(七). event.which
- 该方法的作用是在鼠标单击事件中获取到鼠标的左、中、右键;在键盘事件中获取到键盘的按键
- 获得键盘的按键
$(function(){
$("a").mousedown(function(e){
alert(e.which); /*1=鼠标左键;2=鼠标中键;3=鼠标右键*/
})
})
$("input").keyup(function(e){
alert(e.which);
})
(八). event.metaKey
- 针对不同浏览器对键盘中
<ctrl>
按键解释不同,jQuery也进行了封装,并规定event.metaKey
为键盘事件中获取<ctrl>
按键
六、移除事件
<button id="btn">单击我</button>
<div id="test"></div>
<script>
$().ready(function(){
$("#btn").bind("click",function(){
$('#test').append('<p>我的绑定函数1</p>');
}).bind("click",function(){
$('#test').append('<p>我的绑定函数2</p>');
}).bind("click",function(){
$('#test').append('<p>我的绑定函数3</p>');
});
});
</script>
(一). 移除按钮元素上以前注册的事件
unbind()
方法的语法结构:unbind([type],[data]);
- 第1个参数是事件类型,第2个参数是将要移除的函数
- 如果没有参数免责删除所有绑定事件;如果提供了事件类型作为参数,则只删除该类型的绑定事件;如果把在绑定时传递的处理函数作为第2个参数,则只有这个特定的事件处理函数会被删除
<button id="delAll">删除所有事件</button>
$("#delAll").click(function(){
$('#btn').unbind();
});
(二). 移除<button>
元素的其中一个事件
$().ready(function(){
/*1. 首先需要为这些匿名处理函数指定一个变量 2. 然后就可以单独删除某一个事件了*/
$("#btn").bind("click",myFun1=function(){
$('#test').append('<p>我的绑定函数1</p>');
}).bind("click",myFun2=function(){
$('#test').append('<p>我的绑定函数2</p>');
}).bind("click",myFun3=function(){
$('#test').append('<p>我的绑定函数3</p>');
});
$("#delAll").click(function(){
$('#btn').unbind("click",myFun2); /*删除绑定函数2*/
});
});
(三). one()
- 另外,对于值需要触发一次,随后就要立即解除绑定的情况,jQuery提供了一种简写方法——
one()
方法 one()
方法可以为元素绑定处理函数。当处理函数触发一次后,立即被删除。即在每个对象上,事件处理函数只会被执行一次one()
方法的结构与bind()方法类似,使用方法也与bind()
方法相同,其语法结构如下:one(type[,data],fn)
$().ready(function(){
/*使用one()方法为<button>元素绑定单击事件后,只在用户第1次单击按钮时,处理函数才执行,之后的单击毫无作用*/
$("#btn").one("click",function(){
$('#test').append('<p>我的绑定函数1</p>');
}).one("click",function(){
$('#test').append('<p>我的绑定函数2</p>');
}).one("click",function(){
$('#test').append('<p>我的绑定函数3</p>');
});
});
七、模拟操作
(一). 常用模拟
- 在jQuery中,
trigger()
方法完成模拟操作 - 在用户进入页面后,就触发一些事件,而不需要用户主动去操作
$().ready(function(){
$("#btn").bind("click",function(){
$('#test').append('<p>我的绑定函数1</p>');
}).bind("click",function(){
$('#test').append('<p>我的绑定函数2</p>');
}).bind("click",function(){
$('#test').append('<p>我的绑定函数3</p>');
});
$("#btn").trigger("click");
});
//可以直接用简化写法click(),来达到同样的效果
$("#btn").click();
(二). 触发自定义事件
trigger()
方法不仅能触发浏览器支持的具有相同名称的事件,也可以触发自定义名称的事件
$().ready(function(){
$("#btn").bind("myClick",function(){
$("#test").append("<p>我的自定义事件.</p>")
});
$("#btn").trigger("myClick");
});
(三). 传递数据
trigger(type,[data])
方法有两个参数,第1个参数是要触发的事件类型,第2个参数是要传递给事件处理函数的附加数据,以数组形式传递- 通常可以通过传递一个参数给回调函数来区别这次事件是代码触发的还是用户触发的
$().ready(function(){
$("#btn").bind("myClick",function(event,message1,message2){
$("#test").append("<p>"+message1+message2+"</p>");
});
$("#btn").trigger("myClick",["我的自定义","事件"]);
});
(四). 执行默认操作
trigger()
方法触发事件后,会执行浏览器默认操作- jQuery中的
triggerHandler()
方法只触发绑定事件,同时取消浏览器对此事件的默认操作
$().ready(function(){
/*不仅会触发<input>元素绑定的focus事件,也会使<input>元素本身得到焦点(这是浏览器的默认操作)*/
$("input").trigger("focus");
});
$().ready(function(){
/*该方法会触发<input>元素上绑定的特定事件,同时取消浏览器对此事件的默认操作,即文本只触发绑定的focus事件,不会得到焦点*/
$("input").triggerHandler("focus");
});
八、其他用法
(一). 绑定多个事件
bind()
可以为元素一次性绑定多个事件类型
$().ready(function(){
$("div").bind("mouseover mouseout",function(){
$(this).toggleClass("over");
})
});
(二). 添加事件命名空间,便于管理
bind()
方法可以把元素的多个事件类型用命名空间规范起来
$().ready(function(){
$("div").bind("click.plugin",function(){
$("body").append("<p>click事件</p>");
}).bind("mouseover.plugin",function(){
$("body").append("<p>mouseover事件</p>");
}).bind("dblclick",function(){
$("body").append("<p>dblclick事件</p>");
});
/*在所绑定的事件类型后面添加命名空间,这样在删除事件时只需要指定命名空间即可。*/
/*单击<button>元素后,"plugin"的命名空间被删除,而不在"plugin"的命名空间的"dbclick"时间依然存在*/
$("button").click(function(){
$("div").unbind(".plugin");
});
});
(三). 相同事件名称,不同命名空间执行方法
- 可以为元素绑定相同的事件类型,然后以命名空间的不同按需调用
$().ready(function(){
$("div").bind("click",function(){
$("body").append("<p>click事件</p>");
}).bind("click.plugin",function(){
$("body").append("<p>click.plugin事件</p>");
});
$("button").click(function(){
$("div").trigger("click!"); //!失效
})
});
/*如果需要两者都被触发*/
$("div").trigger("click");
源于整理《锋利的 jQuery》