I want to create a flashing effect. When user click the flashing element, it will be disappeared. However, it seems not every "user's click" can fire the "click event". Sometimes, when I clicked the flashing element, it didn't disappear. I thought the reason is a hidden element can not be clicked. Just like this article says CSS: Is a hidden object clickable?. So, is there other methods to make the flashing element disappeared immediately when user clicks the element?
var flashToggle = setInterval(function() {
$("div").toggle();
}, 200)
$("div").on("click", function(e) {
clearInterval(flashToggle);
$(this).hide();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Flashing element</div>
Put the flashing element inside another element, and put the handler on that parent element. Also, you might change the visibility property of the flashing element, not the display of the flashing element, so that it doesn't change the layout of your page every time it appears or disappears.
const child = $('#child');
let visible = true;
var flashToggle = setInterval(function() {
visible = !visible;
child.css('visibility',
visible
? 'visible'
: 'hidden'
);
}, 500)
$("#container").on("click", function(e) {
clearInterval(flashToggle);
$(this).hide();
})
div {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="child">Flashing element</div>
</div>
Yes, hidden/toggle will hide elements by setting the css display. When hidden, elements can not receive clicks. You can try the following:
Use .css('visibility','hidden|visible') instead. This is recommended as it does not have the side effect of changing container size and causing jiggling of other elements.
Wrap your flashing element inside a container element, register the click on the container element instead.
$(this).hide(); ---> $("div").hide();
I think this might be what you're looking for: $("my-element").click()
Try to use opacity : 0|1 instead of display: none / visibility: hidden.
On click event on opacity: 0 worked for me.
It worked for me.
Related
I have a dropdown menu inside a DIV.
I want the dropdown to be hide when user click anywhere else.
$('div').blur(function() { $(this).hide(); }
is not working.
I know .blur works only with <a> but in this case what is the simplest solution?
Try using tabindex attribute on your div, see:
Check this post for more information and demo.
I think the issue is that divs don't fire the onfocusout event. You'll need to capture click events on the body and then work out if the target was then menu div. If it wasn't, then the user has clicked elsewhere and the div needs to be hidden.
<head>
<script>
$(document).ready(function(){
$("body").click(function(e) {
if(e.target.id !== 'menu'){
$("#menu").hide();
}
});
});
</script>
<style>#menu { display: none; }</style>
</head>
<body>
<div id="menu_button" onclick="$('#menu').show();">Menu....</div>
<div id="menu"> <!-- Menu options here --> </div>
<p>Other stuff</p>
</body>
$("body").click(function (evt) {
var target = evt.target;
if(target.id !== 'menuContainer'){
$(".menu").hide();
}
});
give the div an id, for instance "menuContainer". then you can check by target.id instead of target.tagName to make sure its that specific div.
Not the cleanest way, but instead of capturing every click event on the page you could add an empty link to your div and use it as a "focus proxy" for the div.
So your markup will change to:
<div><a id="focus_proxy" href="#"></a></div>
and your Javascript code should hook to the blur event on the link:
$('div > #focus_proxy').blur(function() { $('div').hide() })
Don't forget to set the focus on the link when you show the div:
$('div > #focus_proxy').focus()
I just encountered this problem.
I guess none of the above can fix the problem properly, so I post my answer here. It's a combination of some of the above answers:
at least it fixed 2 problems that one might met by just check if the clicked point is the same "id"
$("body").click(function(e) {
var x = e.target;
//check if the clicked point is the trigger
if($(x).attr("class") == "floatLink"){
$(".menu").show();
}
//check if the clicked point is the children of the div you want to show
else if($(x).closest(".menu").length <= 0){
$(".menu").hide();
}
});
.click will work just fine inside the div tag. Just make sure you're not over top of the select element.
$('div').click(function(e) {
var $target = $(e.target);
if (!$target.is("select")) { $(this).hide() };
});
I have some overlay elements which are display: none initially but turn to display: inline when I hover over specific items on the page, and disappear again when the mouse hovers over something else. Exactly same behavior as tool-tips with the difference that this overlay objects have clickable and interactive elements (such as a jquery accordion).
Everything works perfectly, until I interact with these overlay elements, i.e. click on one of the clickable items in the overlay element. Then, once that overlay item becomes display:none again, the page becomes extremely laggy in terms of how long it takes when I hover over an item to find its corresponding overlay element (they are selected by their id) and for it to appear and disappear.
The strange thing is that if I click anywhere on the html body, the lag disappears and everything becomes fast as in the beginning.
Out of despair, I have tried to programmatically call blur, focus, trigger('click') once the overlay element is set back to display:none but none has helped so far, and I have to manually click on the page for the lag to go away.
Any idea what causes such behavior and how I can fix it? thanks,
Edit: code
CSS part:
span.overlay {
z-index:10;
display:none;
position:absolute;
}
span.visible { display:inline; }
HTML part: lots of such span elements, each with their own unique id.
<span class='overlay ui-widget-content' id='xyz'>
<!-- lots of stuff here -->
</span>
javascript part:
/* displays overlay element when user hovers over the first td */
$('table.foo > tbody > tr > td:first-child').hover(
function(e) {
$(this).parent().tooltip('disable');
var elem = $('#' + $(this).parent().data('overlay-id'));
if (!elem.hasClass('visible')) {
elem.css('left', e.pageX + 20).css('top', e.pageY).addClass('visible');
elem.find('.accordion:first').accordion('refresh');
}
}, function() {
var elem = $('#' + $(this).parent().data('overlay-id'));
if (! elem.is(':hover') && ! elem.hasClass('pin')) {
$(elem).removeClass('visible');
}
$(this).parent().tooltip('enable');
});
/* if mouse leaves span.visible and it is not pinned it will hide the span */
$('body').on('mouseleave', 'span.visible',
function() {
if (!$(this).hasClass('pin')) {
$(this).removeClass('visible');
}
});
Edit: profiling the code, it seems that get offsetHeight and get offsetWidth take way longer than before. Yet I do not know why this should happen and why it should go away by clicking on the page.
previously, when I do not observe the problem, these two functions each take less than 3%.
try binding the mouseleave event upon opening the "tooltip". Replace your code with this (not tested):
/* displays overlay element when user hovers over the first td */
$('table.foo > tbody > tr > td:first-child').on('mouseenter',
function(e) {
$(this).parent().tooltip('disable');
var elem = $('#' + $(this).parent().data('overlay-id'));
if (!elem.hasClass('visible')) {
elem.css('left', e.pageX + 20).css('top', e.pageY).addClass('visible');
elem.find('.accordion:first').accordion('refresh');
// notice the "ONE" handler, it'll unbind the event after execution
elem.one('mouseleave', function() {
if (!$(this).hasClass('pin')) {
$(this).removeClass('visible');
}
$(this).parent().tooltip('enable');
});
}
}
);
Notice the one listener to unbind the event after it's first execution.
I can't guarantee that this will fix your issue but I experienced lots of performance hits when a page has A LOT of elements and browsers need to check hover events that change very quickly.
This way the browser only needs to check one mouseleave event. And if it happened, it's gone again. It seems you may have too many bound events and don't clean them up properly.
I'm not sure if I replicated your desired functionality correctly so please add code if I missed something. I was unsure why exactly you'd need to bind a mouseleave event via body AND via .hover().
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.
I have following code:
HTML:
<div class="one">Content</div>
<div class="two">Content</div>
I want to hide my second div when mosueleave event happen from first div and also the mouse don't have over second div.
Algorithm:
if ((mouseleave from div.one) && (mouse not on div.two))
hide (div.two);
How can I implement this snippet using jquery? please help me.
You can set a flag on the .two div that keeps track of the mouseover state. Then when the mouse leaves .one you check for this state and if it exists you hide the div. Like so:
$(".two").live("mouseenter", function(){
$(this).data("hover", true);
}).live("mouseleave", function(){
$(this).removeData("hover");
});
$(".one").live("mouseleave", function(){
if( !$(".two").data("hover") ) $(".two").hide();
});
enclose both divs in another, say, div class='zero'. so you would have something in your $(document).ready() like
$('.zero').live('hover', function() {
$('.two').show();
});
$('.zero').live('blur', function() {
$('.two').hide();
});
note: you must style="display: none" for div class='two' by default
I have a dropdown menu inside a DIV.
I want the dropdown to be hide when user click anywhere else.
$('div').blur(function() { $(this).hide(); }
is not working.
I know .blur works only with <a> but in this case what is the simplest solution?
Try using tabindex attribute on your div, see:
Check this post for more information and demo.
I think the issue is that divs don't fire the onfocusout event. You'll need to capture click events on the body and then work out if the target was then menu div. If it wasn't, then the user has clicked elsewhere and the div needs to be hidden.
<head>
<script>
$(document).ready(function(){
$("body").click(function(e) {
if(e.target.id !== 'menu'){
$("#menu").hide();
}
});
});
</script>
<style>#menu { display: none; }</style>
</head>
<body>
<div id="menu_button" onclick="$('#menu').show();">Menu....</div>
<div id="menu"> <!-- Menu options here --> </div>
<p>Other stuff</p>
</body>
$("body").click(function (evt) {
var target = evt.target;
if(target.id !== 'menuContainer'){
$(".menu").hide();
}
});
give the div an id, for instance "menuContainer". then you can check by target.id instead of target.tagName to make sure its that specific div.
Not the cleanest way, but instead of capturing every click event on the page you could add an empty link to your div and use it as a "focus proxy" for the div.
So your markup will change to:
<div><a id="focus_proxy" href="#"></a></div>
and your Javascript code should hook to the blur event on the link:
$('div > #focus_proxy').blur(function() { $('div').hide() })
Don't forget to set the focus on the link when you show the div:
$('div > #focus_proxy').focus()
I just encountered this problem.
I guess none of the above can fix the problem properly, so I post my answer here. It's a combination of some of the above answers:
at least it fixed 2 problems that one might met by just check if the clicked point is the same "id"
$("body").click(function(e) {
var x = e.target;
//check if the clicked point is the trigger
if($(x).attr("class") == "floatLink"){
$(".menu").show();
}
//check if the clicked point is the children of the div you want to show
else if($(x).closest(".menu").length <= 0){
$(".menu").hide();
}
});
.click will work just fine inside the div tag. Just make sure you're not over top of the select element.
$('div').click(function(e) {
var $target = $(e.target);
if (!$target.is("select")) { $(this).hide() };
});