现在的web项目,不使用jquery的恐怕极少。但是在使用jquery时,也会发现一些异常的情况。
一般我们如下绑定点击等事件:
<div class="music">
<ul>
<li>01.mp3</li>
<li>02.mp3</li>
</ul>
</div>
$(function(){
$(".music").find("li").on('click',function(){
$("#myAudio").attr("src", "music/"+$.trim($(this).text()));
});
//... ...
});
因为该绑定事件是在一打开网页时,就进行了绑定,对于页面上已经存在的符合条件的 li 标签绑定了点击事件,但是如果在打开网页之后,通过 jquery 函数 append('<li> ....</li>')或者
prepend('<li>....</li>') 再一次插入页面上的 li 元素就不在上面的绑定范围之内了,因为这些 li 元素是在 $(function(){...}); 执行之后,才出现在页面上的。所以理所当然,就不受他的控制了。
解决方法形如下面处理:
1.方法一:
append('<li onclick="some_function()">....</li>');
这样处理就行了,就是在创建 li 标签的时间,内联绑定 onclick 事件来处理,就像css样式内联一样。这是最简单的处理方法,但是这样的话事件和html就绑定在一起了,代码耦合太过了。
2.方法二:
可以在
li元素的共同的祖先元素比如ul中进行绑定事件,这样即使是后面插入的li,也会因为事件冒泡机制而触发事件,而得到执行。
$(function(){
$(".music").find("ul").on('click', function(){
$("#myAudio").attr("src", "music/"+$.trim($(this).text()));
});
});
但是在祖先元素上绑定事件,有个缺点,即 this 对象发生了变化,this对象变成了祖先元素,要特别注意这点,如果代码中要使用到this对象,比如本例中。那么就会发生错误!所以上面的代码其实是错误的。但是此时也还是有解救的方法:
$(function(){
$(".music").find("ul").on('click', 'li', function(){
alert(this); //[object HTMLLIElement]
alert(event.target); //[object HTMLLIElement]
alert(event.currentTarget); //[object HTMLLIElement]
$("#myAudio").attr("src", "music/"+$.trim($(this).text()));
});
});
使用事件的委托机制,加入一个过滤的参数 'li' ,此时代码中的 this 对象就是 li 而不是他的祖先 ul 了。我们看到this==event.target==event.currentTarget
所以在使用冒泡机制的事件委托时,如果使用到了 this 对象,一定要将实际的那个点击对象,通过过滤参数参入进去。这样 this 对象才是那个实际点击的对象,不然this对象就成了选择对象了。
我们查看jquery的文档如下:
返回值:jQuery on(events,[selector],[data],fn)
events:一个或多个用空格分隔的事件类型和可选的命名空间,如"click"或"keydown.myPlugin" 。
selector:一个选择器字符串用于过滤器的触发事件的选择器元素的后代。如果选择的< null或省略,当它到达选定的元素,事件总是触发。
data:当一个事件被触发时要传递event.data给事件处理函数。
fn:该事件被触发时执行的函数。 false 值也可以做一个函数的简写,返回false。
3.方法三
使用event的属性target。我们知道每一个事件都有一个event对象,他的event.target就是我们直接点击的对象,而event.currentTarget是事件冒泡过程中冒泡到哪里,就代表哪个对象,所以冒泡结束时event.currentTarget代表的就是我们在哪个父元素上绑定事件,他就代表哪个对象,我们可以使用下面的代码进行测试:
$(".music").find("ul").on('click',function(event){
alert(this); //[object HTMLUListElement]
alert(event.target); //[object HTMLLIElement]
alert(event.currentTarget); //[object HTMLUListElement]
$("#myAudio").attr("src", "music/"+$.trim($(event.target).text()));
});
我们在li的父元素ul上进行绑定,那么冒泡结束,也就是事件进行处理时,this代表的是event.currentTarget,而不是event.target。上面我们可以清楚的看到这一点!清楚了这一点,我们就可以使用 event.target 来获取我们直接点击的那个对象,获得他的属性,设置他的属性,对他进行各种操作。
我们一定要明白this 和 event.target, event.currentTarget三者的联系和区别。在利用冒泡机制进行事件处理时,一定不要错误地将this 和 event.target等同!
3.方法四
使用jquery的live()函数来绑定事件,但是jquery-1.11.1已经不支持live()函数了。从1.7开始推荐使用delegate函数来代替。
3.方法四
使用delegate()函数:
$(".music").find("ul").delegate('li', 'click', function(event){
alert(this); //[object HTMLLIElement]
alert(event.target); //[object HTMLLIElement]
alert(event.currentTarget); //[object HTMLLIElement]
$("#myAudio").attr("src", "music/"+$.trim($(this).text()));
});
我们看到使用delegate()函数是,this == event.target == event.currentTarget.所以此时可以使用this来获得我们直接点击的那个元素。
jquery文档:
使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)
从上面我们可以看到,加入了过滤参数的on绑定函数和delegate函数是等价的。所以目前推荐一切事件绑定都使用on函数,因为在jQuery 1.7中,.on()方法 提供绑定事件处理程序所需的所有功能。帮助从旧的jQuery事件方法转换,完全取代 .bind(), .delegate(), 和 .live(). 要删除的.on()绑定的事件,请参阅.off()。
我们甚至可以将事件绑定到body上:
$("body").on('click', '.music li', function(event){
alert(this); //[object HTMLLIElement]
alert(event.target); //[object HTMLLIElement]
alert(event.currentTarget); //[object HTMLLIElement]
$("#myAudio").attr("src", "music/"+$.trim($(this).text()));
});
总结:
1)理解 event, event.target, event.currentTarget, this
2)事件冒泡机制
3)一切事件绑定事件推荐使用on函数,事件代理一定要指定on函数的过滤参数,也就是event。target对象。
4)非事件代理中,this, event.currentTarget 都是变化的,event.target始终指向直接触发事件的那个元素。但是在事件代理中,三者是一致的,都是指直接触发事件的元素。
分享到:
相关推荐
在jQuery中,动态添加元素(如使用`append`方法)并尝试为这些新添加的元素绑定事件时,可能会遇到一个问题:绑定的事件无法正常触发。这是因为JavaScript的事件处理方式是基于DOM(文档对象模型)的,当元素在页面...
在这个例子中,我们绑定了滚轮事件到`body`元素,当滚轮事件触发时,会打印出滚动的方向。`event.originalEvent.wheelDelta`用于IE和Chrome,正数表示向上滚动,负数表示向下滚动;`-event.originalEvent.detail`...
然而,这种操作往往伴随着一个挑战:为这些新添加的元素绑定的事件可能无法正常工作,即所谓的“事件失效”问题。这个问题的根源在于事件冒泡机制,即事件从最深的节点向上层节点传播。当动态添加的元素不存在于DOM...
因此,当通过JavaScript代码动态添加新的DOM元素到页面中时,原先绑定的事件并不会应用到这些新元素上,导致事件失效。 解决动态生成DOM元素事件失效的方法有几种: 1. 直接在动态生成DOM元素的地方重新绑定事件。...
这种方法不仅解决了新插入元素的事件绑定问题,而且还能提高性能,因为只需要绑定一次事件处理函数,而不是为每个新添加的元素单独绑定。因此,无论代码的复杂程度如何,`on`方法都是处理动态元素事件绑定的最佳实践...
总的来说,解决jQuery `append`添加元素的事件无效问题,关键在于使用`on`方法代替`click`等直接的事件绑定,并将事件处理器绑定到一个固定的、已存在的父元素上,以便处理动态生成的子元素的事件。这种方法不仅解决...
2. **事件绑定**:jQuery的`.on()`方法允许我们绑定各种事件,如`mouseenter`(鼠标进入)、`mouseleave`(鼠标离开)或`click`(点击)。当这些事件触发时,我们执行相应的处理函数。 3. **CSS样式操作**:jQuery...
3. **事件处理**:jQuery的事件处理非常方便,例如`click()`, `mouseover()`, `mouseout()`, `change()`等,可以轻松绑定事件监听器。`on()`函数是更通用的事件绑定方法,支持动态加载的元素。 4. **jQuery UI**:...
在JavaScript和jQuery的世界中,事件绑定是常见的交互方式,它允许我们对用户的操作做出响应。然而,如果在处理动态内容时不小心,可能会遇到事件绑定叠加的问题,这正是本文要探讨的核心话题。 首先,我们需要理解...
本文主要讨论了在使用jQuery动态添加HTML内容和JavaScript事件绑定时,可能出现的失效问题。具体来说,涉及到以下几个知识点: 1. jQuery动态添加HTML内容:在Web开发中,经常需要动态地向页面中添加新的HTML元素。...
当使用jQuery库来操作DOM和绑定事件时,如果页面的部分内容是通过AJAX动态加载的,就可能出现事件绑定失效的问题。本知识点将围绕“AJAX更新数据后,jQuery事件失效问题”进行深入探讨。 首先,我们要了解jQuery的...
总之,要解决jQuery中`.on()`事件冒泡问题,推荐的方法是将事件处理器绑定到离目标元素最近的父元素上,并在需要阻止冒泡的情况下,在事件处理函数中调用`e.stopPropagation()`方法。这样做既可以提高程序的性能,也...
这就是为什么在页面内容动态加载后,使用`bind()`绑定的事件可能失效的原因。 为了解决这个问题,jQuery引入了`delegate()`方法。`delegate()`专门用于处理动态生成的元素的事件绑定。它的基本使用方式如下: ```...
如果`<body>`标签已经有了`onload`事件,jQuery的`$(document).ready()`事件绑定的函数可能不会被执行。 3. **绑定与反绑定事件监听器** - **绑定事件**: - `bind(type, [data], fn)`是基本的事件绑定函数,将...