Issue with element visibility when spamming with hover events - javascript

When I hover over #HoverMe, the #hidden shows, if I un-hover it, #hidden will disapear as intended. However, if I "spamming" with hover-unhover-hover-unhover really fast, it gets bugged so next time I hover #HoverMe, #hiddenthen just disappear instantly. I think there's some kind of timer-loop that mess it up? How do I prevent that?
$("#HoverMe").hover(function() {
$("#hidden").show();
}, function() {
$("#hidden").delay(1000).fadeOut();
});

Use stop(true) to remove any queued animations before starting the next one:
$("#HoverMe").hover(function() {
$("#hidden").stop(true).show();
}, function() {
$("#hidden").stop(true).delay(1000).fadeOut();
});
#hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="HoverMe">Hover me</div>
<div id="hidden">Not hidden!</div>

Related

Add a class on hover remove class on second hover

I want to add a class on hover but not remove it when mouse leaves. Instead it must be removed on the second mouse hover. So on mouse hover add class. Mouse leaves class remains. Mouse hovers again class is removed.
This code adds the class but if the mouse leaves the class is removed which is not what I'm trying to achieve.
jQuery('.menuButton').hover(function(){
jQuery('.mainMenuDrop').addClass('show')
}, function() {
jQuery('.mainMenuDrop').removeClass('show')
});
To achieve your requirement of add on first entry and remove on second entry, you can change your existing code:
jQuery('.menuButton').hover(function(){
jQuery('.mainMenuDrop').addClass('show')
}, function() {
jQuery('.mainMenuDrop').removeClass('show')
});
to use .toggleClass
jQuery('.menuButton').hover(function(){
jQuery('.mainMenuDrop').toggleClass('show')
}, function() {
// nothing here
});
As jquery .hover binding is just syntax for mouseenter and mouseleave and you don't need mouseleave, this can be simplified to:
jQuery('.menuButton').on("mouseenter", function() {
jQuery('.mainMenuDrop').toggleClass('show');
});
div { border: 1px solid black; padding: 20px; width: 100px; }
.show { background-color: pink; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='menuButton'>point at me</div>
<div class='mainMenuDrop'>changes here</div>

how to display a div1 on hovering div2 and fading div1 on mouseout?

I want to display div1 on hovering div2 and disappear div1 only if mouse is not hovering both div1 and div2.
I tried using the following CSS and jquery. But the div1 disappears immadiately after unhovering div2 and i am unable to access the content of div1.
$(document).ready(function() {
$('.about').hover(
function() {
$('.showsection').slideDown(800).addClass('show');
}
, function() {
$('.showsection').slideToggle(800);
});
});
.showsection{
display:none;
}
.show{
display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class=about>
<h1>About</h1>
</div>
<div class="showsection">
<h1>Title</h1>
</div>
This could be done by attaching mouseenter and mouseleave events to the elements you want to show/hide.
These are the requirements:
Show showsection when mouse enters about. This can be done using mouseenter on about
Hide showsection when mouse is not hovering over both showsection and about. This actually means checking two things: the mouse is not hovering showsection when it leaves about and the mouse is not hovering about when it leaves showsection. That means we have to attach mouseleave events to both showsection and about.
The below snippet should help.
// JS
$(document).ready(function() {
// mouse enters .about
$('.about').on('mouseenter', function() {
$('.showsection').slideDown(800);
});
// mouse leaves .about
$('.about').on('mouseleave', function() {
// if mouse is not hovering over .showsection hide it
if (!$('.showsection').is(':hover')) {
$('.showsection').slideToggle(800);
}
});
// mouse leaves .showsection
$('.showsection').on('mouseleave', function() {
// if mouse is not hovering over .about hide .showsection
if (!$('.about').is(':hover')) {
$('.showsection').slideToggle(800);
}
});
});
/* CSS */
.showsection {
display: none;
background: #ddd;
}
h1 { margin: 0; }
.about { background: #eee; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class=about>
<h1>About</h1>
</div>
<div class="showsection">
<h1>Title</h1>
</div>
The CSS :hover attribute will only control the element which it is assigned to, in your case presumable div1. So, you are going to have to use JavaScript.
With JavaScript attach a mouseenter and mouseleave event to div1. Inside those event listener functions, control what you want div2 to do.
That's basically how to do it.

Removing and adding class on hover

I am making a panel of photos/text. All the panels will have an overlay color on them except the first one which has an active class on page load which removes the overlay. As you hover over the second/third etc panels, the overlay active class will remove from first panel and go onto the one that is hovered.
Right now it is only active on page load, I can't seem to get the class off the first div and onto the second div on hover.
if ( $(".overlay:first") ){
$(".overlay:first").addClass("active");
}
else {
if ( $(".overlay:not(:first)").hover ){
$(".overlay:first").removeClass("active");
}
}
https://jsfiddle.net/egdkuh16/3/
There is no need to use JavaScript or jQuery for this. It's best used in CSS with the :hover pseudo-selector. It's also much easier today.
.overlay:first-child {
background: white;
}
.overlay:first-child:hover {
background: gold;
}
If you insist on using jQuery, you can try this
$(".overlay:first").on("mouseover", function() {
$(this).addClass("active");
}).on("mouseout", function() {
$(this).removeClass("active");
});
.active {
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="overlay">First overlay class</div>
<div class="overlay">Second overlay class</div>
This approach is highly frowned upon though
In jQuery, you could do it like this:
$(document).ready(function() {
// Make the first active
$(".overlay:first").addClass("active");
// On hover remove all active classes from .overlay
// and add .active only to the one that is hovered
$(".overlay").hover(function() {
$(".overlay").removeClass("active");
$(this).addClass("active");
});
});
but Richard Hamilton's answer is much better and cleaner.
You can use jQuery's on. For example:
$(".overlay:first").addClass("active");
$(".overlay").on("hover", function(){
$(this).addClass("active");
$(".overlay:first").removeClass("active")
});

jQuery slideDown not functioning correctly

I wish to animate a div to make it appear and slide down with jQuery.
I have got my script to work where you hover over an image and another div slides in, should the user leave the mouse hover, the div will slide up and disappear.
Problem:
The first time i hover over the image, nothing happens. I have to leave my mouse and hover over it a second time for the effect to start working, I dont get why this is???
jQuery:
function show_action(){
$(function(){
$(".action").hide();
$(".logo").hover(
function(){ $(".action").slideDown(); },
function(){ $(".action").slideUp(); }
);
});
}
CSS:
#action_text{
display:none;
}
HTML:
<div class="center_container">
<div class="action" id="action_text"><span>Click To Upload</span></div>
<img src="images/logo.png" class="logo" onmouseover="show_action();">
</div>
No need to call .hide() on the .action element. Just give it display: none in your css, so that it will not show when the page loads. That way, you don't need the .stop() to clear the animation queue, and it also prevents a 'flicker' effect where your .action element will show up when the page loads for a brief moment until .hide() gets called.
$(document).ready(function() {
$('.logo').hover(
function() {
$(".action").slideDown();
},
function() {
$(".action").slideUp();
}
);
});
.action {
width: 100%;
background-color: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="logo">LOGO</span>
</div>
<div class="action">
<span>Action</span>
</div>
I think you are calling function show_action as onhover="show_action() remove that and move the rest code outside function wrapping, otherwise the hover() event handler will only bind after the first hover. additionally use stop() to clear the animation queue
$(function() {
$(".action").hide();
$(".logo").hover(
function() {
$(".action").stop().slideDown();
},
function() {
$(".action").stop().slideUp();
}
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class=logo>Hover here</div>
<div class=action>content<br>here</div>
Update : You can remove $(".action").hide(); by adding following css
.action {
display: none;
}

Select <divs> within parent <div> using jQuery

I have a parent <div>, #amwcontentwrapper, which has a series of divs within it with their own classes and ids.
I want to use jQuery to select these child divs, and IF they have the class .amwhidden, do nothing, but if not, remove the .amwshown class and add the .amwhidden class.
This is what I have so far, but it is not working. I think it may be my selecting of the child divs within the parent.
Can anybody see any obvious problems? Thanks for your help.
if ($('#amwcontentwrapper > div').hasClass('amwhidden')){
} else {
$('#amwcontentwrapper > div').fadeIn(600, function(){
$('#amwcontentwrapper > div').removeClass('amwshown');
$('#amwcontentwrapper > div').addClass('amwhidden');
});
}
And here is the basic html that I am using:
<div class="amwshown" id="amwintro">
Intro Section, which should have the 'amwshown' class removed, and the
'amwhidden' class added, when the jQuery runs. Currently, this does not happen.
</div>
UPDATE: Using War10ck's solution in the comments below (i.e. $('#amwcontentwrapper > div.amwshown')) I have managed to get the classes changing as I wished. However, those which have had the .amwshown class removed and .amwhidden class added still show on the page, despite the CSS looking like this:
.amwhidden {
display:none;
}
.amwshown {
display:block;
}
Looking at the Dev Tools, it seems that, when the jQuery is run (on a click event) the classes are changing, but any classes which are having the .amwshown class added (thus displaying them on the page) are also having the a <style> tag added to them which makes them display:block;
When I then press another button, which should hide the aformentioned <div> to make way for another one, the class is being changed to .amwhidden, but that <style> tag is not being deleted, so even though it has the .amwhidden class, it is still on the page.
I've created a JSFiddle here, if anybody still wants to help!
`
$(document).ready(function() {
$('#buybutton').click(function() {
$('#amwcontentwrapper > div.amwshown').fadeIn(600, function() {
$(this).removeClass('amwshown').addClass('amwhidden');
});
if ($('#amwbuy').hasClass('amwshown')) {} else {
$('#amwbuy').fadeIn(600, function() {
$('#amwbuy').removeClass('amwhidden');
$('#amwbuy').addClass('amwshown');
});
}
});
$('#phdbutton').click(function() {
$('#amwcontentwrapper > div.amwshown').fadeIn(600, function() {
$(this).removeClass('amwshown').addClass('amwhidden');
});
if ($('#amwphd').hasClass('amwshown')) {} else {
$('#amwphd').fadeIn(600, function() {
$('#amwphd').removeClass('amwhidden');
$('#amwphd').addClass('amwshown');
});
}
});
});
#sidebar {
position: absolute;
left: 1%;
top: 1%;
font-size: 5em;
color: #000000;
width: 10%;
display: block;
background-color: red;
}
#amwcontentwrapper {
position: absolute;
left: 20%;
top: 5%;
}
.amwshown {
display: block;
}
.amwhidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="amwsidebar">
<span class="sidebarbutton" id="phdbutton">PhD Button</span>
<br />
<br />
<span class="sidebarbutton" id="buybutton">Buy Button</span>
</div>
<div id="amwcontentwrapper">
<div class="amwshown" id="amwintro">
<p>An intro section to welcome the visitor. Disappears when one of the other sections is clicked.</p>
<br />
<br />
</div>
<div class="amwhidden" id="amwbuy">
Buy Section
</div>
<div class="amwhidden" id="amwphd">
PhD Section
</div>
</div>
`
You can use not to remove the elements you do not want, like this:
$('#amwcontentwrapper > div').not('.amwhidden')
.removeClass('amwshown')
.addClass('amwhidden');
And work with that.
Try this
$(document).ready(function() {
$("#amwcontentwrapper").children().each(function(elem, x) {
if ($(x).attr("class") == "amwhidden") {
alert($(x).attr("class"));
$(x).removeClass("amwhidden").addClass("amwshow");
alert($(x).attr("class"));
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="amwcontentwrapper">
<div class="amwhidden"></div>
<div></div>
<div></div>
</div>
You can try each as follow,
$("#amwcontentwrapper div").each(function(){
if($(this).hasClass('amwhidden'))
//DO something
else
//DO something
});
Thank you for all help, it has prompted some brainstorming which has solved this issue.
Instead of adding the .amwhidden class and removing the .amwhidden class using jQuery, I have just created a .amwsection class, which all the sections belong to which has an initial display value of none. So far, so good; all of the sections are not there when you load up the page.
Then I use the .css jQuery function to change the display:none to display:block when the corresponding button is clicked, and changing all other .amwsections to display:none. This works just fine, but the effect is quite abrupt; there is no fading in, as you would get if you used the .animate function. .animate, however, does not work with the display value.
.fadeOut and .fadeIn to the rescue! By wrapping the .css change in these, I can create a fading in/out effect and can still use the display value.
Here is one example of this code.
The #buybutton is the button to be pressed.
#amwintro is just something which appears when the page loads - it will now be set to display:none if this is the first button pressed.
The .amwsection are all of the hidden sections. This portion of the code just resets all of them. This and the #amwintro section happen very quickly (1/100th of a second) to keep response time good.
The #amwbuy is the specific section that I want to reveal. As you can see, this fades in over a longer period.
Currently only tested in Chrome, but I think I've got it!
$(document).ready(function () {
$('#buybutton').click(function() {
$('#amwintro').fadeOut(1, function() {
$(this).css({
display:'none',
});
});
$('.amwsection').fadeOut(1, function() {
$(this).css({
display:'none',
});
});
$('#amwbuy').fadeIn(600, function() {
$(this).css({
display:'block',
});
});
});
});

Categories