1

我有一个包含一些 Javascript / jQuery 内容的页面,例如:

(function()
{
    $('.tip').tooltip();

    $('.test').click(function()
    {
        alert('Clicked!')
    });
}();

在页面上,我使用 jQuery 插入了一些 HTML,因此 DOM 发生了变化。例如,我插入了一个带有“tip”或“test”类的额外元素。刚刚插入的新元素不起作用,因为 jQuery 正在使用未操作的 DOM,而刚刚插入的元素不存在。因此,我四处搜索并找到了“点击”的解决方案:

$('body').on('click','.click',function()
{
    alert('Clicked!')
});

我不明白为什么,但是这样它就可以使用被操纵的 DOM,而 jQuery 的东西可以在新插入的元素上工作。所以我的第一个问题是,为什么这行得通而只是 click() 函数不行?而第二个问题,为什么我必须指向“身体”?

最后,我的第三个问题是,如何使用工具提示完成这项工作?

我知道有很多关于这个主题的信息(之前我读过的 delegate() 和 live() 函数),但我找不到关于它的解释。而且我无法用我找到的信息解决我的第三个问题。

我期待着您的回复!

额外的问题:

4)是否建议在这种情况下始终指向“身体”?它总是在那里,但可能存在性能问题?

4

3 回答 3

3

所以我的第一个问题是,为什么这行得通而只是 click() 函数不行?

因为事件处理程序现在被委托给父元素,所以即使在替换/操作子元素之后它仍然存在。

关于事件委托的古老文章供您阅读 - 但概念保持不变:

还有第二个问题,为什么我要指向“身体”

您不需要,任何合适的父元素都可以。例如,任何不会被替换的直接父级(例如 div 包装器)。

最后,我的第三个问题是,如何使用工具提示完成这项工作?

您需要在新插入的元素上重新初始化工具提示插件。例如:

$.get("foo.html", function (html) {
    $("#someDiv").html(html);
    $("#someDiv").find(".tip").tooltip();
});
于 2013-03-26T19:16:29.737 回答
2

当您操作 DOM 时,该click()事件不起作用,因为 JQuery 没有监视 DOM 更改。当您绑定click()事件时,它会选择当时页面上的元素。除非您明确绑定事件,否则新的不在列表中。

因为您已将事件指向click()身体。JQuery 然后检查单击的目标是否匹配任何事件处理程序(如您创建的)与单击的元素匹配。这样,任何新元素都将获得与它们“关联”的事件。

因为工具提示不是您可以放置​​在主体上的事件,所以您需要在创建元素时重新初始化它。

编辑:

对于你的第四个问题,这取决于。绑定到主体的优点是您不会不小心将事件多次绑定到元素。缺点是您正在添加需要检查每个事件的事件处理程序,这可能会导致性能问题。

至于您对 DRY 的担忧,请将工具提示的初始化放入一个函数中,并在添加它们时调用它。在这方面,IMO 试图避免使用相同的函数调用有点矫枉过正。

于 2013-03-26T19:18:04.697 回答
1

事件绑定到您要绑定的特定对象。

因此,类似的东西$('.tip').tooltip()将执行 tooltip() 功能$('.tip'),实际上它只是满足 css 选择器的对象集合.tip。您应该注意的是,该集合不是动态的,它基本上是当前页面的“数据库”查询,并返回由 jQuery 包装的 HTML DOM 对象的结果集。

因此,在该集合上调用 tooptip() 只会对该集合内的对象执行工具提示功能,调用工具提示时不在该集合中的任何内容都将不具有工具提示功能。因此,在调用之后添加满足.tip选择器的元素不会为其提供工具提示功能。tooltip()

现在,$('body').on('click','.click', func)实际上是将点击事件绑定到body标签(它应该始终存在:P),但是它会捕获点击事件是否已通过您的目标 css 选择器的元素(.click在这种情况下),所以因为检查是动态完成,新元素将被捕获。

这是对正在发生的事情的相对简短的总结......我希望它有所帮助

更新: 工具提示的最佳方法是在添加元素后绑定工具提示,例如

$('#container').load('www.example.com/stuff', function() {
    $('.tip', $(this)).tooltip();
});
于 2013-03-26T19:23:24.960 回答