15

I have a div that I am creating dynamically via jQuery with some links/buttons in it. When this div loses focus I need to remove it. This part I can do ok.

However, right now I have the focusout event on the wrapper for the div and when I click on a button inside the div, the wrapper loses focus to the child and my event gets fired. Checking if the element clicked is a child of the wrapper I can do, but since the wrapper no longer has focus, my event will not fire again to remove the div.

I have also tried .blur, but this doesn't work any better.

What is the best way to do this?

Helto
  • 565
  • 1
  • 4
  • 17

3 Answers3

21

A way of solving this with plain javascript is using the relatedTarget given in the event argument:

element.addEventListener('focusout', function(event) {
    if (element.contains(event.relatedTarget)) {
        // don't react to this
        return;
    }
    // do something
});
Jens
  • 8,423
  • 9
  • 58
  • 78
Stefan Hessler
  • 211
  • 2
  • 2
18
$("#yourDiv").focusout(function () {
   if ($(this).has(document.activeElement).length == 0) {
       // remove div
   }
});

$(this) = the div you're focusing out of.

document.activeElement = the element that is currently in focus.

$(this).has(document.activeElement) is simply checking if the active element is a child of your div

Isaac
  • 212
  • 3
  • 3
1

here is how I solved this for a menu using event.relatedTarget , :

$('#mapmenu  a.nolink').click(function (e) {//ul.lev-0 > li.expanded >
  $(this).closest('li').toggleClass('hovered');
  e.preventDefault();
  e.stopPropagation();
  return false;
});
$('#mapmenu  a.nolink').closest('li').focusout(function (e) {
  var ax = e.relatedTarget;
  var bx = $(ax).closest('ul');
  if ($(this).has(bx).length == 0) {
    $(this).removeClass('hovered');
  }
});
GZveri
  • 41
  • 3