Нажатие кнопки на кнопке отправляет значок в качестве цели?

У меня проблема очень похожа на: "JQuery 'click' не стреляет, когда значок включен на кнопку" , однако разрешение для этого сообщения не дает решения для меня, поэтому я думаю, что что-то другое может продолжаться.

Существенная проблема заключается в том, что у меня есть кнопка с иконкой в ​​ней. Когда я нажимаю кнопку (например, текст), целью события является элемент кнопки; однако, когда я нажимаю на значок, целью события является объект значка. К сожалению, это очень раздражает, поскольку я храню данные на моей кнопке, к которой я хотел бы получить доступ.

Вот HTML:

<button class="btn btn-success vote-button" id="btnUpVote" type="button" data-vote="1">
    <i class="fa fa-thumbs-up"></i>
    Up Vote!
</button>

<button class="btn btn-danger vote-button" id="btnDownVote" type="button" data-vote="-1">
    <i class="fa fa-thumbs-down"></i>
    Down Vote!
</button>

И вот Javascript:

function sendVote(event) {
    var $btn = $(event.target);
    console.log(parseInt($btn.data('vote'));
    console.log($btn.prop('tagName'));
}

$('body').on('click', 'button.vote-button', sendVote);

Нажав на текст ( "Вверх Vote!" или "Down Vote!" ), вы получите следующий вывод консоли:

1
BUTTON
-1 
BUTTON

Нажатие на значок (и т.д.) приводит к следующему выводу консоли:

NaN
I
NaN
I

Несмотря на то, что я зарегистрировал дескриптор элементов с помощью кнопки "button.vote-button". Кто-нибудь знает, почему это происходит? Мне не хотелось бы предоставлять атрибуты данных значкам.

Ответ 1

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

Если проблема заключается в том, что вы просто хотите ссылаться на кнопку при каждом запуске кода, но вы все еще хотите, чтобы она срабатывала при нажатии на значок вместо текста, вам просто нужно использовать this, а не event.target:

var $btn = $(this);
...

jQuery будет следить за тем, чтобы this всегда ссылался на кнопку, даже если фактический элемент event.target является элементом внутри него.

Ответ 2

Использовать event.currentTarget, который всегда является объектом, слушающим событие; event.target - это реальная цель, которая получила событие, которое не является тем, что вы хотите в этом случае, поскольку это может быть значок.

С помощью event.currentTarget, если пользователь нажимает на значок, он пузырится событие до слушателя объекта, который является кнопкой в ​​вашем случае. Если пользователь нажимает кнопку, он все равно будет работать, потому что снова слушателем будет ваша кнопка.

Ответ 3

обновите это, потому что $(event.target) не всегда button для этого вам нужно использовать тройной оператор, как предлагается, или заменить $(event.target) на $(this), который всегда button в контексте селектора:

function sendVote(event) {
    event.stopPropagation(); 
    var $btn = $(event.target).is('button') ? $(event.target) : $(event.target).parent();
    console.log(parseInt($btn.data('vote')));
    console.log($btn.prop('tagName'));
}
$(function () {
    $('body').on('click','button.vote-button', sendVote);
});

Демо-скрипта


или с $(this), который всегда button, потому что событие привязано к нему, и если вы нажмете на любое его дочернее устройство, то event запустится до дерева dom, и событие, связанное с нажатием кнопки, будет выполнено:

function sendVote(event) {
    var $btn = $(this);  // <-----------------change just here
    console.log(parseInt($btn.data('vote')));
    console.log($btn.prop('tagName'));
}

Ответ 4

Как только проверка выполняется внутри функции, если тэг - это я, и если это так, получив родителя как ваш $btn. http://jsfiddle.net/jFIT/qZgYU/3/

$('body').on('click', 'button.vote-button', function() {
 var $btn = $(this).prop('tagName').toLowerCase() == "i" ? $(this).parent() : $(this);
 console.log(parseInt($btn.data('vote')));
 console.log($btn.prop('tagName'));
});

Ответ 5

Простое решение CSS:

button > * {
  pointer-events: none;
}