无法弄清楚为什么这个小的jquery函数是递归的

时间:2017-06-20 16:16:57

标签: javascript jquery recursion append

所以我有这个小功能,只需在添加新的动态HTML片段时检查DOM,然后当鼠标输入图像时,我希望它在图像后追加<span>。它有效,但它追加9次而不是一次。我不能为我的生活找出原因。

编辑 - 同样,在每个后续追加操作时,它会追加它之前执行的数字的两倍。 (因此,第一个动作它会附加9次,第二个动作会附加18次,等等。)

TIA。

$(document).on('DOMNodeInserted', '.module', function(event) {
  $('.body-copy,.subhead,.lead-in,.blockquote,.disclosure-text,.caption,.link-text,.button,.cta').attr('contenteditable', 'true');
  $('img').mouseenter(function(event) {
     $(this).parent('td').append('<span class="image-link"><a class="fa-link fa"></span>');
     $(this).children('image-link').attr('hover', 'true');
  });

});

1 个答案:

答案 0 :(得分:0)

有两个主要部分可以解决您的问题:

  1. 您的.on("DOMNodeInserted", ...)可能会多次运行。
  2. 您的$("img").mouseenter(...)正在为页面上的每个图片运行,无论它何时到达。
  3. 每次将DOM节点添加到实时树时,都会调用该侦听器,包括侦听器本身添加的节点。

    正确的解决方案是将事件添加到现有节点,然后将相同的处理程序添加到添加的任何新<img>元素。像这样:

    // Factored out the listener for reuse
    function listener(e) {
        $(this).parent('td').append('<span class="image-link"><a class="fa-link fa"></span>');
        $(this).children('image-link').attr('hover', 'true');
    }
    
    // Add the listener to all existing images.
    $('img').on('mouseenter', listener);
    
    // Observe for any future image additions.
    new MutationObserver(function (record) {
        $(record.addedNodes).filter('img').on('mouseenter', listener);
        // Avoid memory leaks
        $(record.removedNodes).filter('img').off('mouseenter', listener);
    })
    .observe(document.body, {
        childList: true,
        subtree: true,
    });
    

    (我特意使用MutationObservers,因为Mutation Events API由于性能原因已经被弃用了很长时间,并且从未被浏览器完全和互操作地实现。此外,MutationObservers在此时具有相当广泛的兼容性。)