Функция jQuery click против встроенного onclick - PullRequest
10 голосов
/ 03 мая 2009

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

В основном, есть ссылка для выполнения действия. Если щелкнуть ссылку, действие выполняется с помощью 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>

Ответы [ 5 ]

16 голосов
/ 03 мая 2009

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

Для этого вы можете использовать .live.


Обновление

Начиная с jQuery 1.7, метод .on является предпочтительным способом сделать это.

Начиная с jQuery 1.9, метод .live был удален.

4 голосов
/ 03 мая 2009

Просто демонстрируем использование .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();
    });
});
2 голосов
/ 03 мая 2009

Вау !! Спасибо всем вам!

Я читал о прямом эфире, и окончательный рабочий код:

$(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 () для удаления текста, предлагающего выполнить действие. Я изменил его для скрытия / показа, поэтому мне не нужно использовать live в первой функции.

Еще раз спасибо!

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

Поскольку вы динамически добавляете новые элементы в DOM, вам придется снова зарегистрировать обработчик click для новых элементов. jQuery устанавливает обработчик при вызове $('...').click(...).

1 голос
/ 03 мая 2009

Обработчик щелчков не выбирается при добавлении элемента в 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;
});

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...