Замена элемента и возвращение нового в 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
просто останется там навсегда.
Есть ли способ вернуть элемент замены без его выбора?
Спасибо заранее.
Ответы
Ответ 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
});