element.innerHTML 更改后 mootools 事件侦听器消失
我整理了一个页面,将显示一组存储的值。我使用 mootools 和 AJAX 调用来更新值,而无需在用户每次从下拉菜单中选择新项目时刷新页面。
HTML 的每一行看起来像这样:
<div class="selections">
<input class="checkbox selector" type="checkbox" CHECKED />
<span class="b_name">
<select class="b_n selector">
<!-- options -->
</select>
</span>
<span class="b_level">
<select class="b_l selector">
<!-- options -->
</select>
</span>
<span class="values">
<!-- the values -->
</span>
</div>
在头部我设置了一个事件侦听器,例如:
$$('.selector').addEvent('change', function(event){changeValues(this);});
我的问题是,当 "b_name"
选择更改时,我必须更新 中的选项列表>“b_level”
选择。我通过另一个页面上的 PHP 脚本从数据库获取可能选项的列表并替换 "b_level"
的 innerHTML 来实现这一点。一旦我这样做,附加到“b_l选择器”的事件侦听器就不再起作用。
我尝试通过每次 "b_name"
更改时显式地将事件侦听器附加到 "b_l 选择器"
来解决此问题,如下所示:
row.getElement('.b_l').addEvent('change', function(event){changeValues(row.getElement('.b_l'));});
其中 'row' 是 html 元素 'div .选择'。
它仍然不起作用,我不知道发生了什么事。任何人都可以提供有关如何解决此问题的建议吗?或者也许是做我正在做的事情的更好方法。
I putting together a page that will display a set of stored values. I am using mootools and AJAX calls to update the values without needing to refresh the page each time the user selects a new item from the drop down menus.
the HTML each line looks something like:
<div class="selections">
<input class="checkbox selector" type="checkbox" CHECKED />
<span class="b_name">
<select class="b_n selector">
<!-- options -->
</select>
</span>
<span class="b_level">
<select class="b_l selector">
<!-- options -->
</select>
</span>
<span class="values">
<!-- the values -->
</span>
</div>
In the head I have set up an event listener like:
$('.selector').addEvent('change', function(event){changeValues(this);});
My problem is that when the "b_name"
select changes I have to update the list of options in the "b_level"
select. I accomplish that by getting a list of the possible options from my database through a PHP script on another page and replacing "b_level"
's innerHTML. Once I do that, the event listener attached to "b_l selector"
no longer works.
I tried to resolve this issue by explicitly attaching an event listener to "b_l selector"
each time "b_name"
changes like so:
row.getElement('.b_l').addEvent('change', function(event){changeValues(row.getElement('.b_l'));});
where 'row' is the html element 'div.selections'.
It still isn't working and I have no idea what's going on. Can anyone offer a suggestion as to how I can get this resolved? or perhaps a better way to do what I'm doing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这就是 JavaScript 的工作原理,它不是错误。
您需要使用的是元素委托 - 将事件附加到父元素,同时指定事件应委托给的元素。
以下是元素委托实际操作的基本示例:http://jsfiddle.net/ oskar/ENR3E/
以及文档:http ://mootools.net/docs/more/Element/Element.Delegation
This is how JavaScript works, it's not a bug.
What you need to use is Element Delegation - you attach an event to the parent element, in the same time specifying the element that the event should be delegated to.
Here's a basic example of Element Delegation in action: http://jsfiddle.net/oskar/ENR3E/
And the documentation: http://mootools.net/docs/more/Element/Element.Delegation
当您在元素上设置
innerHTML
时,该元素的内容将被完全清除并替换为一组新的元素 - 从innerHTML
属性解析的元素。在旧元素上设置的任何事件都不会应用于新元素。jQuery 通过
live()
事件提供了解决此问题的方法。我找到了一个解决方案这里,它显然实现了与 mootools 相同。When you set
innerHTML
on an element, the element's contents are completely cleared and replaced with a new set of elements -- the ones parsed from theinnerHTML
property. Any events set on the old elements will not apply to the new ones.jQuery provides a solution to this problem with
live()
events. I found a solution here that apparently achieves the same with mootools.您的方法是正确的,您的
addEvent()
代码中可能存在错误。当您替换innerHTML 时事件处理程序消失的原因非常简单 - 您正在删除处理程序所在的元素,因此处理程序也会被删除。但是您重新添加处理程序的方法应该有效。我认为这可能是一个范围问题。如果显式引用 div 会发生什么,如下所示:
Your approach is correct, there's probably just a bug in your
addEvent()
code. The reason the event handler disappears when you replace the innerHTML is straightforward enough - you are removing the elements that the handlers are on, so the handlers are removed as well. But your approach to re-add the handler should work.I think it's possible that it's a scoping issue. What happens if you reference the div explicitly, like this: