Подтвердить что ты не робот

Замена элемента и возвращение нового в jQuery

Как заменить элемент в jQuery и вернуть элемент замены вместо удаляемого элемента?

У меня есть следующий сценарий. У меня много флажков, и как только вы нажмете один из них, этот флажок заменяется значком загрузки. Как только происходит какое-то действие AJAX, значок загрузки заменяется значком галочки.

Используя jQuery 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'/>"); 

});

Однако это не работает, потому что replaceWith возвращает удаленный элемент, а не тот, который был добавлен. Итак, после завершения работы AJAX, loading.jpg просто останется там навсегда.

Есть ли способ вернуть элемент замены без его выбора?

Спасибо заранее.

4b9b3361

Ответ 1

Дайте загрузочному изображению класс, затем в обратном вызове 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'/>");
  });
});

Если у вас может быть несколько из них за один раз, вы можете получить ближайший родительский элемент this и использовать его в качестве контекста при поиске класса.

EDIT. Еще одна альтернатива, использующая переменную для хранения нового элемента и устраняющая необходимость применения класса и поиска нового элемента при возврате функции.

$("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'/>");
  });
});

Ответ 2

Создайте элемент и используйте его как параметр для заменыWith:


$('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"/>');
    });
});

Ответ 3

Вы можете присвоить ему уникальный идентификатор, используя индекс:

$("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'/>"); 

});

Ответ 4

Причина, по которой ваш код не работает, заключается в том, что первый replaceWith заменяет элемент, на который ссылается this. Вторая replaceWith пытается заменить ее снова, но поскольку она уже ушла, заменить ничего не стоит. И значок галочки не будет отображаться.

Лучше всего использовать функцию обратного вызова, которую предлагает tvanfosson.

Ответ 5

Проверьте это.

$.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');

Ответ 6

Я написал небольшой плагин для достижения аналогичного результата, потому что мне нравится получать указатель на новый элемент в одной строке кода.

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

Пример использования:

$("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'/>");
    });
});

Ответ 7

Если нет необходимости специально использовать метод replaceWith - вы можете использовать метод replaceAll, который является противоположным replaceWith.

См. ответ здесь: (ответ на аналогичный вопрос, заданный через год) replaceAll заменяет каждый элемент в объекте, переданном как параметр или элементы, соответствующие переданному селектору, в качестве параметра с согласованными элементами и возвращает согласованные элементы (новый контент).

Таким образом, редактирование в ответе 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'/>");
    });
});

Это только строка короче, но для краткости и включения опции replaceAll() я счел нужным добавить этот ответ к этому старому и более просматриваемому вопросу.

Ответ 8

Почему бы не создать промежуточный объект 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
});