DOM树更改时更新事件处理程序

Update Event Handlers when the DOM tree changes

本文关键字:更新 事件处理 程序 DOM      更新时间:2023-09-26

可能重复:
JQuery或vanilla Javascript 中的DOM突变事件

我使用的backbone.js带有动态生成的模板,我使用的是几个jQuery UI插件,它们附加到一些类上,比如slimScroll:

$(function(){
    $('.scroll').slimScroll({
        height: $(window).height();
    });
    $('.stars').changeSelectBoxToRatingStars();
    // ...
});

当我更新DOM树(通过呈现模板、加载新内容…)并且添加了新元素时,需要刷新这些绑定。

有一些DOM树突变事件,现在已弃用,IE不支持这些事件(请参阅DOM突变事件替换)。我在jQuery中也看到了.live(),它可以更新类似事件的.click(),但它不能监视DOM的更改。对于在每个浏览器中监控DOM树更改的高效、符合标准的方法,有什么建议吗?

我真的不建议使用.live().

.live()将事件与最高的DOM元素(主要是文档)相关联。的确,如果你在某个特定的选择器上使用它,然后动态添加一些新元素,这也会使之前关联的事件发生,但每次启动该事件时,它都必须向上转到DOM树中的文档元素来处理它。

在一个巨大的DOM树中思考它。您单击一个td元素,它会在整个DOM中运行,直到document元素。这很恶心。

处理这种情况的最好方法是使用.delete()。它的工作原理与.live()方法类似,但不会将事件启动到document元素中的处理程序,而是在您选择的上层元素中。

像这样:

$(UpperElement).delegate(SelectorsOfClickableElements, eventsToDelegate, callbackFunction); 

这样,当您单击DOM中的新元素时,事件的处理程序将是您选择的上层元素,而不是文档元素。相信我,这比.live().快得多

.on()自jQuery 1.7开始工作。我对此有点过时了,但也许你会发现它更好。无论如何,.delete()应该可以工作。

对不起我的英语。

JCADE(JQuery创建和销毁事件)将执行此操作。它对IE使用行为,对其他浏览器使用DOM突变事件。它不使用计时事件,也不包装像livequery这样的JQuery方法。

https://github.com/snesin/jcade

$(document).create("a",function(event){alert(event.target);});

我终于自己找到了解决方案。正如@Šime Vidas在评论中所建议的那样,我现在在需要时直接处理UI更新。也就是说,当(在MainRouter#show中)呈现新内容时,

class MainRouter extends Backbone.Router
  # [...]
  show: (id) ->
    item = Items.get(id)
    # Render item
    @view = new ShowView(model: item)
    $(".content").html(@view.render().el)
    # Update scrolling and UI items
    window.updateUI()

当调整窗口大小时打开:

window.$(window).resize -> window.updateUI()

window.updateUI()方法本身并不花哨。它只是在必要的地方添加slimScroll滚动条,并在调整窗口大小时更新一些div。

感谢大家的帮助