如果模糊事件的任何一个子元素接收到焦点,则防止触发模糊事件

我在一个页面上有一个 div,它显示了一些关于特定类别(图像,名称等)的信息。

当我点击编辑图像,它把类别进入编辑模式,让我更新的名称。正如你可以从下面的图片看到,它显示“汤”目前在编辑模式,其他人在正常的视图模式。取消/保存按钮可以正常工作。(我试图添加一个形象,但不让我,需要更多的爱)

然而 一次在编辑模式下,如果我单击页面上的任何其他地方(在 div 之外) ,预期的结果将是汤类别回到视图模式。在某种类型的事件触发时,这还应该允许我询问他们是否希望保存更改。

所以我决定在“ soups”父 div 上创建一个模糊事件。如果我单击页面上的任何地方,这个工作原理就是正常的,但是如果我单击 div 的内部元素,它也会导致父元素模糊事件被触发,从而导致类别回到查看模式。

那么,如果父 div 的任何一个子 div 接收到焦点,是否有办法防止它触发侠影事件?

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

我只是在没有编译器的情况下编写了代码,所以不确定它是否能工作,但是希望你能明白我的意思。

我正在使用 Knockout.js 动态更新 GUI,但这不会影响我从未想过的答案。

56724 次浏览

我以前不得不解决这个问题。我不确定这是否是最好的解决方案,但它是我最终使用的。

由于点击事件在模糊后触发,因此没有(跨浏览器、可靠的)方法来判断哪个元素获得焦点。

然而,在模糊之前,鼠标向下开火。这意味着您可以在子元素的鼠标向下移动中设置一些标志,并在父元素的模糊中查询该标志。

工作示例: http://jsfiddle.net/L5Cts/

注意,如果您还想捕捉键盘造成的模糊,还必须处理 keydown(并检查 tab/shift-tab)。

我不认为有任何保证 mousedown会发生在所有浏览器的焦点事件之前,所以一个更好的方法来处理这可能是使用 evt.relatedTarget。对于 focusin事件,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
}
});

我也面临同样的问题,这对我很有效。

 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)) {
.....
}
}

享受:)