javascript - jQueryeach与replaceWith结合问题

标签 javascript jquery dom each replacewith

我试图用一个类循环遍历每个元素,然后用 div 包装它,然后继续下一个。

目前正在使用这个...

$('.img-editable').each(function(i) {
    if ($(this).prop("tagName") == "IMG") {
        $(this).replaceWith('<span class="img-edit-container">'+this.outerHTML+'<button class="btn btn-default btn-sm img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
    } else {
        $(this).replaceWith('<span class="img-edit-container bg-img-edit-container">'+this.outerHTML+'<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
    }
});

它适用于简单的情况。但挑战是当存在像这样的嵌套元素时......

    <div class="img-editable>
        <div id="something else">
            <div class="img-editable"></div>
        </div>
    </div>

然后它就会分崩离析,内部元素无法正确包裹。

我的信念是 each() 函数正在循环最外层的元素,当它与第一个元素匹配时,它会执行 replaceWith() 然后继续。但是,当循环到达下一个(内部)时,对匹配的第二个内部元素的引用不再存在(根据浏览器)。

我也尝试过这个...

var setupImgWrapper = function(elem) {
    if (elem.prop("tagName") == "IMG") {
        elem.replaceWith('<span class="img-edit-container">'+this.outerHTML+'<button class="btn btn-default btn-sm img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
        elem.children('.img-edtiable').each(function(i) {
            setupImgWrapper($(this));
        });
    } else {
        elem.replaceWith('<span class="img-edit-container bg-img-edit-container">'+this.outerHTML+'<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
        elem.children('.img-edtiable').each(function(i) {
            setupImgWrapper($(this));
        });
    }
}

$('.img-editable').each(function(i) {
    setupImgWrapper($(this));
});

这完全失败了。

我很想知道我们如何克服这个问题?有没有办法在执行 replaceWith() 后维护 DOM 引用,或者我们可以更新它吗?

TL;DR 在所选元素上循环执行 replaceWith 后,后代元素引用似乎中断,并且这些元素未成功更新。

谢谢!

<小时/>

下面接受的解决方案

$('.img-editable').each(function(i) {
    if ($(this).prop("tagName") == "IMG") {
        $(this).wrap('<span class="img-edit-container"></span>');
        $(this).after('<button class="btn btn-default btn-sm img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button>');
    } else {
        $(this).wrap('<span class="img-edit-container bg-img-edit-container"></span>');
        $(this).after('<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button>');
    }
});

最佳答案

有一个.wrap() jQuery 提供的方法完全满足您的需要。

这是一个演示

$('body > div').each(function() {
  $(this).wrap('<div class="wrapper" />');
});
.wrapper {
  border: 1px solid tomato;
  margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>Normal Element</div>

<div>
  <span>Simple inline element</span>
</div>

<div>
  <div>
    <h1>More Stuff</h1>
  </div>
</div>

如果 .img-editable > ... > .img-editable 破坏了您的代码,您应该更喜欢一个更适合您需求的选择器。我可以帮助您,只需对此答案发表评论,我们就会解决问题。 :)

关于javascript - jQueryeach与replaceWith结合问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43065655/

相关文章:

javascript - sessionStorage 什么时候真正被清除了?

javascript - 如果选中复选框,则激活字段

javascript - 将类应用于 jquery 中的动态元素

jquery - 所需的字符串参数 'userName' 不存在

firefox - 从 Firefox 扩展在浏览器中加载动态创建的文档

javascript - 使用 Jquery 获取与条件匹配的第一个前一个元素

javascript - 如何调用嵌入到 HTML 元素中的脚本

javascript - 了解 IIFE

javascript - 无法将待办事项存储到本地存储

c# - 使用 javascript 从另一个按钮触发单击按钮事件