2016-04-04 2 views
0

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

Вот фрагмент кода

JS

$('.detailTable').delegate('tr', 'click', function() { 
    console.log('clicked in row'); 
    $('#saveButton').click(function(event) { 
    console.log('clicked on button'); 
    return false; 
    }); 
}); 

HTML

<table class="detailTable"> 
    <tr> 
    <td>first</td> 
    <td> 
     <button id="saveButton"> 
     Save 
     </button> 
    </td> 
    </tr> 
</table> 

Working Fiddle

+0

Почему вы связываете событие внутри делегированного обработчика кликов? Также вы должны использовать '.on()' – Satpal

+0

FYI, вы действительно должны использовать '.on()' вместо '.delegate()', если вы не используете действительно старую версию jQuery. – jfriend00

+0

Я не могу использовать .on(), поскольку я использую jquery 1.6.4 –

ответ

1

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

Вопрос: у вас есть событие click, связанное с tr, которое, в свою очередь, связывает событие на button. Поэтому каждый раз, когда вы нажимаете на tr, он регистрирует новое событие, поэтому обратный вызов запускается для каждой регистрации. Если вы нажмете в tr 3 раза, то для button обратный вызов будет выполнен 3 раза.

По-моему, вы должны просто использовать обычные click события.


Вы можете сделать это:

$('.detailTable').delegate('tr', 'click', function() { 
    console.log('clicked in row'); 
}).delegate('#saveButton', 'click', function(e) { 
    console.log('clicked on button'); 
    return false; // does two things e.preventDefault() & e.stopPropagation() 
    // and this will stop the event to bubble up to the tr element. 
}); 
+0

Да, это точно проблема. Нет ли решений для этого без использования .on()? Я хочу, чтобы нажатие кнопки просто выполнялось. –

+0

Есть, подождите, я обновляю его. – Jai

+0

@UjwalRatra вы можете использовать его сейчас. – Jai

0

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

Чтобы получить строку из события нажатия кнопки, вы можете попробовать это:

$("#saveButton").click(function() { 
    var $item = $(this).closest("tr"); 
}); 
+1

Это не ответ. – Jai

+0

Мне не нужна строка из кнопки. –

+0

Затем просто используйте класс на кнопке и зарегистрируйте щелчок на каждой кнопке следующим образом: $ (". SaveButton"). Click (function() { // сделайте что-нибудь }); – janhamburg

0

Во-первых, вы не можете иметь несколько кнопок с одинаковыми идентификаторами. Это незаконный HTML и просто вызовет проблемы для селекторов. Вместо этого я бы предложил использовать имя класса.

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

Тогда, если вы используете действительно старую версию jQuery, вы должны использовать .on() вместо .delegate().

Итак, вот что я хотел бы предложить:

<table class="detailTable"> 
    <tr> 
    <td>first</td> 
    <td> 
     <button class="saveButton"> 
     Save 
     </button> 
    </td> 
    </tr> 
    <tr> 
    <td>first</td> 
    <td> 
     <button class="saveButton"> 
     Save 
     </button> 
    </td> 
    </tr> 
</table> 

Код:

// save button click handlers 
$('.detailTable').on('click', '.saveButton', function(e) { 
    // don't let button click handler propagate to the row 
    // you can remove this e.stopPropagation() line if you want 
    // a click to trigger both button and row click handlers 
    e.stopPropagation(); 
    console.log('clicked on save Button'); 
}); 

// row click handlers 
$('.detailTable').on('click', 'tr', function() { 
    console.log('clicked in row'); 
}); 

Работа демо: https://jsfiddle.net/jfriend00/hy69py9m/


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

+0

Я не использую несколько кнопок с одинаковым идентификатором, фрагмент был всего лишь образцом. То, что я точно делаю, - каждый раз, когда я нажимаю строку, я добавляю id с соответствующей кнопкой сохранения в этой строке. Теперь всякий раз, когда я нажимаю кнопку «Сохранить», я хочу, чтобы она срабатывала один раз, но она срабатывает (количество раз подряд нажимается + один раз). –

+0

@UjwalRatra - Прекратить привязку нового обработчика кликов для кнопки КАЖДЫЙ раз, когда щелкнет строка. Это проблема. Если вы хотите получить более подробную информацию о том, как еще решить вашу проблему, вам придется больше узнать о проблеме. Но причина, по которой вы получаете несколько обработчиков кнопок, заключается в том, что вы устанавливаете несколько обработчиков кликов. – jfriend00

+0

@UjwalRatra - Единственная причина, по которой здесь можно использовать делегированную обработку событий, - это динамическое добавление элементов в таблицу. Если вы этого не делаете, тогда нет причин использовать делегированную обработку событий. Вы можете просто использовать статическую обработку событий с прямыми селекторными совпадениями. Поскольку вы не показываете нам настоящую проблему, которую вы пытаетесь решить с помощью этого кода, мы не знаем, что еще предложить. – jfriend00

0

Я не получить то, что ваш вопрос, но некоторые замечания:

Я сделал это Fiddle с вашим кодом и некоторые умеренные редактирует.

Отделив прослушиватель событий (тот, у которого есть кнопка) внутри другого (тот, у кого есть строка), необходимо сначала нажать на строку (или на кнопку, потому что она находится в строке) только после что событие на кнопке будет прослушиваться.

Если у вас несколько строк, вам нужно не использовать один и тот же идентификатор для каждой кнопки. В скрипке я использовал имя класса, которое решает эту проблему.

я предлагаю использовать два отдельных слушателей:

$('.detailTable tr').click(function() { 
    console.log('clicked in row'); 
}); 

$('.detailTable tr .saveButton').click(function(event) { 
    console.log('clicked on button'); 
    event.stopPropagation(); 
}); 

event.stopPropagation() (jQuery api) предотвращает щелчок на пузырьке до строки так, при нажатии на кнопку в строке не будет нажата.

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