2009-05-02 3 views
10

Я пытаюсь реорганизовать свой код и сделать его более ненавязчивым.Функция jQuery click vs inline onclick

В основном, есть ссылка для совершения действия. Если вы нажмете на ссылку, действие выполняется через ajax (здесь код ajax отсутствует здесь), а текст заменяется другим текстом, предлагая пользователю возможность отменить действие. Если пользователь нажимает ссылку «Отменить», ajax восстанавливает предыдущую ситуацию и текст, предлагающий пользователю выполнить действие, которое оно показано снова.

Я сделал более простой вариант своей проблемы в одном html-файле (код ниже). Есть два абзаца. Если вы нажмете на ссылку первого абзаца, в которой используется встроенный вызов onclick, код работает так, как ожидалось. Но если вы нажмете ссылку второго абзаца, в которой используется функция jQuery onclick, ссылка Undo не работает, и я не могу понять, почему.

Любая помощь? Большое спасибо!

<!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> 

ответ

15

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

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


Обновление

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

С jQuery 1.9 метод .live удален.

+0

Живая будет работать только тогда, когда селектор находится точно такой же. В этом случае я считаю, что селектор уникален для каждого элемента DOM. – tvanfosson

+0

Спасибо @wolfr. Я не знал, что это существовало. –

+0

Отличный ответ. Я знал, что мой js-код работал, но не мог понять, что происходит ... после прочтения вашего ответа я понял, что привязываюсь к привязным тегам, представленным через asp.net mvc webgrid ... снова, спасибо за помощь @Wolfr –

2

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

1

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

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

2

Ничего себе !! Всем спасибо!

Я прочитал о живом турнире и окончательный рабочий код:

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

Ранее я использовал удалить() для удаления текста, который предлагает выполнить действие. Я изменил его для hide/show, поэтому мне не нужно использовать live также в первой функции.

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

4

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