web-dev-qa-db-ja.com

ボタンのクリックイベントは、ターゲットとしてアイコンを送信していますか?

私は非常によく似た問題を抱えています: "アイコンがボタンにあるときにJquery 'クリック'が起動しない" しかし、その投稿の解像度は私に解決策を提供していないので、何か違うかもしれないと思います起こっています。

本質的な問題は、アイコンが入ったボタンがあることです。ボタン(テキストなど)をクリックすると、イベントターゲットはボタン要素になります。ただし、アイコンをクリックすると、イベントターゲットはアイコンオブジェクトになります。残念ながら、アクセスしたいボタンにデータ値を保存しているので、これは非常に面倒です。

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);

テキスト(「賛成票!」または「反対票!」)をクリックすると、次のコンソール出力が表示されます。

1
BUTTON
-1 
BUTTON

アイコン(など)をクリックすると、次のコンソール出力が表示されます。

NaN
I
NaN
I

セレクター「button.vote-button」で要素のハンドルを登録しましたが。なぜこれが起こっているのか誰かが知っていますか?アイコンにデータ属性を指定する必要はありません。

20
bbengfort

これは、イベントの伝播が原因です。ボタンの内側にあるアイコンをクリックすると、clickイベントがDOMを介してアイコンからボタンに、そしてドキュメントに至るまで伝播します。これにより、clickイベントハンドラコードが実行されます。

コードが実行されるたびにボタンへの参照が必要であるが、テキストではなくアイコンをクリックしたときにボタンをトリガーすることが問題である場合は、ではなくthisを使用する必要があります。 event.target

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

jQueryは、実際のevent.target要素がボタン内の要素であっても、thisが常にボタンを参照するようにします。

5
Anthony Grist

使用する event.currentTargetこれは常にイベントをリッスンするオブジェクトです。 event.targetは、イベントを受信した実際のターゲットですが、アイコンである可能性があるため、この場合は必要ありません。

event.currentTargetユーザーがアイコンをクリックすると、イベントがオブジェクトリスナー(この場合はボタン)にバブルされます。ユーザーがボタンをクリックしても、オブジェクトリスナーがボタンであるため、引き続き機能します。

43
Han

$(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'));
}
_
1
Jai

タグ名がIであるかどうかを関数内でチェックし、そうである場合は、親を$ 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'));
});
0
JF it

シンプルなCSSソリューション:

button > * {
  pointer-events: none;
}
0
BlueStory