Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Action on blur except when specific element clicked with jQuery

There are two elements in play:

$('#myInput') // an input field for search $('#myList') // a list to display search results 

I want to hide the list when the input no longer has focus, like so:

$('#myInput').blur(function() {   $('#myList').hide(); }); 

This works great, except when a list item is clicked, because the blur event fires and hides the list before the click is registered. The goal is for the list to stay visible when any part of the list is clicked, even though this will cause the input to blur.

How can I do this? Thanks!

like image 464
Justin Stayton Avatar asked Feb 04 '11 19:02

Justin Stayton


People also ask

What triggers the jQuery blur event?

The blur event occurs when an element loses focus. The blur() method triggers the blur event, or attaches a function to run when a blur event occurs. Tip: This method is often used together with the focus() method.

Does blur trigger Focusout?

The blur event fires when an element has lost focus. The main difference between this event and focusout is that focusout bubbles while blur does not. The opposite of blur is focus . This event is not cancelable and does not bubble.

Does blur happen before click?

It looks like click event has lower priority than blur, so it is predictible behaviour that blur event fires first.

Does Onblur work on Div?

The blur event fires when focus is lost. By default, a div element cannot have the focus in the first place so it can't be lost. If you set tabindex on a div, then it can gain the focus, but you should almost always be using a more appropriate element (such as a button) when you think about making interactive controls.


2 Answers

You can accomplish this by keeping a global variable, and setTimouts, to wait a delay of 200ms and then check if one of the 2 elements have focus.

var keepFocus = false;  function hideList(){     if(!keepFocus){         $('#myList').hide();     } }  $('#myInput').blur(function() {     keepFocus = false;     window.setTimeout(hideList, 200); }).focus(function(){     keepFocus = true; });   $('#myList').blur(function() {     keepFocus = false;     window.setTimeout(hideList, 200); }).focus(function(){     keepFocus = true; }); 
like image 65
The Scrum Meister Avatar answered Sep 21 '22 07:09

The Scrum Meister


I've faced with the exact same problem, so this is how I solved it.

I came up with the fact that blur() fires earlier than click().

So I've tried to change click() to mousedown() and found out that mousedown() fires before blur().

And to imitate click() you'll have to fire mousedown() and then mouseup()

So in your case I would do something like this:

var click_in_process = false; // global  $('#myList').mousedown(function() {     click_in_process = true; });  $('#myList').mouseup(function() {     click_in_process = false;     $('#myInput').focus();      // a code of $('#myList') clicking event  });  $('#myInput').blur(function() {     if(!click_in_process) {         $('#myList').hide();          // a code of what you want to happen after you really left  $('#myInput')      } }); 

Demo / example: http://jsfiddle.net/bbrh4/

Hope it helps!

like image 28
Pigalev Pavel Avatar answered Sep 24 '22 07:09

Pigalev Pavel