我在页面上有一个div,显示有关特定类别(图像,名称等)的一些信息。
当我点击编辑图像时,它会将类别置于编辑模式,这样我就可以更新名称。从下图中可以看出,它显示“Soup”当前处于编辑模式,其他处于正常视图模式。这一切都按预期工作,取消/保存按钮做正确的事情。 (我尝试添加图像,但不会让我,需要更多的爱)
然而一旦处于编辑模式,如果我点击页面上的任何其他位置(div之外),预期结果将是汤类别将返回查看模式。在事件发生某种情况下,这也应该让我问他们是否想要保存更改。
所以我接下来决定在“汤”父div上创建一个模糊事件。如果我单击页面上的任何位置,这将按预期工作,但是如果我单击div的内部元素,它也会导致父模糊事件被触发,从而导致类别返回到查看模式。
那么,有没有办法阻止父div在其任何一个子节点获得焦点时触发模糊事件?
<div tabindex="-1" onblur="alert('outer')">
<input type="text" value="Soup" />
</div>
我只是在没有编译器的情况下编写代码,因此不确定这是否有效,但希望你能得到这个想法。
我正在使用Knockout.js动态更新GUI,但这不应该影响我不会想到的答案。
答案 0 :(得分:32)
我以前必须解决这个问题。我不确定它是否是最好的解决方案,但这是我最终使用的。
由于点击事件在模糊之后触发,因此没有(跨浏览器,可靠)方式来判断哪些元素正在获得焦点。
但是,Mousedown会在模糊之前触发。这意味着您可以在子元素的mousedown中设置一些标志,并在父母的模糊中查询该标志。工作示例:http://jsfiddle.net/L5Cts/
请注意,如果您还想捕捉键盘引起的模糊,您还必须处理keydown
(并检查tab / shift-tab)。
答案 1 :(得分:31)
我遇到了同样的问题。这对我有用。
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)) {
.....
}
}
享受:)
答案 2 :(得分:7)
我认为在所有浏览器中的焦点事件之前都会发生任何保证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
}
});