【问题标题】:jQuery returns prevObject....sometimesjQuery 有时会返回 prevObject....
【发布时间】:2015-05-07 12:50:05
【问题描述】:

我正在尝试使用 jQuery 从 DOM 中删除一个项目,有时会得到一个 prevObject 而不是一个元素。我知道当没有找到元素时会返回 prevObject,如here 解释的那样

我创建了一个单页应用程序,它以两种不同的方式将元素添加到播放列表中,一种是通过拖放,另一种是通过按下按钮。两种方式都调用同一个函数,传入相关信息。

当我点击一个已被拖放的元素的移除按钮时,它被成功移除,但任何通过该按钮添加到播放列表的项目都不会被移除,因为 prevObject 是由 jQuery 返回的。

项目can be found here如果你需要好好看看。

HTML(来自 chrome 开发工具)

顶部项目已被拖放,第二个通过按钮。

<aside class="col-sm-12 ui-sortable" id="sortable">
    <article class="dropped" id="2">
        <img src="http://img.youtube.com/vi/gnbLLQwZxeA/mqdefault.jpg" alt="Put social back in social media">
        <h3>Put social back in social media</h3>
        <div class="clearfix"></div>
        <a href="#" title="Remove item" id="remove2"><i class="fa fa-minus-circle"></i></a>
    </article>
    <article class="dropped" id="3">
        <img src="http://img.youtube.com/vi/ccFLVPNBRE4/mqdefault.jpg" alt="jQuery Performance Myths and Realities">
        <h3>jQuery Performance Myths and Realities</h3>
        <div class="clearfix"></div>
        <a href="#" title="Remove item" id="remove3"><i class="fa fa-minus-circle"></i></a></article>
    // more items here
</aside>

将项目添加到播放列表的功能

var addToPlayList = function(title, image, id){
    var playlistItem = '';
    playlistItem += '<article class="dropped" id="' + id + '">';
    playlistItem += '<img src="' + image + '" alt="' + title + '">';
    playlistItem += '<h3>' + title + '</h3>';
    playlistItem += '<div class="clearfix"></div>';
    playlistItem += '<a href="#" title="Remove item" id="remove' + id +'"><i class="fa fa-minus-circle"></i></a>';
    playlistItem += '</article>';

    $(playlistItem).insertBefore('.droppable');

    $('.playlist #remove' + id).click(function(ev) {
        removePlaylistItem(id);
    });
    fixClearfix();
}

从播放列表中删除项目的功能

var removePlaylistItem = function(id){
    var itemToRemove = $('aside article#' + id);
    console.log(itemToRemove); // returns prev object for items added by button
    itemToRemove.remove();

    var video = findVideoByID(id);
    displayVideo(video, id);
    fixClearfix();
}

非常感谢任何帮助

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

    如果您完全指定您的 jQuery 选择器,(即将'aside article#' + id 更改为'aside article[id=' + id + ']' 它应该可以工作。

    我注意到的另一个问题是,当视频被拖动时,它们会从主列表中删除。当它们通过按钮添加时,它们不是。

    【讨论】:

    • 你太棒了 :) 感谢您的回答和错误报告。
    • 没问题。如果我找出发生这种情况的原因,我会发表评论。我一直认为$('#a')$('[id=a]') 是等价的。
    • 哦,想通了。它与另一个错误有关。当您通过按钮添加它时,视频不会从主列表中删除,它的 id 也等于索引。然后,当您尝试使用 remove 方法中的快捷语法进行选择时,它不会返回任何内容,因为它遇到了页面上具有相同 id 的两个元素。选择器的简写版本更宽容(但它也可能选择了错误的元素)。
    • 真正的解决办法是确保 ID 不会重复 - 否则它不是合法的 HTML。
    • @user1403582 感谢您花时间进一步研究。通过按钮将视频从网格中删除后,原始选择器可以正常工作。具有讽刺意味的是,我留下了重复的视频错误,直到我弄清楚了选择问题:)
    【解决方案2】:

    考虑将 ID 作为 data 属性存储在 &lt;article&gt; 元素上,而不是使用数字 ID 和(非法)重复 ID:

    <article data-id="1" ...>
    

    然后,在删除按钮上,实际上根本不需要 ID,更好的是,您可以使用委托事件处理程序,该处理程序将处理所有条目,无论何时添加:

    $('.playlist').on('click', '.remove', function(ev) {
        var id = $(this).closest('article').data('id');
        removePlaylistItem(id);
    });
    

    从而避免必须为列表中的每篇文章动态注册单独的事件处理程序。请注意,remove 链接现在只有一个类(因为每个此类链接都被同等对待)`,它通过查看其祖先来计算 ID。

    您的removePlaylistItem 函数需要一点 工作才能与上述功能一起工作,但是在click 处理程序中,您已经知道要删除哪个元素,因此您不应该真的必须遍历 DOM 才能再次找到它。

    【讨论】:

    • 欣赏答案。随着另一个答案中的错误修复,页面上永远不会有两个元素具有相同的 id,因为我在其他地方使用了 data 和 name 属性。我将按照您的建议使用委托事件处理程序,以防止重复调用 DOM。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    相关资源
    最近更新 更多