Hide a DIV when it loses focus/blur - javascript

I have a JavaScript that displays a DIV (sets its display css property from 'none' to 'normal'. Is there a way to give it focus as well so that when I click somewhere else on the page, the DIV loses focus and its display property is set to none (basically hiding it). I'm using JavaScript and jQuery

For the hide the div when clicking any where on page except the selecteddiv
$(document).not("#selecteddiv").click(function() {
$('#selecteddiv').hide();
});
if you want to hide the div with lost focus or blur with animation then also
$("#selecteddiv").focusout(function() {
$('#selecteddiv').hide();
});
with animation
$("#selecteddiv").focusout(function() {
$('#selecteddiv').animate({
display:"none"
});
});
May this will help you

The examples already given unfortunately do not work if you have an iframe on your site and then click inside the iframe. Attaching the event to the document will only attach it to same document that your element is in.
You could also attach it to any iframes you're using, but most browsers won't let you do this if the iframe has loaded content from another domain.
The best way to do this is to copy what's done in the jQuery UI menubar plugin.
Basic example HTML:
<div id="menu">Click here to show the menu
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
And the jQuery needed to make it work:
var timeKeeper;
$('#menu').click(function()
{
$('#menu ul').show();
});
$('#menu ul').click(function()
{
clearTimeout(timeKeeper);
});
$('#menu').focusout(function()
{
timeKeeper = setTimeout(function() {$('#menu ul').hide()}, 150);
});
$('#menu').attr('tabIndex', -1);
$('#menu ul').hide();
What it does is give the menu a tab index, so that it can be considered to have focus. Now that you've done that you can use the focusout event handler on the menu. This will fire whenever it has been considered to lose focus. Unfortunately, clicking some child elements will trigger the focusout event (example clicking links) so we need to disable hiding the menu if any child elements have been clicked.
Because the focusout event gets called before the click event of any children, the way to achieve this is by setting a small timeout before hiding the element, and then a click on any child elements should clear this timeout, meaning the menu doesn't get hidden.
Here is my working jsfiddle example

$(document).mouseup(function (e)
{
var container = $("YOUR CONTAINER SELECTOR");
if (!container.is(e.target)&& container.has(e.target).length === 0)
{
container.hide();
}
});

You can bind a function on click of body and check if its the current div using e.target (e is the event)
$(document).ready(function () {
$("body").click(function(e) {
if($(e.target).attr('id') === "div-id") {
$("#div-id").show();
}
else {
$("#div-id").hide();
}
});
});

Regarding mouse clicks, see the other answers.
However regarding lost focus, .focusout is not the event to attach to, but rather .focusin. Why? Consider the following popup:
<div class="popup">
<input type="text" name="t1">
<input type="text" name="t2">
</div>
What happens on moving from t1 to t2:
t1 sends focusout, which bubbles up to $('.popup').focusout
t2 sends focusin, which bubbles up to $('.popup').focusin
... so you get both types of event even though the focus stayed completely inside the popup.
The solution is to analogous to the magic trick done with .click:
$(document).ready(function() {
$('html').focusin(function() {
$('.popup').hide();
});
$('.popup').focusin(function(ev) {
ev.stopPropagation();
});
});
(side note: I found the .not(...) solution not working bc. of event bubbling).
Bonus: working fiddle click me - open the popup, then try tabbing through the inputs.

I was also looking for this and here I found the solution https://api.jquery.com/mouseleave/. This may be useful for future readers.
The mouseleave event differs from mouseout in the way it handles event bubbling. If mouseout were used in this example, then when the mouse pointer moved out of the Inner element, the handler would be triggered. This is usually undesirable behavior. The mouseleave event, on the other hand, only triggers its handler when the mouse leaves the element it is bound to, not a descendant.

On triggering mouseup() event, we can check the click is inside the div or a descendant and take action accordingly.
$(document).mouseup(function (e) {
var divContent= $(".className");
if(!divContent.is(e.target) && divContent.has(e.target).length === 0) {
$(".className").hide();
}
});

I personally haven't tried blur on divs, only on inputs etc. If blur eventhandler works, it's perfect and use it. If it doesn't, you could check this out:
jQuery animate when <div> loses focus

$('.menu > li').click(function() {
$(this).children('ul').stop().slideDown('fast',function()
{
$(document).one('click',function()
{
$('.menu > li').children('ul').stop().slideUp('fast');
});
});
});

Showing is easy
$('somewhere').click(function {$('#foo').show();})
For hiding
How do I hide a div when it loses its focus?

With jQuery you can hide elements with hide(), ex: $("#foo").hide()
Hide element in event listener:
$("#foo").blur(function() {
$("#foo").hide();
});

Related

How to disable Left Click of Mouse for a div using jquery?

I am using this code but it's not working.
Jquery Code: I am create div for captcha i want not copy or select this contents (Captcha code).
$(document).ready(function() {
$("#lo").on("contextmenu",function(e){
return false;
});
});
HTML Code:-
<div id="lo">CAPTCHACODE2321</div>
You can try the below code
HTML
<div id="lo" class="preventLeftClick">wwww</div>
Jquery
$('.preventLeftClick').on('click', function(e){
e.preventDefault();
return false;
});
Note: You can use this with any number of divs. You just need to add the class preventLeftClick with that div only
try this its prevent the click it showing as normal mouse pointer when hover the hyper link .
<div id="lo" style="pointer-events:none;">wwww</div>
One way would be to disable pointer-events in css so no events would be generated.
#lo { pointer-events: none; }
The element is never the target of mouse events; however, mouse events
may target its descendant elements if those descendants have
pointer-events set to some other value. In these circumstances, mouse
events will trigger event listeners on this parent element as
appropriate on their way to/from the descendant during the event
capture/bubble phases.
Another way would be to catch click and disable default browser behaviour.
$(document).ready(function() {
$("#lo").on("click",function(e){
e.preventDefault();
return false;
});
});
You can add a simple css3 rule in the body or in specific div, use "pointer-events: none;" property.
Check this sample code

jQuery - hide dropdown when DOM element is focused

i got to show a dropdown menu, now i would like to hide that when anoher element (not dropdown or dropdown's children) in the DOM is focused.
(hide dropdpown when element !== dropdown||dropdown's childrens is focused in the DOM)
i tryed with focusout() with no results:
$('a').on('click',function(){
$('.drop.user-menu').fadeIn();
});
$('.drop.user-menu').on('focusout',function(){
$(this).fadeOut();
alert('antani');
});
any idea?
jsfiddle here : example
event.target() will be useful in this scenario:
$('.drop.user-menu').on('focusout',function(e){
if(e.target !== this){
$(this).fadeOut();
alert('antani');
}
});
Update:
Check this out and see if helps:
$('.a').on('click', function (e) {
e.stopPropagation();
$('.drop.user-menu').fadeToggle();
});
$('.drop.user-menu').on('click', function (e) {
e.stopPropagation();
$('.drop.user-menu').fadeIn();
});
$(document).on('click', function (e) {
if (e.target !== $('.drop.user-menu') && e.target !== $('.a')) {
$('.drop.user-menu').fadeOut();
}
});
The above script done with click in this fiddle
A DIV cannot take or lose focus (unless it has a tabindex). You'll have to give it a tabindex or add a focusable element into your div.drop.user-menu. See Which HTML elements can receive focus?.
You then also have to explicitly give that element (or an element within it) focus (with .focus()) as simply fading it in doesn't give it focus.
When the element blurs, then check if the new active element is still part of the menu. If it's not, fade out the menu.
See a working example.
There is no focus or focusout events triggered, because you're not operating on form fields.
This is probably what you want : How do I detect a click outside an element?
var menu = $('.drop.user-menu');
menu.on('click',function(e){
e.stopPropagation(); // stop clicks on menu from bubbling to document
});
$('a').on('click', function (e) {
menu.fadeIn();
e.stopPropagation(); // stop clicks on <a> from bubbling to document
});
$(document).on('click',function(e){
// any other click
if (menu.is(":visible")) {
menu.fadeOut();
}
});
http://jsfiddle.net/BBxEN/10/
Update
As Derek points out, this is not very friendly for keyboard users. Consider implementing a way for users to both open and close the menu using keyboard shortcuts.
You can tru with blur, is what you want?
Try this:
$('.drop.user-menu').on('blur',function(){
$(this).fadeOut();
alert('antani');
});

Excluding an element from jQuery selection

I'm trying to get a .click() event to work on a div.content except if clicked on something with a specific class, say, .noclick. Example html:
<div class="content">
<a href="#" class="noclick">
</div>
Doing this doesn't work because the <a> tag is not technically in the selection:
$('.content').not('.noclick').click(function(){/*blah*/});
How can I get the click function to work if I click anywhere on .content except something with class .noclick?
You'd have to exclude them from within the callback:
$('.content').click(function(e) {
if ($(e.target).hasClass('noclick')) return;
});
Or stop the event from leaving those elements:
$('.noclick').click(function(e) {
e.stopPropagation();
});
I would go with the second one. You can just drop it and your current code (minus the .not()) will work.
$('.content').click(function(event) {
// ...
}).find('.noclick').click(function(event) {
event.stopPropagation();
});
$('.content').click(function(e){
if(!$(e.target).is('.noclick')){
// Handle click event
}
});
$('.content').
on('click', '.noclick', function(){return false;}).
click(function(){alert("click")})
cancels clicks on '.noclick', yet fires clicks elsewhere
http://jsfiddle.net/FshCn/

Disable slideDown/Up on links inside div

Basicllay i have a div with a class called .li-level-1, and inside that i have differnt ul's with lists. i Have it set up so when you click on a li-level-1 div displays the ul's and li's inside that div by animating a drop down and when you click on the next one it closes the one previously opened and slidesDown the next one.
the only thing is the a links that are inside the div's seem to trigger the slideUp/Down on level-1 and animation as well.
any Suggestions?
$('.sitemap_page .li-level-1').each(function(){
$(this).find('ul.ul-level-2').hide();
$(this).click(function(){
var this_list = $(this);
this_list.parent().find('.open').each(function(){
$(this).slideUp(function(){
this_list.find('ul.ul-level-2').addClass("open").slideDown();
}).removeClass('open');
});
if(this_list.find('ul.ul-level-2.open').length == 0) {
this_list.find('ul.ul-level-2').addClass("open").slideDown();
}
});
});
That's because of event bubbling: the click event raised on the <a> elements bubble up to their containing <div> and cause your event handler to execute.
One way to work around that problem would be to use event.target to determine the event's origin, and only perform the sliding animations if the event did not originate on a link:
$(this).click(function(event) {
if (!$(event.target).is("a")) {
var this_list = $(this);
this_list.parent().find('.open').each(function() {
$(this).slideUp(function() {
this_list.find('ul.ul-level-2').addClass("open").slideDown();
}).removeClass('open');
});
if (this_list.find('ul.ul-level-2.open').length == 0) {
this_list.find('ul.ul-level-2').addClass("open").slideDown();
}
}
});
The problem is with event bubbling as sugested by Frederic. The other possible solution is to divide your div into title and content divs. Hold data in content and check click on title (not on the parent list). This means rebuilding the handler but the code will be clearer and it won't depend on event.target.

Internet Explorer and <select> tag problem

I am having the following problem under Internet Explorer 7/8:
I have a popup that gets activated when user mouseover a link. The popup is a simple <div> that contains some data. Inside this <div> tag there is a <select> tag with some <option>s. I have attached mouseover/mouseout events to the <div>, so that this popup will stay open while cursor is over it. The problem comes when you click on the <select> and then move the cursor over any of the <option>s. This triggers the mouseout event of the <div> tag and respectively closes it.
How can I prevent the closing of the popup in IE ?
You should be able to detect if the situation is the one you want just with the values off the event. It is a little convoluted but it seems to work.
In the event handler of your outer div, do something like this:
<div onmouseover="if (isReal()) { toggle(); }"
onmouseout="if (isReal()) { toggle(); }">
</div>
Then implement the isReal method:
function isReal() {
var evt = window.event;
if (!evt) {
return true;
}
var el;
if (evt.type === "mouseout") {
el = evt.toElement;
} else if (evt.type === "mouseover") {
el = evt.fromElement;
}
if (!el) {
return false;
}
while (el) {
if (el === evt.srcElement) {
return false;
}
el = el.parentNode;
}
return true;
}
Basically the isReal method just detects if the event was coming from within the div. If so, then it returns false which avoids calling the hide toggle.
My suggestion would be to set another flag while the select box has focus. Do not close the div while the flag is set.
How about re-showing the div when the mouse is over the <options>s through mouseover events of <options>s.
Edit: execution order of mouseover of option and mouseout of div might cause problems though.
In the mouseout event for the div add a timeout to the div element that will hide the div in 200 milliseconds or so.
Then in the mouseover event for the div/select and the click event of the select clear the timeout stored in the div element.
This gives a very slight delay before hiding the div that allows the mouseover or click events to clear the timeout before it is executed. It's not pretty but it should work.
instead of using mouseout as the event to close the div, use mouseleave, then the event will only be triggered when the pointer leaves the boundary of the div, not when it moves onto other elements within it
you could try adding another mouseover event specifically for the options list.
Well, the reason for this behavior is because the mouseover/out events bubble, which effectively means that whenever you mouseover any of the elements inside the popup, the popup receives the event also.
You can read more here about these events, and here about event bubbling.
You have 3 possible solutions here:
Change the events to onmouseenter/leave. You've mentioned that this didn't help, which just sounds plain odd, since these aren't supposed to bubble.
Check srcElement in relation to from/toElement in the event.
An improved version of McKAMEY's check would be:
function isReal() {
var evt = window.event;
if (!evt) {
return true;
}
var el;
if (evt.type === "mouseout") {
el = evt.toElement;
} else if (evt.type === "mouseover") {
el = evt.fromElement;
}
if (!el) {
return false;
}
// this will also return true if el == evt.srcElement
return evt.srcElement.contains(el);
}
Does the same thing, just shorter.
3 . Another option would be to create a transparent, invisible div just under your popup that covers the area that the select box drops down into. I'm assuming that it's dropping outside the actual area of the popup.
Hope this helps!
have you tried hover instead of mouseover/out effects?
$(".myDiv").hover(function(){
$(this).show();
}, function {
$(this).hide();
});
What about something like this:
<div id="trigger">
Hover over me!
</div>
<div class="container">
<select>
<option>Blah</option>
<option>Blah</option>
</select>
</div>
$("#trigger").mouseover(function(){
$('.container).show();
});
$(".container").mouseleave(function(){
$(this).hide();
});
The basic idea is that you show the container element when you hover over the trigger then when you leave the container you hide the container. You'd need to position the container so it clipped the trigger element, otherwise it would hide straight away.
Why have mouseover / mouseout on the <div>? Why not just show the <div> on the mouse over, then set <body onmouseover="hidedivs();"> I don't know if this would work, but if the <div> is on top of the body, then the <div> should stay visible.
Many people posting solutions/examples do not seem to realize one thing: onmouseout event on <div> fires before onmouseover event on <select>.
When <div> loses focus (onmouseout) do not close it immediately, but after say, 500 milliseconds. If during this time <select> gets focus (mouseover) do not close <div> at all (clearTimeout).
Also, try to play with event propagation/bubling.
Given that selects in IE are a pain, especially when it comes to the whole layering issue where a select appears above a div even though it shouldn't, can I point you in the direction of YUI's Menu button controls. They look really nice, are easy to implement and won't cause this issue
Here is a link: http://developer.yahoo.com/yui/examples/button/btn_example07.html
You should use event.stopPropagation() while in <select>, or cancelBubble() in <select> element itself.

Categories

Resources