144

カスタム ドロップダウン メニューを表示する入力フィールドがあります。次の機能が欲しいです。

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

これが私の実装です:

入力フィールドには、ユーザーが入力フィールドの外側をクリックするたびにonblur()(その親を空の文字列に設定することによって) メニューを削除するイベントがあります。innerHTMLメニュー内の div にはonclick()、特別な処理を実行するイベントもあります。

問題はonclick()、メニューがクリックされたときにイベントが発生しないことです。これは、入力フィールドonblur()が最初に発生し、onclick()s! を含むメニューが削除されるためです。

この回答onclick()で提案されているのと同様に、メニュー divをonmousedown()onmouseup()イベントに分割し、マウスを離すとクリアされるグローバル フラグを設定することで問題を解決しました。は の前に発生するため、メニュー div の 1 つがクリックされた場合にフラグが設定されますが、画面上の他の場所がクリックされた場合は設定されません。メニューがクリックされた場合は、メニューを削除せずにすぐに戻り、 が起動するのを待ちます。その時点でメニューを安全に削除できます。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;
    ...
}
4

5 に答える 5

212

私はあなたとまったく同じ問題を抱えていました.私のUIはあなたが説明したとおりに設計されています. onClickメニュー項目の を に置き換えるだけで問題を解決しましたonMouseDown。私は他に何もしませんでした。いいえonMouseUp、フラグはありません。これにより、これらのイベント ハンドラーの優先度に基づいてブラウザーが自動的に並べ替えられるようになり、追加の作業を行わなくても問題が解決しました。

これがあなたにとってもうまくいかなかった理由はありますか?

于 2015-03-10T12:36:41.067 に答える
-7

次のように、ハンドラーsetInterval内で関数を使用できます。onBlur

<input id="input" onblur="removeMenu()" ... />

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

setInterval関数はコールスタックから関数を削除し、onBlur 時間を0に設定したため追加します。この関数は、他のイベントハンドラーが終了した直後に呼び出されます

于 2015-11-12T03:56:08.893 に答える