jQuery - 如何将处理程序附加到尚不存在的元素?

5

我刚遇到了一个jQuery的问题。我没有找到已经发布的解决方案,如果有的话,我很抱歉我的错误。

我有这个DOM:

<div class='usersList list'>                                    
    <div id='7' class='sidebarElement'> <span>user</span></div> 
    <div id='21' class='sidebarElement'><span>user</span></div> 
    <div id='12' class='sidebarElement'><span>user</span></div> 
    <div id='15' class='sidebarElement'><span>user</span></div> 
    <div id='17' class='sidebarElement'><span>user</span></div> 
    <div id='13' class='sidebarElement'><span>user</span></div> 
    <div id='5' class='sidebarElement'> <span>user</span></div> 
    <div id='3' class='sidebarElement'> <span>user</span></div> 
    <div id='4' class='sidebarElement'> <span>user</span></div> 
    <div id='19' class='sidebarElement'><span>user</span></div> 
    <div id='2' class='sidebarElement'> <span>user</span></div> 
    <div id='6' class='sidebarElement'> <span>user</span></div> 
    <div id='18' class='sidebarElement'><span>user</span></div> 
    <div id='16' class='sidebarElement'><span>user</span></div> 
    <div id='14' class='sidebarElement'><span>user</span></div> 
</div>                                                          

这段代码通过AJAX从另一个文件中加载。我遇到的问题如下。这是我的JS代码:

$(document).ready(function () {

    function reloadUsers(query) {
        $.ajax({
            url: 'getLoginUsersAjax.php',
            type: 'GET',
            data: {query: query},
            success: function (data) {
                $('.usersCardAjaxContainer').empty().html(data);
            }
        });
    }

    $(".sidebarElement span").click(function() {
       console.log($(this).parent().attr("id"));
    })

    reloadUsers("");

});

这不起作用,我认为是因为元素是通过AJAX加载的,当解析或其他操作click时,它们还不存在,我不知道jQuery内部如何工作。我的解决方法是将点击事件放入ajax的success分支中,像这样:

success: function (data) {
    $('.usersCardAjaxContainer').empty().html(data);

    $(".sidebarElement span").click(function() {
        console.log($(this).parent().attr("id"));
    })
}

这个方法可以运行,但是我认为它不太对。我已经寻找其他可以实现这个功能的函数或方法,但是我只发现了live,但是自jQuery 1.7以来就已经被弃用了。是否还有其他可以使用的方法,或者我必须坚持使用这个解决方法?


4
使用事件委托,详见此处:http://api.jquery.com/on/。 - Kartikeya Khosla
你为什么没有在Google(或其他地方)搜索“jquery动态元素事件”之类的东西呢? - Regent
@Regent 我其实已经尝试过了,但所有的解决方案都不适用于我,但是嘿,与其抱怨我没有使用谷歌,你不如直接发布一个解决方案。 ;) - Realitätsverlust
1个回答

6

您可以将点击事件附加到已经存在的元素上,但只触发该元素的特定子元素。如下所示:

$('.sidebarElement').on('click', 'span', function() {
    //...
});

你可以在技术上将你的事件附加到 $('body'),只要第二个参数(这是一个jquery选择器)足够精确。虽然我不建议使用这种方法,因为它肯定会对性能产生负面影响。 请参考jquery的 .on() 函数

啊,现在我明白了,所以我将它附加到body上,但只有在.sidebarElement span上触发它,对吧?所以我的事件是$('body').on('click', '.sidebarElement span', function() {,我理解得对吗? - Realitätsverlust
没错,与主体一起工作。非常感谢! - Realitätsverlust
@Y U NO WORK: 永远不要在委托事件处理程序中使用'body'!如果没有更接近正在更改的元素,请使用document作为后备。与样式相关的body存在错误,这意味着事件(特别是点击)并不总是有效。 - iCollect.it Ltd
@TrueBlueAussie,这是哪个jQuery版本?这是一个已知的错误吗?我问这个问题是因为最近我遇到了有趣的事件处理程序行为(在对话框中聚焦元素时,blur()被触发并伴随着一个空的堆栈跟踪),它们的“角色被颠倒”,也就是说:事件处理程序附加到一个元素上,然后将其附加到body上。 - UweB
我在最近的jQuery版本中实践中发现了问题(不知道是否是官方问题),所以现在我总是优先使用document而不是bodydocument的额外好处是它存在于任何DOM加载之前。 - iCollect.it Ltd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接