【问题标题】:jquery .on not working after other .on calljquery .on 在其他 .on 通话后无法正常工作
【发布时间】:2012-06-11 20:55:43
【问题描述】:

我有以下 jquery 脚本:

$(function(){   
$('#top-menu').on('click', 'a.change-menu', function(e){   
e.preventDefault()   
$("#menu-change-div").load($(this).attr("href"));   

});  
}); 

$(function(){   
$('#menu-change-div').on('click', 'a.change-content', function(e){     
e.preventDefault()   
$("#content").load($(this).attr("href"));     
});  
}); 

这是正文中的 HTML:

<div id="menu-div">
<div id="top-menu">
<h3 id="top-tabs"><a href="contentColumn.html" class="change-menu">Contents</a></h3>
<h3 id="top-tabs"><a href="indexColumn.html" class="change-menu">Index</a></h3>
<h3 id="top-tabs"><a href="searchColumn.html" class="change-menu">Search</a></h3>
</div>
<div id="menu-change-div">
<ul>
//Lots of nested list items and ul's with #change-content id
</ul>
</div>
</div>

<div id="content">
<div id = "page-content">
//content section
</div>
</div>

当我单击菜单 div 中的列表项并将 html 文件加载到我的内容 div 中时,会发生第一个功能。

第二个在选择不同的选项卡时更改菜单div中的内容。

我可以单击列表项,一切都按预期工作,当我单击选项卡时,它也可以正常工作。如果我首先单击一个列表项,然后单击一个选项卡,然后单击另一个列表项,则会出现我的问题。它不像第一次单击时那样将 html 加载到 div 中,而是跟随 href 并在另一个窗口中打开它。任何想法我做错了什么?

【问题讨论】:

  • 这些.on() 调用都没有使用委托,这意味着当它们绑定的元素被替换/删除时,事件将不再发生。 api.jquery.com/on

标签: jquery onclick


【解决方案1】:

试试:

$(function() {
    $('body').on('click', 'a.change-content', function(e) {
        e.preventDefault()
        $("#content").load($(this).attr("href"));
        return false;
    });
    $('body').on('click', 'a.change-menu', function(e) {
        e.preventDefault()
        $("#menu-change-div").load($(this).attr("href"));
    });
});​

如果元素是动态添加的,那么你需要改变你使用 .on() 的方式。

根据docs

事件处理程序仅绑定到当前选定的元素;他们 在您的代码调用 .on() 时必须存在于页面上。 为了确保元素存在并且可以被选择,执行事件 绑定在文档就绪处理程序中的元素 页面上的 HTML 标记。如果新的 HTML 被注入到页面中, 在新的 HTML 之后选择元素并附加事件处理程序 放置在页面中。或者,使用委托事件附加事件 处理程序,如下所述。

另外请注意,您可以将两个$(function () {...}) 合二为一。

【讨论】:

  • 除了body之外还有更好的元素。在某种程度上,它就像全局变量或单例。
  • 我同意。但是,如果没有任何 HTML,我只能提供正文作为保证。
  • 绝对,也许将其添加到您的答案中。 +1 任一方式
  • 在这种情况下,您可以使用document,这是.live 的委托。它保证在代码中的任何地方也可以工作(就像在 domready 之前一样)。 :P
  • 是的,项目是动态添加的,当我更改选项卡时,我的菜单 div 中的列表元素会发生变化。
【解决方案2】:

当另一个选项卡出现时,第二个会更改我的菜单 div 中的内容 已选中。

那么您可能需要将您的第二个 click 事件处理程序委托给将留在 DOM 中的祖先元素。您可以通过将选择器传递给 on 方法来做到这一点:

$("#someAncestor").on("click", "a.change-menu", function(e) {
    //Do stuff
});

这是因为当您更改a.change-menu 引用的元素时,绑定事件处理程序的元素不再存在(新元素不会自动获取绑定到它们的事件处理程序)。

通过将事件处理程序委托给 DOM 树的更高层,您可以利用大多数 DOM 事件在树上冒泡的事实,并且您可以在祖先元素上侦听该事件。如果事件目标与传递给on 的选择器匹配,则执行事件处理程序。

【讨论】:

    【解决方案3】:

    .on() 方法正在侦听已经存在的 DOM 元素。如果添加一些新元素,它们将不会被监听。如果您需要监听这些元素,即使它们是后来添加的(例如使用 .load()),请使用 .live() 方法。

    【讨论】:

    • .on 被重载以根据参数进行委托/直接绑定。 .live 已弃用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    相关资源
    最近更新 更多