knockout.js 如果blur事件的任何一个子级获得焦点,则防止触发blur事件

gstyhher  于 2022-11-10  发布在  其他
关注(0)|答案(3)|浏览(162)

我在页面上有一个div,它显示了关于特定类别的一些信息(图像、名称等)。
当我点击编辑图片时,它会将类别设置为编辑模式,这样我就可以更新名称了。正如你从下面的图片中看到的,它显示“Soup”当前处于编辑模式,其他的处于普通视图模式。这一切都和预期的一样,取消/保存按钮做的一切都是正确的。(我试着添加一张图片,但不让我添加,需要更多的爱)

然而一旦进入编辑模式,如果我点击页面上的任何地方(在div之外),预期的结果将是soup类别将返回到查看模式。在某种事件触发时,这也应该允许我询问他们是否要保存更改。

因此,我决定在“soups”父div上创建一个blur事件。如果我单击页面上的任何位置,这将按预期工作,但是如果我单击div的内部元素,它也会引发parents blur事件,从而导致类别返回到查看模式。
那么,有没有一种方法可以防止父div在它的任何一个子div获得焦点时触发blur事件?

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

我只是在没有编译器的情况下写了代码,所以不确定这是否有效,但希望你能明白。
我正在使用Knockout.js来动态更新GUI,但这不应该影响这个答案,我不会想到。

iqjalb3h

iqjalb3h1#

我也遇到过同样的问题。这对我很有效。

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

尽情享受吧:)

j0pj023g

j0pj023g2#

我以前也遇到过这个问题,我不确定这是否是最好的解决方案,但我最终还是用了这个方法。
由于click事件在blur之后触发,因此没有(跨浏览器的,可靠的)方法来判断哪个元素获得了焦点。
然而,Mousedown在blur之前触发,这意味着你可以在子元素的mousedown中设置一些标志,然后在父元素的blur中询问这个标志。
工作示例:http://jsfiddle.net/L5Cts/
请注意,如果您还想捕获由键盘引起的模糊,则还必须处理keydown(并检查Tab/shift-tab)。

h79rfbju

h79rfbju3#

我不认为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
    }
});

相关问题