在 jQuery 中替换元素并返回新元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/892861/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 10:03:38  来源:igfitidea点击:

Replacing an element and returning the new one in jQuery

jqueryreplace

提问by Philip Morton

How do you replace an element in jQuery and have the replacement element returned instead of the element that was removed?

如何替换 jQuery 中的元素并返回替换元素而不是被删除的元素?

I have the following scenario. I have many checkboxes and once you click one of them, that checkbox is replaced by a loading icon. Once some AJAX stuff happens, the loading icon is replaced by a tick icon.

我有以下场景。我有很多复选框,一旦您单击其中一个,该复选框就会被加载图标替换。一旦发生了一些 AJAX 问题,加载图标就会被一个勾号图标取代。

Using jQuery's replaceWith, you'd do something like:

使用 jQuery's replaceWith,您可以执行以下操作:

$("input[type='checkbox']").click(function() {

  $(this).replaceWith("<img src='loading.jpg' alt='loading'/>");
  $.post("somepage.php");
  $(this).replaceWith("<img src='tick.jpg' alt='done'/>"); 

});

However, this doesn't work because replaceWithreturns the element that was removed, not the one which was added. So after the AJAX stuff completes, loading.jpgwill just stay there forever.

但是,这不起作用,因为replaceWith返回的是被删除的元素,而不是被添加的元素。所以在 AJAX 的东西完成后,loading.jpg将永远留在那里。

Is there some way I can return the replacement element without selecting it?

有什么方法可以在不选择它的情况下返回替换元素?

Thanks in advance.

提前致谢。

采纳答案by tvanfosson

Give the loading image a class, then in the post callback, use the class as a selector to find the image you've just injected.

给加载图像一个类,然后在post回调中,使用该类作为选择器来查找您刚刚注入的图像。

$("input[type='checkbox']").click(function() {
  $(this).replaceWith("<img src='loading.jpg' alt='loading' class='loading-image' />");
  $.post("somepage.php", function() {
      $('.loading-image').replaceWith("<img src='tick.jpg' alt='done'/>");
  });
});

If you may have several of these running at a time, you can get the closest parent of thisand use that as the context when searching for the class.

如果您可能同时运行其中的几个,您可以获取最接近的父级this并将其用作搜索类时的上下文。

EDIT: Another alternative that uses a variable to store the new element and removes the need to apply the class and search for the new element when the function returns.

编辑:另一种使用变量来存储新元素的替代方法,并消除了在函数返回时应用类和搜索新元素的需要。

$("input[type='checkbox']").click(function() {
  var loading = $("<img src='loading.jpg' alt='loading' />");
  $(this).replaceWith(loading);
  $.post("somepage.php", function() {
      loading.replaceWith("<img src='tick.jpg' alt='done'/>");
  });
});

回答by Keeper

Create an element and use it as parameter to replaceWith:

创建一个元素并将其用作replaceWith的参数:


$('input[type=checkbox]').click(function() {
    var img = document.createElement('img');
    img.src = 'loading.jpg';
    $(this).replaceWith(img);
    $.post('somepage.php', function() {
        $(img).replaceWith('<img src="tick.jpg" alt="done"/>');
    });
});

回答by Jose Basilio

You could give it a unique id using the index:

你可以使用索引给它一个唯一的 id:

$("input[type='checkbox']").click(function() {
  var index = $("input[type='checkbox']").index(this);
  $(this).replaceWith("<img src='loading.jpg' id='myLoadingImage" + index + "' alt='loading'/>");
  $.post("somepage.php");
  $('#myLoadingImage'+index).replaceWith("<img src='tick.jpg' alt='done'/>"); 

});

回答by Mario Menger

The reason your code doesn't work is that the first replaceWithreplaces the item that thisrefers to. The second replaceWithattempts to replace it again, but since it is already gone, there is nothing to replace. And the tick icon won't get shown.

您的代码不起作用的原因是第一个replaceWith替换了this所指的项目。第二个replaceWith尝试再次替换它,但由于它已经消失了,所以没有什么可以替换的。并且不会显示勾号图标。

Your best bet is to use the post callback function that tvanfosson suggests.

最好的办法是使用 tvanfosson 建议的后回调函数。

回答by mr_app

Check this.

检查这个。

$.fn.replaceWithMod = function(obj) {
var $a = $(obj);
this.replaceWith($a);
return $a;  
};

var newObj  = $('a').replaceWithMod('<div>New Created Object</div>');
$(newObj).css('color','green');

回答by MjrKusanagi

I wrote a little plugin to achieve a similar result because I like to be able to retrieve a pointer for the new item in one line of code.

我写了一个小插件来实现类似的结果,因为我喜欢能够在一行代码中检索新项目的指针。

(function($){
    $.fn['overwrite'] = function(target){
        $(target).replaceWith(this);
        return this;
    }
}(jQuery));

Usage example:

用法示例:

$("input[type='checkbox']").click(function() {
    var $loading = $("<img src='loading.jpg' alt='loading' class='loading-image' />").overwrite( this );
    $.post("somepage.php", function() {
        $loading.replaceWith("<img src='tick.jpg' alt='done'/>");
    });
});

回答by et_l

If there isn't a necessity to use specifically the replaceWith method - you could use the replaceAll method which is the opposite to replaceWith.

如果没有必要专门使用 replaceWith 方法 - 您可以使用与 replaceWith 相反的 replaceAll 方法。

See the answer here: (answer to a similar question asked a year later)replaceAll replaces each element in the object passed as the parameter or the elements matching the passed selector as the parameter with the matched elements and returns the matched elements (the new content).

看到这里的答案:(回答一年后提出的类似问题)replaceAll 将作为参数传递的对象中的每个元素或与作为参数传递的选择器匹配的元素替换为匹配的元素并返回匹配的元素(新内容)。

That way, the edit in tvanfosson's answer (and the code at Keeper's answer) would look like this:

这样,tvanfosson 的答案(以及 Keeper 的答案中的代码)中的编辑将如下所示:

$("input[type='checkbox']").click(function() {
    var loading = $("<img src='loading.jpg' alt='loading' />").replaceAll($(this));
    $.post("somepage.php", function() {
        loading.replaceWith("<img src='tick.jpg' alt='done'/>");
    });
});

It's only a line shorter but for brevity and to include the option to use replaceAll() I saw fit to add this answer to this old and more-viewed question.

它只是更短的一行,但为了简洁起见,并包含使用 replaceAll() 的选项,我认为适合将此答案添加到这个旧的和更多人查看的问题中。

回答by belugabob

Why not make an intermediate jquery object, like this?...

为什么不制作一个中间 jquery 对象,像这样?...

$("input[type='checkbox']").click(function() {
    var insertedElement = $("<img src='loading.jpg' alt='loading'/>");
    $(this).replaceWith(insertedElement);
    $.post("somepage.php");
    var anotherInsertedElement = $("<img src='tick.jpg' alt='done'/>");
    $(this).replaceWith(anotherInsertedElement);
    //do something with either of the inserted elements
});