如何检测容器何时失去焦点

sri*_*lla 0 javascript extjs

我有一个容器(在表单中),它有一个带有一组编辑字段(文本、复选框等)的表格布局。

我需要在用户单击容器外(例如在菜单项上)时进行捕获。当前容器上没有事件处理程序。

小智 5

我知道这是一个老问题,但我最近遇到了同样的问题,所以我想我会尝试帮助任何其他患者。

我被困了几个小时,创建了各种模糊和点击事件侦听器的化身,这些似乎几乎都可以工作。模糊会失败,因为即使焦点在子元素上它也会触发。单击有效但不处理键盘导航。

我的最终解决方案是在窗口级别捕获焦点事件,并将焦点目标与我的容器及其子项进行比较。这仅适用于支持addEventListener 的浏览器。在我的应用程序中,我有一个俘虏观众,不需要担心 IE < 9。

首先创建一个函数来检查焦点目标是您的容器还是它的任何子元素。

var LocalTarget = function( el, target )
{
    if ( el === target )
    {
        return true;
    }
    else if ( el.childNodes )
    {
        var els = el.childNodes;

        for ( var i = 0, n = els.length; i < n; i++ )
        {
            if ( els[i] === target )
            {
                return true;
            }
            else if ( els[i].childNodes )
            {
                if ( LocalTarget(els[i], target) ) return true;
            }
        }
    }

    return false;
};
Run Code Online (Sandbox Code Playgroud)

请注意,这将通过递归比较容器中的所有节点。

接下来,创建一个侦听器函数。

var Listener = function( e )
{
    // Check if receiving element is part of the container.
    if ( !LocalTarget([YOUR CONTAINER], e.target) )
    {
        // Do focus lost stuff here...

        // Remove the event listener. [OPTIONAL]
        window.removeEventListener( 'focus', Listener, window, true );
    }
};
Run Code Online (Sandbox Code Playgroud)

请注意,LocalTarget 和 Listener 函数以及 [YOUR CONTAINER] 都是闭包。

最后,添加事件侦听器。

window.addEventListener( 'focus', Listener, window, true );
Run Code Online (Sandbox Code Playgroud)

虽然看起来有很多工作要做,而且开销也很疯狂,但这是我唯一能做的混合物。希望它可以帮助某人。