web-dev-qa-db-ja.com

マウスアップイベントがクリックイベントを防ぐことができないのはなぜですか

jsfiddle

<div class='wrapper'>
    <button class='child'>Click me</button>
</div>

function h(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    alert(e.type);
    return false;
}

document.querySelector('.wrapper').addEventListener('mouseup', h, false);
document.querySelector('.child').addEventListener('click', h, false);

これにより、「クリック」イベントが発生しないようになると思いますが、そうではありません。ただし、mouseupmousedownに変更すると、実際にはクリックイベントが防止されます。

また、useCapture引数をtrueに設定しようとしましたが、これもmouseupで目的の動作を生成しません。私はこれをChromeとFirefoxでテストしました。バグを報告する前に、ここで質問すると思いました。

これは現在のブラウザのバグですか、それとも文書化された動作ですか?

W3C標準(DOMレベル2) を確認しましたが、この動作を説明できるものは見つかりませんでしたが、何かを見逃した可能性があります。

私の特定のケースでは、同じ要素のイベントをリッスンする2つのコードを分離しようとしています。これを解決するには、優先度の高い部分でキャプチャイベントを使用するのが最もエレガントな方法であると考えましたが、この問題に。 FWIW、公式にサポートされているバージョンのFFとChrome(FFのESRを含む)のみをサポートする必要があります。

14
beatgammit

このquirksmodeの記事をチェックしてください

clickイベント:

同じ要素でmousedownイベントとmouseupイベントが発生したときに発生します。

したがって、マウスクリックを離すと、mouseupイベントとclickイベントの両方が発生し、clickmouseupコールバックが終了するのを待ちません。ほとんどの場合、mouseupclickは同義語として使用できます。

clickをキャンセルするには、デモのように、falseイベントコールバックでmousedownを返すことができます。これにより、clickイベントが完了しなくなります。

2
Joseph Spens

Joseph Spensが言ったように、マウスダウンをキャンセルすると、クリックイベントがトリガーされなくなります

function log(msg){
    logBox.innerHTML += '<li>' + msg + '</li>'
}

function onMousedown(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    log(e.type);
    return false;
}



function onMouseup(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    log(e.type);
    return false;
}



function onClick(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    log(e.type);
    return false;
}

document.querySelector('.child').addEventListener('mousedown', onMousedown, false);
document.querySelector('.child').addEventListener('mouseup', onMouseup, false);
document.querySelector('.child').addEventListener('click', onClick, false);
var logBox = document.querySelector('.log')
<div class='wrapper'>
    <button class='child'>Click me</button>
    <ul class="log">
    </ul>
</div>
0
Tiago Coelho

Sames returnfalseは機能しません

function log(msg){
    logBox.innerHTML += '<li>' + msg + '</li>'
}

function onMousedown(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    log(e.type);
    return false;
}



function onMouseup(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    log(e.type);
    return false;
}



function onClick(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    log(e.type);
    return false;
}

document.querySelector('.child').addEventListener('mousedown', onMousedown, false);
document.querySelector('.child').addEventListener('mouseup', onMouseup, false);
document.querySelector('.child').addEventListener('click', onClick, false);
var logBox = document.querySelector('.log')
<div class='wrapper'>
    <button class='child'>Click me</button>
    <ul class="log">
    </ul>
</div>
0
A.Chan