最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to detect when a Container loses focus - Stack Overflow

programmeradmin2浏览0评论

I have a container (in a form) that has a Table layout with a set of Edit fields (texts, Checkboxes, etc).

I need to capture when the user clicks outside the container (on a menu item for example). There are no event handlers on the container currently.

I have a container (in a form) that has a Table layout with a set of Edit fields (texts, Checkboxes, etc).

I need to capture when the user clicks outside the container (on a menu item for example). There are no event handlers on the container currently.

Share asked Mar 14, 2013 at 19:22 srini.venigallasrini.venigalla 5,1451 gold badge20 silver badges29 bronze badges 2
  • $(document).not("#container").click(function() { .... – Rodrigo Siqueira Commented Mar 14, 2013 at 19:23
  • @RodrigoAssis That doesn't work if it needs to be triggered when tabbed out too. – James Coyle Commented Mar 14, 2013 at 19:24
Add a ment  | 

3 Answers 3

Reset to default 5

I know this is an old question, but I recently ran into the same problem so I thought I would try to help any fellow sufferers.

I got stuck for hours creating various incarnations of blur and click event listeners which all seemed to almost work. Blur would fail because it fires even if the focus is on a child element. Click worked but didn't handle keyboard navigation.

My final solution was to capture the focus event at the window level and pare the focus target with my container and it's children. This will only work for browsers that support addEventListener. In my app, I had a captive audience and didn't need to worry about IE < 9.

First create a function to check if the focus target is your container or any of it's child elements.

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;
};

Note that this will pare all nodes in the container through recursion.

Next, create a listener function.

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 );
    }
};

Note that the LocalTarget and Listener functions as well as [YOUR CONTAINER] are closures.

Finally, add the event listener.

window.addEventListener( 'focus', Listener, window, true );

While it seems like a lot of work to go through and the overhead is insane, this is the only concoction I could make work. Hope it helps someone.

Here is a solution using the focusout event, Node.contains method, and the relatedTarget property. This listens for the focusout event on a containing element. When the related target is no longer a descendent of that containing element you know that the focus has gone outside of that element.

let element = document.querySelector('.some-selector');
element.addEventListener('focusout', e => {
  if (! element.contains(e.relatedTarget)) {
    // Focus has left the element
  }
});

This might not work in IE11 since IE11 has only partial support for the Node.contains method.

In jquery you can use $('#container').blur(function() { //some code here });

发布评论

评论列表(0)

  1. 暂无评论