Blur event not firing on <label> - can't find workaround for dealing with hide-on-blur <input> text field

StackOverflow https://stackoverflow.com/questions/20822978

TL;DR how can I get this self-explanatory JSFiddle to work?

From the W3C:

The blur event occurs when an element loses focus either via the pointing device or by tabbing navigation. This event is valid for the following elements: LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.

The basic idea, HTML:

<form>
    <label>
        <input type="text" />
        <a href="#">after focusing in input, there should be no blur when clicking here</a>
    </label>
</form>
<a href="#">but blur should fire when clicking here</a>

And JS:

$("form, label").on("blur", function() {
    alert("you're not going to see this");
});

It doesn't work. A more illustrative example is in this JSFiddle.

I also tried focusout, with this JSFiddle, but (presumably because it bubbles up from the input), it always fires.

I could probably rig up what I need with a hack like this: https://stackoverflow.com/a/5049387/458614 but I'd rather not have to.


Edit: There are lots of related questions and I have read all that I could find, none of which help. Some talk about setting tabindex=0 on the form or label elements. I have tried this in various permutations but it doesn't help. JSFiddle here. If you put it on the form, blur events do fire when you click outside the form. However, it doesn't apply to any of it's children: it won't pick up anything if you click on the input and then outside the form.


Edit 2: I don't really understand some of the answers posted so far and none seem to really... work. Anyway, to clarify, here is what I am trying to accomplish:

In my app, you can add tags to documents. When you click the "add tag" button, a previously-hidden text input field pops up and is focused. And then...

  1. Clicking outside (on blur) should close the text input field again
  2. Pressing enter should add the tag and close the input field
  3. Clicking the "add tag" button should also add the tag and close the input field

The problem is that #1 and #3 are incompatible. The "add tag" button needs to perform a different action based on whether the text field is open or closed, but because I can only achieve #1 with an onblur event on the text field, the text field is closed by the time any action happens on the "add tag" button for #3.

Here is a JSFiddle with my best attempt so far.

有帮助吗?

解决方案

The thing I think you are looking for is

e.stopPropagation();

This Fiddle here shows a little different way to handle it ... it put the hide on a window click (which would blur the input anyways) except on the label, which it would allow the click event to stop inside the label.

Happy coding!

其他提示

use the below code to achieve the desired

  $(document).on("blur", "label",function() {
       $("div").append("form or label blurred<br>");
   });

Here is the demo Fiddle

Try this it should work

.focus {
border-color:red;
}


$(document).ready(function() {    

    $('input').blur(function(){
            $('input').removeClass("focus");
        })
             .focus(function() {        
                 $(this).addClass("focus")
        });

});

Add this piece of js in your Fiddle. you added listener for label but blur happens on anchor tag.

      $("form a").on("blur", function() {
              $("div").append("form or label blurred<br>");
       });

according to your explanation i have create a demo

$("form > label >a").on("blur", function() {
      return false
});

    $("#outsideform > a").on("blur", function() {
    alert("but blur should fire when clicking here");
});

Check the Demo here

For a while, I am posting an intermediate development. But this definitely will help you where exactly you should look for. The jquery implementation but not your javascript. This is the real concern.

I have added 3 lines at different places. no big changes.

  1. Added an || $("input").css("visibility") == "visible" to the if condition
  2. Added $("input").css("visibility","hidden"); to the inner else condition
  3. $("input").css("visibility","visible"); to the outer (and last) else condition.

Please note this is intermediate, you need to click twice after a submit of non-empty text. If I get time, I would post the correct working thing. This is the fiddle.

tobek, your JSFiddle with my best attempt so far is almost there. The problem is your selector at the bottom in this section of code:

$("input").on("blur", function(){
    $("input").hide();
});

You stated the problem correctly in your comments when you said: "THE PROBLEM: we never get in here because it's already been hidden because the input blurred".

Change the above section to this and I think you'll have what you're looking for.

$("input-blur label").on("blur", function(){
    $("input").hide();
});

Because the "Add tag" link is inside the label clicking it doesn't trigger your "blur" function.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top