jQuery中的事件
加载DOM
以浏览器装在文档为例,在页面加载完毕后,浏览器会通过JavaScript为DOM元素添加事件。在常规的JavaScript代码中,通常使用window.onload方法,而在jQuery中,使用的是$(document).ready()方法。$(document).ready()是事件模块中最重要的一个函数,可以极大地提高Web应用程序的响应速度。jQuery就是用$(document).ready()方法来代替传统JavaScript的window.onload方法的。通过使用该方法,可以在DOM载入就绪时就对其进行操纵并调用执行它所绑定的函数。
$(document).ready()与window.onload区别
(1)执行时机
window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行,JavaScript此时才可以访问网页中的任何元素。而通过jQuery中的$(document).ready()方法注册的事件处理程序,在DOM完全就绪时就可以被调用。此时,网页的所有元素对jQuery而言都是可以访问的,但是,这不是意味着这些元素关联的文件都已经下载完毕。
假设有一个网站,与图片有关的HTML下载完毕,并且已经解析为DOM树了,但很有可能图片还未加载完毕,所以例如图片的高度和宽度这样的属性此时不一定有效。为了解决这个问题,可以使用jQuery中另一个关于页面加载的方法——load()方法。load()方法会在元素的onload事件中绑定一个处理函数。如果处理函数绑定给window对象,则会在所有内容(包括窗口、框架、对象和图像等)加载完毕后触发。
$(window).load(function(){ //编写代码 })
等价于JavaScript中的代码:
window.onload = function(){ //编写代码 }
(2)多次使用
假设网页中有两个函数:
function one(){ alert("one"); } function two(){ alert("two"); }
当网页加载完毕后,通过JavaScript代码来分别调用one函数和two函数:
window.onload = one;
window.onload = two;
运行后只弹出字符串“two”对话框,字符串“one”不能弹出的原因是JavaScript的onload事件一次只能保存对一个函数的引用,它会自动用后面的函数覆盖前面的函数,因此不能在现有的行为上添加新的行为。
为了达到两个函数顺序触发的效果,只能在创建一个新的JavaScript方法来实现。
window.onload = function(){ one(); two(); }
虽然这样编写的代码能解决某些问题,但是不能满足某些需求,例如有多个JavaScript文件,每个文件都需要用到window.onload方法,这种情况下用上面提到的方法编写代码会非常麻烦。而jQuery的$(document).ready()方法能够很好地处理这些情况,每次调用$(document).ready()方法都会在现有的行为上追加新的行为,这些行为函数会根据注册的顺序一次执行。
$(document).ready(function(){ one(); }) $(document).ready(function(){ two(); })
(3)简写方式
$(document).ready(function(){ //编写代码 }) 可以写成: $(function(){ //编写代码 }) 也可以写成: $().ready(function(){ //编写代码 })
事件绑定
在文档装载完成后,如果打算为元素绑定事件来完成某些操作,则可以使用bind()方法来对匹配元素进行特定事件的绑定,bind()方法的格式为:
bind(type[,data],function)
bind()方法有3个参数:
♦ 第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个参数用来绑定的处理函数。
代码示例:
$(function(){ $("p").bind("click",function(){ alert("click事件被触发"); }) })
简写方式:
$(function(){ $("p").click(function(){ alert("click事件被触发"); }) })
合成事件
jQuery有两个合成事件——hover()方法和toggle(),属于jQuery自定义的方法。
(1)hover
hover()方法的语法结构:
hover(enter,leave);
hover()方法用于模拟光标悬停事件。当光标移动到元素上时,会触发指定的第1个函数(enter),当光标移出这个元素时,会触发指定的第2个函数(leave)。
注:hover()方法准确的说是替代了jQuery中的bind("mouseenter")和bind("mouseleave"),而不是替代bind("mouseover")和bind("mouseout").因此当需要触发hover()方法的第2个函数时,需要用trigger("mouseleave")来触发,而不是trigger("mouseout").
(2)toggle
toggle()方法的语法结构:
toggle(fn1,fn2,...fnN);
toggle()方法用于模拟鼠标连续单击事件。第一次单击元素,触发指定的第1个函数(fn1);再次单击同一个元素,触发第2个函数(fn2);如果有更多函数,则依次触发,直到最后一个。随后的每次单击都重复对这几个函数的轮番调用。
事件冒泡
在页面上可以有多个事件,也可以多个元素响应同一个事件。假设网页上有两个元素,其中一个元素嵌套在另个里面,并且都被绑定了click事件,同时<body>元素上也绑定了click事件。
<script> $(function(){ $("span").click(function(){ var txt = $("#msg").html() + "<p>内层span元素被单击</p>"; $("#msg").html(txt); }); $("#content").click(function(){ var txt = $("#msg").html() + "<p>外层div元素被单击</p>"; $("#msg").html(txt); }); $("body").click(function(){ var txt = $("#msg").html() + "<p>body元素被单击</p>"; $("#msg").html(txt); }); }) </script> <div id="content"> 外层div元素 <span>内层span元素</span> 外层div元素 </div> <div id="msg"></div>
当单击内部<span>元素,即触发<span>元素的click事件,会输出3条记录,这就是由事件冒泡引起的。
在单击<span>元素的同时,也单击了包含<span>元素的<div>及包含<div>的<body>,并且每个元素都会按照特定的顺序响应click事件。<span>--<div>--<body>。
之所以称为冒泡,是因为事件会按照DOM的层次结构像水泡一样不断向上直至顶端。
解决事件冒泡
事件对象
jQuery进行了必要的扩展和封装,从而使得在任何浏览器中都能很轻松地获取事件对象以及事件对象的一些属性。在程序中使用事件对象非常简单,只需要为函数添加一个参数。
$("element").bind("click",function(event){ //event:事件对象 //... })
这样,当单击“element”元素时,事件对象就被创建了。这个事件对象只有事件处理函数才能访问到。事件处理函数执行完毕后,事件对象就被销毁了。
停止事件冒泡
停止事件冒泡可以阻止事件中其他对象的事件处理函数被执行。在jQuery中提供了stopPropagation()方法来停止事件冒泡。
$("span").click(function(event){ var txt = $("#msg").html() + "<p>内层span元素被单击</p>"; $("#msg").html(txt); event.stopPropagation(); });
阻止默认行为
网页中的元素有自己默认的行为,例如,单击超链接后会跳转、单击“提交”按钮后表单会提交,有时需要阻止元素的默认行为。在jQuery中,提供了preventDefault()方法来阻止元素的默认行为。
<script> $(function(){ $("#sub").click(function(){ var username = $("#username").val(); if(username==""){ $("#msg").html("<p>文本框内容不能为空。</p>"); event.preventDefault(); } }) }) </script> <form action="test.html"> 用户名:<input type="text" id="username"/> <input type="submit" value="提交" id="sub"/> </form> <div id="msg"></div>
当用户名为空时,单击“提交”按钮,会出现“文本框不能为空。”的提示,并且表单不能提交。只有用户名输入内容后,才能提交表单。
其实无论是停止冒泡程序还是阻止默认行为都可以用“return false;”来代替。
事件捕获
事件捕获和事件冒泡刚好相反的两个过程,事件捕获是从自顶端往下开始出发。从最外层元素开始,然后再到最里层元素。jQuery不支持事件捕获,JavaScript支持。
事件对象的属性
(1)event.type
$("a").click(function(event){ alert(event.type); }) //"click"
(2)event.target
$("a[href='http://google.com']").click(function(event){ var tg = event.target; alert(tg.href); }) //"http://google.com"
(3)event.pageX和event.pageY
该方法的作用是获取到光标相对于页面的x的坐标和y坐标。如果页面上由滚动条,则还要加上滚动条的宽度或者高度。
$("a").click(function(event){ //获取鼠标当前相对于页面的坐标 alert("Current mouse position:" + event.pageX + ", " + event.pageY); })
(4)event.which
该方法作用是在鼠标单击事件中获取到鼠标的左、中、右键;在键盘事件中获取键盘的案件。
$("a").click(function(event){ alert(event.which); }) //1:鼠标左键;2:鼠标中键;3:鼠标右键