There are two input elements which hide themselves on blur. The problem is that the click event which caused the blur is lost if the click was on an element which comes after the element being hidden in the DOM.
If the clicked element is before the blurred element, it works as expected
This simple snippet demonstrates:
<html>
<script src="./jquery.min.js" ></script>
<script type="text/javascript">
$(document).ready(function() {
$('input').blur(function(e) {
console.log('blurred');
$(this).hide();
});
$('.a').click(function() {
console.log('div clicked');
});
$(document).click(function() {
console.log('doc clicked');
});
});
</script>
<body>
<div id="div1">
<div class="a"><input /></div>
<div class="a"><input /></div>
</div>
</body>
</html>
If the bottom input is clicked, then the top, it works as expected – “blurred” prints, then “div clicked”, then “doc clicked” and the bottom input is hidden.
If the top input is clicked, then the bottom, the top input is hidden, only “blurred” prints and the click event can’t be handled anywhere.
If the call to hide is commented out, it also works as expected.
Using .live doesn’t make a difference.
I can think of ways to work around this, but none are very good. Any thoughts on why the order of the inputs matters, or better solutions?
Thanks.
OK OK OK this is just us collectively being stupid together.
Look what is happening when you are clicking from top to bottom.
Top has focus. When you click into the 2nd input THAT IS UNDERNEATH IT, the blur event fires before the click event registers on the 2nd div.
What’s happening is that you are clicking into the 2nd input to give it focus. Since events bubble up from the target that’s clicked (the 2nd input), it gets focus. But since the 1st input blur event fires first, it reduces the height of the top div to 0 and that immediately moves the 2nd div up beyond the range of the the current mouse position. Therefore, the click event on the 2nd div never happens, because the div is already moved out of the way before that happens.
You can see why in this jsfiddle. http://jsfiddle.net/Z884F/ I’ve added
elements to maintain the div heights even after their inputs are being hidden. If you look at the console, you’ll see it works as expected.
The reason Firefox works is that it handles the timing of events a little differently.
IGNORE MY ORIGINAL ANSWER BELOW:
This is very strange behavior. I’ve verified your results in Chrome and Safari on Mac OS 10.7. However, Firefox 12.0 works as expected.
If you do the blur inside a 500ms setTimeout, it works as expected. Though I think the event on the parent div is still being removed.
I have a jsfiddle here, http://jsfiddle.net/gsuTw/
I would highly recommend filing this as a bug over at the jQuery dev site. This looks like a bug with blur().