Функция jQuery click против встроенного onclick
Вопрос
Я пытаюсь реорганизовать свой код и сделать его более ненавязчивым.
В основном, там есть ссылка для выполнения действия.Если вы нажмете на ссылку, действие будет выполнено через ajax (код ajax здесь отсутствует в коде), и текст будет заменен другим текстом, предлагая пользователю возможность отменить действие.Если пользователь нажимает на ссылку Отменить, ajax восстанавливает предыдущую ситуацию, и текст, предлагающий пользователю выполнить действие, отображается снова.
Я создал более простую версию своей проблемы в одном html-файле (код ниже).Там есть два абзаца.Если вы нажмете на ссылку первого абзаца, в котором используется встроенный вызов onclick, код будет работать так, как ожидалось.Но если вы нажмете на ссылку второго абзаца, в котором используется функция jQuery onclick, ссылка отмены не сработает, и я не могу понять почему.
Какая-нибудь помощь?Большое спасибо!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title></title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function() {
$(".add2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .add2").remove();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>");
return false;
})
$(".undoadd2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .actions").find("span.added, a.add2").remove();
$("#" + placeId + " .actions").append("<a class='add2' onclick='copyPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>");
return false;
})
});
function addPlace(placeId){
$("#" + placeId + " .add").remove();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>");
return false;
}
function undoAddPlace(placeId){
$("#" + placeId + " .actions").find("span.added, a.undoadd").remove();
$("#" + placeId + " .actions").append("<a class='add' onclick='addPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>");
return false;
}
</script>
</head>
<body id="home">
<div class="place" id="3435910">
<p class="actions"><a href="#" onclick="addPlace('3435910'); return false;" class="add">Add place</a></p>
</div>
<div class="place" id="3435912">
<p class="actions"><a href="#" class="add2">Add place</a></p>
</div>
</body>
</html>
Решение
Поскольку вы динамически добавляете новые элементы в DOM, вам нужно будет снова зарегистрировать обработчик кликов для новых элементов.
Вы можете использовать .live
для этого.
Обновить
Начиная с jQuery 1.7, .on
метод является предпочтительным способом сделать это.
Начиная с jQuery 1.9, .live
метод был удален.
Другие советы
Просто демонстрируем использование .end () для более гибкого решения:
$(function() {
$(".add2").click(function(){
return $(this).parents(".place")
.find(".add2")
.hide()
.end()
.find(".actions")
.append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>");
});
$('.undoadd2').live('click', function(){
return $(this).parents(".place")
.find(".actions")
.find("span.added, a.undoadd2")
.remove()
.end()
.end()
.find(".add2")
.show();
});
});
Поскольку вы динамически добавляете новые элементы в DOM, вам придется снова зарегистрировать обработчик click
для новых элементов. jQuery устанавливает обработчик при вызове $ ('...'). click (...)
.
Ух ты!!Спасибо всем вам!
Я читал о живом событии, и окончательный рабочий код таков:
$(function() {
$(".add2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .add2").hide();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>");
return false;
})
$('.undoadd2').live('click', function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .actions").find("span.added, a.undoadd2").remove();
$("#" + placeId + " .add2").show();
return false;
});
Ранее я использовал remove() для удаления текста, предлагающего выполнить действие.Я изменил его на hide / show, поэтому мне не нужно использовать live также в первой функции.
Еще раз спасибо!
Обработчик щелчка не распознается, когда вы добавляете элемент в DOM.Попробуйте использовать jQuery для регистрации обработчика кликов, изменив строки, которые выглядят следующим образом:
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>")
Для
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" >Undo</a>");
$('#' + placeId + " .actions").find("span:last").find("a").click( function() {
undoAddPlace( placeId );
return false;
});
Возможно, вы могли бы сделать это проще, но, похоже, вы могли бы добавить к абзацу более одного интервала, поэтому я пошел консервативнее.Вероятно, вы также могли бы отключить добавление по цепочке, но я подумал, что повторный выбор прояснил суть.