web-dev-qa-db-ja.com

blur event.relatedTargetはnullを返します

<input type="text">フィールドがあり、このフィールドがフォーカスを失ったときにクリアする必要があります(つまり、ユーザーがページのどこかをクリックしたことを意味します)。ただし、例外が1つあります。ユーザーが特定の要素をクリックしたときに、入力テキストフィールドをクリアしないでください。

event.relatedTargetを使用して、ユーザーがどこかだけでなく特定の<div>をクリックしたかどうかを検出しようとしました。

ただし、以下のスニペットで見ることができるように、単に機能しません。 event.relatedTargetは常にnullを返します!

function lose_focus(event) {
  if(event.relatedTarget === null) {
    document.getElementById('text-field').value = '';
  }
}
.special {
  width: 200px;
  height: 100px;
  background: #ccc;
  border: 1px solid #000;
  margin: 25px 0;
  padding: 15px;
}
.special:hover {
  cursor: pointer;
}
<input id="text-field" type="text" onblur="lose_focus(event)" placeholder="Type something...">

<div class="special">Clicking here should not cause clearing!</div>
28
CMTV

短い答え:_tabindex="0"_に現れるべき要素に_event.relatedTarget_属性を追加します。

説明:_event.relatedTarget_には、獲得した要素が含まれています。そして問題は、ブラウザがこの要素がボタン/フィールドまたは何らかの制御要素ではないと考えているため、specificdivがフォーカスを取得できないことです。

デフォルトでフォーカスを取得できる要素は次のとおりです。

  • href属性が指定された_<a>_要素
  • href属性が指定された_<link>_要素
  • _<button>_要素
  • _<input>_ hiddenではない要素
  • _<select>_要素
  • _<textarea>_要素
  • _<menuitem>_要素
  • 属性を持つ要素draggable
  • controls属性が指定された_<audio>_および_<video>_要素

したがって、onblurが発生すると、_event.relatedTarget_には上記の要素が含まれます。 All他の要素はカウントされず、それらをクリックしてもnullが_event.relatedTarget_に入れられます。

ただし、この動作を変更することは可能です。 tabindex属性を使用して、フォーカスを取得できる要素としてDOM要素を「マーク」できます。標準は次のとおりです。

コンテンツ属性tabindexを使用すると、作成者は、要素がフォーカス可能であること、シーケンシャルフォーカスナビゲーションを使用して到達可能であるかどうかを示し、オプションでシーケンシャルフォーカスナビゲーションの順序で要素が表示される場所を提案できます。

修正されたコードスニペットは次のとおりです。

_function lose_focus(event) {
  if(event.relatedTarget === null) {
    document.getElementById('text-field').value = '';
  }
}_
_.special {
  width: 200px;
  height: 100px;
  background: #ccc;
  border: 1px solid #000;
  margin: 25px 0;
  padding: 15px;
}
.special:hover {
  cursor: pointer;
}_
_<input id="text-field" type="text" onblur="lose_focus(event)" placeholder="Type something...">

<div tabindex="0" class="special">Clicking here should not cause clearing!</div>_
39
CMTV