1. ホーム
  2. javascript

[解決済み] onclick() と onblur() の順序問題

2022-05-13 10:14:40

質問

カスタムドロップダウンメニューを表示させる入力フィールドがあります。 私は以下の機能を希望します。

  • ユーザーが入力フィールドの外側のどこかをクリックすると、メニューが削除されるようにする。
  • より具体的には、ユーザがメニュー内の div をクリックした場合、メニューを削除するようにします。 のように、どの div がクリックされたかに基づいて特別な処理が行われる必要があります。

以下は私の実装です。

入力フィールドには onblur() イベントがあり、これはメニューを削除します (親の innerHTML を空文字列に設定することで)メニューを削除します。 メニューの中の div も onclick() イベントが発生し、特殊な処理が実行されます。

問題なのは onclick() イベントが発生しないことです。なぜなら、メニューがクリックされても入力フィールドの onblur() イベントが最初に発生し、メニューが削除され、その中に onclick() s!

メニューのdivを分割することで問題を解決しました。 onclick()onmousedown()onmouseup() イベントで提案されたものと同様に、マウスダウン時にグローバルフラグを設定し、マウスアップ時にクリアするようにします。 この回答 . なぜなら onmousedown() が実行される前に onblur() にフラグが設定されます。 onblur() にフラグがセットされ、画面上の他の場所がクリックされた場合はセットされません。 もしメニューがクリックされたなら、私はすぐに onblur() から戻り、メニューが削除されることなく、次に onclick() が鳴るのを待ち、その時点でメニューを安全に削除することができます。

もっとエレガントな解決策はないのでしょうか?

コードは次のようなものです。

<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />

var mouseflag;

function setFlag() {
    mouseflag = true;
}

function removeMenu() {
    if (!mouseflag) {
        document.getElementById('menu').innerHTML = '';
    }
}

function doProcessing(id, name) {
    mouseflag = false;
    ...
}

どのように解決するのですか?

私もあなたと全く同じ問題を抱えていました。私の UI は、あなたが説明したとおりに設計されています。私は、単に onClickonMouseDown . 他には何もしていません。 onMouseUp もなく、フラグもありません。これにより、ブラウザがこれらのイベント ハンドラの優先順位に基づいて自動的に順序を変更することで、私が追加作業をすることなく、問題が解決されました。

この方法がうまくいかない理由はありますか?