2012-05-06 5 views
11

установки:функция JQuery вызывается дважды за каждый клик

Я написал функцию JQuery для обновления таблицы ячеек table_2, когда строка table_1 нажата. Вот что я написал:

<script type="text/javascript"> 
     $("tr").live('click',function() { 
      var host = $(this); 
      alert('A row in table 1 is clicked!'); 

      var count = host.find("td").eq(2).text(); 
      $("#myTable_2 tr:eq(0) td:eq(1)").text(count); 
      $("#myTable_2 tr:eq(1) td:eq(1)").text(5); 
     }); 
    </script> 

Проблема:

Когда я шаг через эту функцию с помощью FireBug, я могу видеть данные ячейки в myTable_2, изменяется. НО, для каждого щелчка функция выполняется дважды. Я вижу окно предупреждения, появляющееся дважды для каждого щелчка.

Может кто-нибудь сказать мне, почему это происходит? И как этого избежать?

ответ

11

В любом из следующих действий:

  1. в момент щелчка строка находится внутри другой строки (две строки щелкнул). (example)
  2. Код, который вы указали, исполняется дважды (example).

Чтобы решить эту проблему, сделайте свой селектор более конкретным. Если вы используете JQuery 1.7+, используйте .on вместо live: http://jsfiddle.net/6UmpY/3/

$(document).on("click", "#myTable_1 > tbody > tr", function() { 
    // This selector will only match direct rows of the myTable_1 table 

Примечание: Использование .on вместо live не решить эту проблему.
Использование более конкретного селектора сделал исправить проблему.
Если вы любите live следующее будет также работать: http://jsfiddle.net/6UmpY/4/

$("#myTable_1 > tbody > tr").live("click", function() { 
3

предположить table_1 это идентификатор первой таблицы.

$("#table_1 tbody").on('click','tr', function() { 
      var host = $(this); 
      alert('A row in table 1 is clicked!'); 

      var count = host.find("td").eq(2).text(); 
      $("#myTable_2 tr:eq(0) td:eq(1)").text(count); 
      $("#myTable_2 tr:eq(1) td:eq(1)").text(5); 
     }); 

Примечание:live() устарела, так что писать, как и выше. вы выполняете код дважды, потому что переключатель tr принадлежит двум таблицам и привязке событий дважды.

Вы можете также использовать delegate():

$("#table_1 tbody").delegate("tr", "click", function(){ 
    var host = $(this); 
    alert('A row in table 1 is clicked!'); 
    var count = host.find("td").eq(2).text(); 
    $("#myTable_2 tr:eq(0) td:eq(1)").text(count); 
    $("#myTable_2 tr:eq(1) td:eq(1)").text(5); 
}); 
+0

Спасибо за ответ. Значит, вы имеете в виду, что использование «on» или «delegate» решит проблему вызова функции дважды? – Bhushan

+0

@Learner no 'on()' используется для привязки события из jquery 1.7+, и дважды огонь события будет решаться с помощью '# table_1', потому что он выберет только' tr', который принадлежит первой таблице – thecodeparadox

+0

, благодаря thecodeparadox. – Bhushan

12

просто избежать распространения щелчку

$("tr").live('click',function() { 

     ... 

     $(event.toElement).one('click', function(e){ e.stopImmediatePropagation(); }); 
    }); 
+0

Есть ли потенциальные негативные последствия этого? –

+1

Это останавливает все остальное, слушая событие на элементе, получающем событие. События вызываются в том порядке, в котором они добавлены, и только события, добавленные после этого, будут предотвращены. – neopickaze

0

Это потому, что $ ("тр") жить ('нажмите', функция.() {}); ^^^^^ имеет 2 счета в html. Чтобы обеспечить выполнение .live() или .delegate() один раз, селектор в $ (selector) .delegate() лучше быть «$ (table [name = users])», а не $ ('td'). или $ ('tr')

0

Некоторые элементы могут иметь одинаковые свойства (имя класса, название тега и т. д.), которые вы можете игнорировать. Это может вызвать такой конфликт. В приведенном ниже примере элемент «tr» используется как селектор для предупреждения, но сценарий имеет два вложенных элемента «tr», которые содержат «текстовую» цель.Таким образом, одним щелчком мыши вы получаете предупреждение для каждого (изнутри наружу) элемента «tr» отдельно. Это называется bubbling. Вы можете просто использовать stopPropogation(), чтобы остановить bubbling.

$("tr").live('click',function() { 
    alert('A row in table 1 is clicked!'); 
    event.stopPropogation(); 
}); 

<table> 
    **<tr>** 
    <td>  
     <table id="myTable_1"> 
     **<tr>** 
     <td>Test</td> 
     **</tr>** 
     </table> 
    </td> 
    **</tr>** 
</table> 

http://jsfiddle.net/6UmpY/97/

Смежные вопросы