在介绍方法之前,我觉得有必要描述一下响应事件的两种策略,一种是事件捕获(Event capturing),一种是事件冒泡(Event bubble),这两种策略是相对立的,它们是在浏览器大战中分别由Netscape和微软提出的完全相反的两种事件传播模型。事件冒泡定义为在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层。而事件捕获则与事件冒泡则恰好相反,处理事件是从对象的最外层往里传播,直到终止。W3C标注是支持两种事件处理策略的,但是却更偏向于事件冒泡,因为事件捕获Bug较多,目前IE是不支持事件捕获的,其他浏览器基本两种都支持。下面我给一个事件冒泡的例子,自己试一下就明白了,至于事件捕获就算了.....
事件冒泡
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>JavaScript事件冒泡</title> <style type="text/css"> #box {width:200px; height:100px; border:2px solid red} #box h5 {margin:0; padding:2px 5px; font-size:18px; text-align:right; background:red; cursor:move} #box h5 a {text-decoration:none; color:#FFF} #box div{ white-space:inherit;}</style> </head> <body> <div id="box"> <h5 οnmοusedοwn="startDrag();"><a οnmοusedοwn="closeBox();" href="javascript:void(0);">关闭</a></h5> <div id="testInfo"></div> </div> <script type="text/javascript"> function startDrag() { document.getElementById('testInfo').innerHTML += '层事件'; } function closeBox(e) { document.getElementById('testInfo').innerHTML += '关闭事件'; //将下面一段注释去掉则可以阻止冒泡// if (e && e.stopPropagation)// e.stopPropagation();// else// window.event.cancelBubble = true; }</script> </body> </html>
那么在JQuery中阻止事件策略的方法有event.preventDefault();(阻止默认行为)、event.stopPropagation();event.stopImmediatePropagation();(阻止事件冒泡)、直接返回return false;(阻止默认行为和时间冒泡)。
事件处理包括bind(type,[data],fn)、bind(map)、one(type,[data],fn)、trigger(type,[data])、triggerHandler(type,[data])、unbind([type],[data])这几个方法。
1、bind(type,[data],fn)用于为指定元素绑定指定的事件处理函数,[data]代表可选的传递的参数,它的写法为:
代码
//带参数的绑定方式 $("#text").bind('click', { result: "yes" }, function(event) { alert(event.data.result); }) //不带参数并且阻止冒泡 $("#text").bind('click', function(e) { //自定义处理行为 e.stopPropagation(); })
其实bind(type,[data],fn)这种绑定事件的方式我们还有一种简写的方式,但是他们的区别在于简写方式不能如bind一样指定参数[data],他的写法就是直接将bind中type参数执行,如下:
$("#text").click(function(e) { //自定义处理行为 alert("简写方式"); })
2、bind(map)就是一次性为元素绑定多个事件处理函数,写法如下:
代码
$('#text').bind({ click: function() { alert("bind(map)绑定的click事件"); }, mouseenter: function() { alert("bind(map)绑定的mouseenter事件"); } });
3、one(type,[data],fn)指定事件只执行一次,写法与bind()方法一样,在此就不做示范。
4、trigger(type,[data])、triggerHandler(type,[data])其实作用是一样的,都是在每一个匹配的元素上触发某类事件,唯一的区别就是前者是执行事件冒泡事件的,而后者只执行指定元素的事件。下面做个比较:
代码
//HTML代码:<button id="trigger">trigger()</button><button id="triggerHandler">triggerHandler()</button><br/><br/><div id="triggerdiv"> <div id="tri"></div></div>//JQuery代码 $("#triggerdiv").click(function() { alert("DIV触发"); }); $("#trigger").click(function() { $("#tri").trigger("click"); }); $("#triggerHandler").click(function() { $("#tri").triggerHandler("click"); }); $("#tri").click(function() { alert("子集DIV触发"); });
5、unbind([type],[data])就再简单不过了,删除指定元素的绑定事件,如果指定type参数则删除指定的事件,如果没有指定则删除该指定元素的所有事件。
在这些事情机制中我最常用到的还是bind方法,再常用的就是它的简写方式。当然这些事件机制是可以结合起来用的,关键看业务需求而定
001 | jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法 |
002 | |
003 | $("#myELement") 选择 id 值等于 myElement 的元素, id 值不能重复在文档中只能有一个 id 值是 myElement 所以得到的是唯一的元素 |
004 | $("div") 选择所有的 div 标签元素,返回 div 元素数组 |
005 | $(".myClass") 选择使用 myClass 类的 css 的所有元素 |
006 | $("*") 选择文档中的所有的元素,可以运用多种的选择方式进行联合选择:例如 $("#myELement,div,.myclass") |
009 | $("form input") 选择所有的 form 元素中的 input 元素 |
010 | $("#main > *") 选择 id 值为 main 的所有的子元素 |
011 | $("label + input") 选择所有的 label 元素的下一个 input 元素节点,经测试选择器返回的是 label 标签后面直接跟一个 input 标签的所有 input 标签元素 |
012 | $("#prev ~ div") 同胞选择器,该选择器返回的为 id 为 prev 的标签元素的所有的属于同一个父元素的 div 标签 |
015 | $("tr:first") 选择所有 tr 元素的第一个 |
016 | $("tr:last") 选择所有 tr 元素的最后一个 |
017 | $("input:not(:checked) + span") |
018 | |
019 | 过滤掉: checked 的选择器的所有的 input 元素 |
020 | |
021 | $("tr:even") 选择所有的 tr 元素的第 0 , 2 , 4... ... 个元素(注意:因为所选择的多个元素时为数组,所以序号是从 0 开始) |
022 | |
023 | $("tr:odd") 选择所有的 tr 元素的第 1 , 3 , 5... ... 个元素 |
024 | $("td:eq(2)") 选择所有的 td 元素中序号为 2 的那个 td 元素 |
025 | $("td:gt(4)") 选择 td 元素中序号大于 4 的所有 td 元素 |
026 | $("td:ll(4)") 选择 td 元素中序号小于 4 的所有的 td 元素 |
027 | $(":header") |
028 | $("div:animated") |
031 | $("div:contains('John')") 选择所有 div 中含有 John 文本的元素 |
032 | $("td:empty") 选择所有的为空(也不包括文本节点)的 td 元素的数组 |
033 | $("div:has(p)") 选择所有含有 p 标签的 div 元素 |
034 | $("td:parent") 选择所有的以 td 为父节点的元素数组 |
037 | $("div:hidden") 选择所有的被 hidden 的 div 元素 |
038 | $("div:visible") 选择所有的可视化的 div 元素 |
041 | $("div[id]") 选择所有含有 id 属性的 div 元素 |
042 | $("input[name='newsletter']") 选择所有的 name 属性等于 'newsletter' 的 input 元素 |
043 | |
044 | $("input[name!='newsletter']") 选择所有的 name 属性不等于 'newsletter' 的 input 元素 |
045 | |
046 | $("input[name^='news']") 选择所有的 name 属性以 'news' 开头的 input 元素 |
047 | $("input[name$='news']") 选择所有的 name 属性以 'news' 结尾的 input 元素 |
048 | $("input[name*='man']") 选择所有的 name 属性包含 'news' 的 input 元素 |
049 | |
050 | $("input[id][name$='man']") 可以使用多个属性进行联合选择,该选择器是得到所有的含有 id 属性并且那么属性以 man 结尾的元素 |
053 | |
054 | $("ul li:nth-child(2)"),$("ul li:nth-child(odd)"),$("ul li:nth-child(3n + 1)") |
055 | |
056 | $("div span:first-child") 返回所有的 div 元素的第一个子节点的数组 |
057 | $("div span:last-child") 返回所有的 div 元素的最后一个节点的数组 |
058 | $("div button:only-child") 返回所有的 div 中只有唯一一个子节点的所有子节点的数组 |
061 | |
062 | $(":input") 选择所有的表单输入元素,包括 input, textarea, select 和 button |
063 | |
064 | $(":text") 选择所有的 text input 元素 |
065 | $(":password") 选择所有的 password input 元素 |
066 | $(":radio") 选择所有的 radio input 元素 |
067 | $(":checkbox") 选择所有的 checkbox input 元素 |
068 | $(":submit") 选择所有的 submit input 元素 |
069 | $(":image") 选择所有的 image input 元素 |
070 | $(":reset") 选择所有的 reset input 元素 |
071 | $(":button") 选择所有的 button input 元素 |
072 | $(":file") 选择所有的 file input 元素 |
073 | $(":hidden") 选择所有类型为 hidden 的 input 元素或表单的隐藏域 |
074 | |
077 | $(":enabled") 选择所有的可操作的表单元素 |
078 | $(":disabled") 选择所有的不可操作的表单元素 |
079 | $(":checked") 选择所有的被 checked 的表单元素 |
080 | $("select option:selected") 选择所有的 select 的子元素中被 selected 的元素 |
083 | |
084 | 选取一个 name 为 ”S_03_22″ 的 input text 框的上一个 td 的 text 值 |
085 | $(”input[@ name =S_03_22]“).parent().prev().text() |
086 | |
087 | 名字以 ”S_” 开始,并且不是以 ”_R” 结尾的 |
088 | $(”input[@ name ^='S_']“).not(”[@ name $='_R']“) |
089 | |
090 | 一个名为 radio_01 的 radio 所选的值 |
091 | $(”input[@ name =radio_01][@checked]“).val(); |
092 | |
097 | $("A B") 查找 A 元素下面的所有子节点,包括非直接子节点 |
098 | $("A>B") 查找 A 元素下面的直接子节点 |
099 | $("A+B") 查找 A 元素后面的兄弟节点,包括非直接子节点 |
100 | $("A~B") 查找 A 元素后面的兄弟节点,不包括非直接子节点 |
101 | |
102 | 1. $("A B") 查找 A 元素下面的所有子节点,包括非直接子节点 |
103 | |
104 | 例子:找到表单中所有的 input 元素 |
109 | <label>Name:</label> |
110 | <input name="name" /> |
111 | <fieldset> |
112 | <label>Newsletter:</label> |
113 | <input name="newsletter" /> |
114 | </fieldset> |
115 | </form> |
116 | <input name="none" /> |
119 | $("form input") |
120 | 结果 : |
121 | |
122 | [ <input name="name" />, <input name="newsletter" /> ] |
123 | |
124 | 2. $("A>B") 查找 A 元素下面的直接子节点 |
125 | 例子:匹配表单中所有的子级 input 元素。 |
126 | |
129 | <form> |
130 | <label>Name:</label> |
131 | <input name="name" /> |
132 | <fieldset> |
133 | <label>Newsletter:</label> |
134 | <input name="newsletter" /> |
135 | </fieldset> |
136 | </form> |
137 | <input name="none" /> |
138 | jQuery 代码 : |
139 | |
140 | $("form > input") |
143 | [ <input name="name" /> ] |
144 | |
145 | 3. $("A+B") 查找 A 元素后面的兄弟节点,包括非直接子节点 |
146 | 例子:匹配所有跟在 label 后面的 input 元素 |
151 | <label>Name:</label> |
152 | <input name="name" /> |
153 | <fieldset> |
154 | <label>Newsletter:</label> |
155 | <input name="newsletter" /> |
156 | </fieldset> |
157 | </form> |
158 | <input name="none" /> |
161 | $("label + input") |
162 | 结果 : |
163 | |
164 | [ <input name="name" />, <input name="newsletter" /> ] |
167 | 4. $("A~B") 查找 A 元素后面的兄弟节点,不包括非直接子节点 |
168 | 例子:找到所有与表单同辈的 input 元素 |
173 | <label>Name:</label> |
174 | <input name="name" /> |
175 | <fieldset> |
176 | <label>Newsletter:</label> |
177 | <input name="newsletter" /> |
178 | </fieldset> |
179 | </form> |
180 | <input name="none" /> |
183 | $("form ~ input") |
184 | 结果 : |
185 | |
186 | [ <input name="none" /> ] |