Guido Tarsia
Guido Tarsia

Reputation: 2162

How to not lose element focus when children are clicked

In this fiddle there is a div with two elements in it.

http://jsfiddle.net/nxujqocw/

HTML:

<div tabindex=0>
    <input type="text" value="hello"/>
    <input type="button" class="hidden" value ="hola"/>
</div>

Javascript:

$(document).ready(function() {
    $("div").focusin(function() {
        console.log("focus in");
        $("input[type=button]").removeClass("hidden");
    });
    $("div").focusout(function() {
        console.log("focus out");
        $("input[type=button]").addClass("hidden");
    });
});

I want the following behaviour to happen: If I click inside the div (including the children), I want a button inside it to appear.

In Chrome, if I make the button appear, and then click it, what happens is that focus is lost and regained, which is fine with me, even though it's not technically correct.

But in Firefox focus is not regained.

How can I accomplish this?

Upvotes: 1

Views: 1291

Answers (1)

Oriol
Oriol

Reputation: 288100

The problem is that, when the text input is focuses and you click the button,

  1. First, focusout is triggered on text input, which hides the button
  2. Then, since the button is hidden, it can't receive focus, so focusin is not triggered.

You can fix it like this:

  • In focusout event listener, instead of hiding the element immediately, use setTimeout.
  • In focusout event listener, clear the timeout if it hasn't run yet.

var $target = $("input[type=button]"),
    timer;
$("div")
.focusin(function() {
    clearTimeout(timer);
    $target.removeClass("hidden");
})
.focusout(function() {
    timer = setTimeout(function() {
        $target.addClass("hidden");
    }, 0);
});
.hidden {
    display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div tabindex="0">
    <input type="text" value="hello"/>
    <input type="button" class="hidden" value="hola" />
</div>

Upvotes: 1

Related Questions