67

我有一个<input type="text">字段,当该字段失去焦点时我需要清除它(这意味着用户单击了页面上的某个位置)。但有一个例外。当用户单击特定元素时,不应清除输入文本字段。

我试图用来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>

4

1 回答 1

100

简短的回答:tabindex="0"属性添加到应该出现在event.relatedTarget.

解释: event.relatedTarget包含一个获得焦点的元素。问题是您的特定div 无法获得焦点,因为浏览器认为该元素不是按钮/字段或某种控制元素。

以下是默认可以获得焦点的元素:

  • <a>href具有指定属性的元素
  • <link>href具有指定属性的元素
  • <button>元素
  • <input>不是的元素hidden
  • <select>元素
  • <textarea>元素
  • <menuitem>元素
  • 带有属性的元素draggable
  • <audio>和具有指定属性<video>的元素controls

所以发生event.relatedTarget时将包含上述元素onblur所有其他元素将不计算在内,单击它们将null放入event.relatedTarget.

但是有可能改变这种行为。您可以将 DOM 元素“标记”为可以通过tabindex属性获得焦点的元素。这是标准所说的:

content 属性允许作者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>

于 2017-03-13T13:09:44.453 回答