Замена элемента и возвращение нового в jQuery - PullRequest
24 голосов
/ 21 мая 2009

Как вы заменяете элемент в 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 останется там навсегда.

Можно ли как-нибудь вернуть заменяющий элемент, не выбрав его?

Заранее спасибо.

Ответы [ 8 ]

22 голосов
/ 21 мая 2009

Присвойте загрузочному изображению класс, затем в обратном вызове поста используйте класс в качестве селектора, чтобы найти изображение, которое вы только что ввели.

$("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'/>");
  });
});
13 голосов
/ 21 мая 2009

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


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

2 голосов
/ 21 мая 2009

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

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

});
0 голосов
/ 09 мая 2016

Если нет необходимости специально использовать метод 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 (), которую я счел целесообразным добавить этот ответ к этому старому и более просматриваемому вопросу.

0 голосов
/ 20 августа 2013

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

(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'/>");
    });
});
0 голосов
/ 26 марта 2012

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

$.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');
0 голосов
/ 21 мая 2009

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

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

0 голосов
/ 21 мая 2009

Почему бы не создать промежуточный объект 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
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...