到目前为止,我一直在使用livequery,但这会使页面浏览看起来很慢。 所以我正试图为此寻找替代解决方案。
我附加了一个函数,该函数在具有某个类的元素上运行一些ajax,如:
$(".blah").each(function(){
$.ajax({
...
success: function(data) {
$(this).removeClass(".blah");
// do other stuff
}
});
});
现在我有几个事件挂钩在可以在DOM中附加html的不同元素,例如:
$(".button").click(function(){
$.ajax({
...
success: function(data) {
$(this).append(data);
// here, new elements with ".blah" class could be inserted in the DOM
// the event above won't be fired...
}
});
});
如果在其他事件中更新DOM,我怎么能这样运行上面的第一个ajax函数?
更新
我也找到了这个插件: http://www.thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin/
你认为这是一个更好的解决方案吗?从快速查看看起来,因为它允许您设置“轮询”间隔,如果将其设置为1秒或某些时间,可能会降低CPU使用率。我现在正在测试它:)
更新2:
不幸的是,它仅适用于元素ID,原因有些奇怪:(
答案 0 :(得分:13)
大多数主流浏览器(但遗憾的是不是IE< = 8)支持DOM mutation events(另见MDN)。如果您只想将节点添加到DOM中,请使用DOMNodeInserted
事件。如果您想了解任何DOM更改,请使用catch-all DOMSubtreeModified
事件。
例如:
document.addEventListener("DOMNodeInserted", function(evt) {
alert("Node inserted. Parent of inserted node: " + evt.relatedNode.nodeName);
}, false);
document.body.appendChild( document.createElement("div") );
现在不推荐使用DOM突变事件,浏览器逐渐转移到mutation observers。目前最明智的策略似乎是使用变异观察者并回归突变事件。
答案 1 :(得分:2)
这是真的,因为新元素没有绑定到回调的事件,它们只是新的元素。我建议在新创建的元素创建之后(即在ajax成功函数内)绑定事件:
$(".blah").each(function(){
$.ajax({
...
success: function(data) {
$(this).removeClass(".blah");
// add handlers to new elements with class "button"
$(this).find('.button').click(function() {
$.ajax({
success: function(data) {
$(this).append(data);
});
}
});
}
答案 2 :(得分:1)
我也遇到过这样的问题。没有真正的方法让dom改变(我知道)。我通过两种不同的方法来解决这个问题
你也可以将第一个ajax查询绑定到body标签,这样当用户点击ajax事件时会触发的任何内容,然后检查是否符合正确的标准。
编辑:这可能有效。添加$(“BODY ID / CLASS”)。change(function(){});不完全确定,因为我不是最流利的jQuery。
答案 3 :(得分:1)
IE9 +,FF和Chrome:
var observeDOM = (function(){
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
eventListenerSupported = window.addEventListener;
return function(obj, callback){
if( MutationObserver ){
// define a new observer
var obs = new MutationObserver(function(mutations, observer){
if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
callback();
});
// have the observer observe foo for changes in children
obs.observe( obj, { childList:true, subtree:true });
}
else if( eventListenerSupported ){
obj.addEventListener('DOMNodeInserted', callback, false);
obj.addEventListener('DOMNodeRemoved', callback, false);
}
}
})();
observeDOM( $('#dom_element')[0] ,function(){
console.log('dom changed');
});