Функция jQuery вызывается дважды для каждого щелчка
Настройка:
Я написал функцию jQuery для обновления ячеек таблицы таблицы_2, когда нажата строка в таблице_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 меняются. НО, для каждого щелчка функция выполняется дважды. Я вижу окно предупреждения, появляющееся дважды для каждого щелчка.
Может кто-нибудь сказать мне, почему это происходит? И как этого избежать?
Ответы
Ответ 1
Любое из следующего:
- Выбранная строка находится внутри другой строки (нажаты две строки). (пример)
- Код, который вы показали, выполняется дважды (пример).
Чтобы решить эту проблему, сделайте свой селектор более конкретным. Если вы используете 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() {
Ответ 2
просто избегайте распространения щелчка
$("tr").live('click',function() {
...
$( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
});
Ответ 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);
});
Ответ 4
Это потому, что
$ ( "tr" ). live ('click', function() {}); ^^^^^ имеет 2 счета в html.
Чтобы обеспечить выполнение .live() или .delegate() один раз, селектор в $(selector).delegate() лучше быть "$ (table [name = users])", а не $('td') или $( 'тр')
Ответ 5
Некоторые элементы могут иметь одинаковые свойства (имя класса, имя тега и т.д.), которые вы можете игнорировать. Это может вызвать такой конфликт. В приведенном ниже примере элемент "tr" используется как селектор для предупреждения, но script имеет два вложенных элемента "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/