53

特定のカテゴリ(画像、名前など)に関する情報を表示するdivがページにあります。

編集画像をクリックすると、カテゴリが編集モードになり、名前を更新できるようになります。下の画像からわかるように、「スープ」は現在編集モードであり、他は通常の表示モードです。これはすべて、キャンセル/保存ボタンがすべて正しく機能することで期待どおりに機能します。(画像を追加しようとしましたが、許可されませんでした。もっと愛が必要です)

ただし、編集モードでページの他の場所(divの外側)をクリックすると、予想される結果として、スープカテゴリが表示モードに戻ります。ある種のイベントが発生すると、変更を保存するかどうかを尋ねることもできます。

そこで、私がやろうと決めたのは、「スープ」の親divでblurイベントを作成することです。これは、ページの任意の場所をクリックすると期待どおりに機能しますが、divの内側の要素をクリックすると、親のぼかしイベントが発生し、カテゴリが表示モードに戻ります。

それで、子のいずれかがフォーカスを受け取った場合に、親divがblurイベントを発生させないようにする方法はありますか?

<div tabindex="-1" onblur="alert('outer')">
    <input type="text" value="Soup" />
</div>

私はコンパイラなしでコードを書いたので、それが機能するかどうかはわかりませんが、うまくいけば、あなたはアイデアを得ることができます。

私はKnockout.jsを使用してGUIをその場で更新していますが、それは私が考えていなかったこの答えに影響を与えるべきではありません。

4

3 に答える 3

95

私は同じ問題に直面しました。これは私のために働いたものです。

 handleBlur(event) {
    // if the blur was because of outside focus
    // currentTarget is the parent element, relatedTarget is the clicked element
    if (!event.currentTarget.contains(event.relatedTarget)) {
        .....
    }
}

楽しみ :)

于 2020-02-06T12:16:16.540 に答える
54

私は以前にこの問題に取り組まなければなりませんでした。それが最善の解決策であるかどうかはわかりませんが、それが私が最終的に使用したものです。

クリックイベントはぼかしの後に発生するため、どの要素がフォーカスを獲得しているかを判断する(クロスブラウザ、信頼性の高い)方法はありません。

ただし、マウスダウンはぼかしの前に発火します。これは、子要素のマウスダウンでフラグを設定し、親のぼかしでそのフラグを調べることができることを意味します。

実例: http: //jsfiddle.net/L5Cts/

keydownキーボードによって引き起こされるブレもキャッチしたい場合は、処理する(そしてタブ/シフトタブをチェックする)必要があることに注意してください。

于 2012-08-23T13:17:00.377 に答える
27

すべてのブラウザでフォーカスイベントの前に発生する保証はないと思うmousedownので、これを処理するためのより良い方法はを使用することかもしれませんevt.relatedTargetfocusinイベントの場合、eventTargetプロパティは現在フォーカスを失っている要素への参照です。その要素が親の子孫であるかどうかを確認できます。そうでない場合は、フォーカスが外部から親に入っていることがわかります。focusoutイベントの場合、relatedTargetは現在フォーカスを受け取っている要素への参照です。同じロジックを使用して、フォーカスが完全に親を離れているかどうかを判断します。

const parent = document.getElementById('parent');

parent.addEventListener('focusin', e => {
    const enteringParent = !parent.contains(e.relatedTarget);

    if (enteringParent) {
        // do things in response to focus on any child of the parent or the parent itself
    }
});

parent.addEventListener('focusout', e => {
    const leavingParent = !parent.contains(e.relatedTarget);

    if (leavingParent) {
        // do things in response to fully leaving the parent element and all of its children
    }
});
于 2017-11-29T23:06:12.380 に答える