Moving mouse to quickly doesn't trigger mouseleave - javascript

I have the following html:
<div class="guide-block" id="energy_guide">
<div class="guide-block-inner">
<div class="guide-block-head">
<a class="guide-block-link" href="#">
<h3 class="guide-block-title">Guides</h3>
</a>
</div>
<div class="guide-block-image">
<div class="guide-block-image-inner" id="energy_guide">
<img src="images/Energy-Saving-Bulb-01.png" alt="Guide">
</div>
</div>
<div class="guide-block-more">
<ul class="guide-block-list us-list" id="energy_guide">
<li>News</li>
<li>Guides</li>
</ul>
</div>
</div>
</div>
and the following js:
$( "#energy_guide" ).mouseenter(function()
{
$(".guide-block-image #energy_guide")
.fadeOut("fast", function()
{
$(".featured_news .guide-block-inner .guide-block-more #energy_guide")
.fadeIn("fast");
});
});
$( "#energy_guide" ).mouseleave(function()
{
$(".featured_news .guide-block-inner .guide-block-more #energy_guide")
.fadeOut("fast", function ()
{
$(".guide-block-image #energy_guide")
.fadeIn("fast");
});
});
The list is hidden by default in the css and what i want to achieve is to replace the image with the list while hovering the mouse over the whole guide-block div. Everything is fine and dandy until you move your mouse too fast, the mouseleave function not being triggered for some reason.

Just a first idea that hit me was that actually your events are totally fine, rather the way jQuery constructs Animations and builds them in the queue.
a probable fix would be to .stop() your subsequent animations (anim. buildups) so an overall code could look like:
$( "#energy_guide" ).hover(function() {
$(this).stop().fadeToggle();
});
(Without seeing a demo of your code with CSS it's a bit hard to guess but here you go)
The way you use your selectors is wrong:
.featured_news .guide-block-inner .guide-block-more #energy_guide
jQuery will select only #energy_guide and taking in considerations that it's the only ID in your document (as it should be) there's no need to use parent Class selectors.

Related

Handle two slideUp/Down via classes

i've two menus in mobile view of my website. If you click on the hamburger bar, they should slide down/up. This is basically no problem for me.
My HTML looks like this:
...
<div class="foo">
<div class="trigger menu1">
..
</div>
<div class="trigger menu2">
...
</div>
</div>
...
<nav id="main-navi">
...
</nav>
<ul id="info-navi>
...
</ul>
...
At the moment I solved it via jQuery with click-events for every single trigger. Like this...
...
$(".trigger.menu1").click(function() {
...
$("#main-navi").slideDown();
});
$(".trigger.menu2").click(function() {
...
$("#info-navi").slideDown();
...
});
...
This works fine, but I want to use it more easier and without so much code. Isn't it possible to get just an event for the .trigger and refer it just to the class to trigger the menu to slide down?
I tried it with something like, but it doesn't work:
if ($this.hasClass("menu1")) {
$("#main-navi").slideDown();
} else {
$("#info-navi").slideDown();
}
Is there a way to get this working?
Regards,
Markus
You already have solved your problem. Though there are other possible solutions to this, but this code works quite well for your purpose:
$(".trigger").on("click", function(e){
e.preventDefault();
if ($this.hasClass("menu1")) {
$("#main-navi").slideDown();
} else {
$("#info-navi").slideDown();
}
});//.trigger click
You can use HTML5 data-* attribute to achieve this:
$(function() {
$('.trigger').click(function(e) {
e.preventDefault();
$('#' + $(this).attr('data-target')).slideToggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="foo">
<div data-target="main-navi" class="trigger">
Menu Opener 1
</div>
<div data-target="info-navi" class="trigger">
Menu Opener 2
</div>
</div>
...
<nav id="main-navi">
Menu Slide 1
</nav>
<ul id="info-navi">
Menu Slide 2
</ul>
You are heading in the right direction, but you had a small syntax error in your code. Try this:
$('.trigger').on('click', function(){
var isMenu1 = $(this).hasClass('menu1');
if(isMenu1){
$("#main-navi").slideDown();
} else {
$("#info-navi").slideDown();
}
});
$this is incorrect, should have been $(this)
This might help you,
var clickedItem = $(".foo").find('div');
clickedItem.click(function(e){
e.prventDefault();
if($(this).hasClass('menu1')){
$("#main-navi").slideDown();
}else{
$("#info-navi").slideDown();
}
});
Why don't you use slideToggle() jquery function ?
You can find help here http://api.jquery.com/slidetoggle/ .

jQuery .slideToggle() to also close other tabs

I have two sections, each with 3 divs, opening on slideToggle. How can I close the other 2 divs in each section when 1 is open?
https://jsfiddle.net/koteva/mdx20uqe/2/
<div id="stage1">
<h2 id="location-1">Location</h2>
<div id="location-1t">grjryjj</div>
<h2 id="jersey-1">JERSEY </h2>
<div id="jersey-1t" style="display: none;"> ighlgkiuluil </div>
<h2 id="details-1">details</h2>
<div id="details-1t" style="display: none;">fykyuk </div>
</div>
<div id="stage2">
<h2 id="location-2">Location2</h2>
<div id="location-2t">grjryjj</div>
<h2 id="jersey-2">JERSEY2 </h2>
<div id="jersey-2t" style="display: none;"> ighlgkiuluil </div>
<h2 id="details-2">details2</h2>
<div id="details-2t" style="display: none;">fykyuk </div>
</div>
With your jsFiddle, you could replace all your js code with
$('h2').click(function(event){
var $this = $(event.target),
id = $this.attr('id');
if($('#'+id+'t').is(':visible')){ // To not slide up and down if clicking an already open element.
$this.parent().children('div').slideUp();
} else {
$this.parent().children('div').slideUp();
$('#'+id+'t').slideToggle();
}
});
as seen in this jsFiddle. This hides the content inside the same stage when you click a header, assuming you follow the same naming convention throughout your entire html code.
I would however recommend, if you can, to perhaps clean up your html a little.
Look at this jsFiddle for an example.
Unless your code has to have your current structure, I would recommend refactoring it into using similar classes and as such be able to write cleaner code.
$('.header').click(function(event){
var $this = $(event.target);
$this.siblings().slideToggle();
$this.parent().siblings().children('.content').slideUp();
});
Would with the structure in the jsFiddle html provide you with the functionality you want.
If you want to do it in simple way. You can do it as follows. its just one function written. But it is simple and line of code will be increased
$( "#details-2" ).click(function() {
$( "#location-2t").hide( "slow");
$( "#jersey-2t").hide( "slow");
$("#details-2t").show("slow");
});
For more complex div structure and the Ids are in the same format as you have specified in your sample code following code will be very useful.
<script>
$(document).ready(function(){
$("div h2").click(
function() {
var thisId = $(this).attr("id");
$("#"+thisId+"t").show("slow");
$(this).siblings("div").not($("#"+thisId+"t")).hide("slow");
});
});
</script>

jQuery toggleClass conflict

For a new webdesign I have two 50% width slider div's as a menu, and I want to add/remove/toggle the 'open' class with jQuery. On the click of one of the .menul, the #left should have added class .open, unless #right:hover and the other way around. The first time you click it it works, but the second time you click it seems to be that the toggleClass is stuck / not updated... Does anyone know how to fix this?
Here's my HTML:
<div id='home'>
<div class='slide' id='left'>
<div class='wrap'>
<div class='text'><a class='menul' href='#sounds'>Savado <span>Sounds</span></a><br/>
<div class='subtext'>
<a class='menul' href='#artist'>Performing artist</a><br/>
<a class='menul' href='#composer' id='one'>Media Composer</a><br/>
<a class='menul' href='#producer' id='two'>Band Producer</a></div>
</div>
<div class='inner'></div>
<a class='full' href='#home'></a>
</div>
<div class='logo' id='logol'>
<a href='#home'><img src='//savado.nl/new/logo.png' alt='Savado' /></a>
</div>
</div>
<div class='slide' id='right'>
<div class='wrap'>
<div class='text'><a class='menur' href='#designs'>Savado <span>Designs</span></a><br/>
<div class='subtext'>
<a class='menur' href='#management'>Content Management</a><br/>
<a class='menur' href='#portfolio' id='one'>Design Portfolio</a><br/>
<a class='menur' href='#engines' id='two'>Search Engines</a></div>
</div>
<div class='inner'></div>
<a class='full' href='#home'></a>
</div>
<div class='logo' id='logor'>
<a href='#home'><img src='//savado.nl/new/logo.png' alt='Savado' /></a>
</div>
</div>
</div>
And here's my jQuery:
$('.menul').click(function(){
$('#left').addClass('open');
$('#right').removeClass('open');
$('#right').hover(function(){$('#left').toggleClass('open')});
});
$('.menur').click(function(){
$('#right').addClass('open');
$('#left').removeClass('open');
$('#left').hover(function(){$('#right').toggleClass('open')});
});
And here's the fiddle: http://jsfiddle.net/ytexqtyg/2/
Any help would be very much appreciated!
I had another look and you will have to add another class or data attribute to differentiate between an active-and-closed menu and a active-and-open menu or this won't work.
The active "flag" is to ensure you only toggle the .open class on an active menu.
In addition you also need to keep unbinding the hover event as otherwise you are constantly re-binding the hover, causing the element to have multiple hover events bound which then will all execute and contradict each other.
Note that when unbinding the hover event using jQuery off('hover')/unbind('hover') doesn't work and you must unbind the mouseenter and mouseleave events as those are bound by jQuery when using selector.hover(...)
The new JavaScript code is as follows:
$('.menul').click(function () {
$('#left').addClass('active');
$('#left').addClass('open');
$('#right').removeClass('active');
$('#right').off('mouseenter mouseleave').hover(function(){
if($('#left').hasClass('active')){
$('#left').toggleClass('open');
}
});
});
$('.menur').click(function () {
$('#right').addClass('active');
$('#right').addClass('open');
$('#left').removeClass('active');
$('#left').off('mouseenter mouseleave').hover(function(){
if($('#right').hasClass('active')){
$('#right').toggleClass('open');
}
});
});
DEMO - Using a separate indicator for an active menu

jQuery .not not functioning correctly

I'm having a problem with jQuery .not() not working.
I've got a pricing table with 3 products, when you mouse over each of the products a description appears and then disappears on mouse out so far everything works fine.
The problem however is that on page load one of the three products (each held in an <aside>) will have a .selected class applied to it and I need the mouseenter/leave function to not run on this <aside>.
The only caveat is that clicking any of the <button>'s in each <aside> will remove the .selected class from it's current <aside> and apply to the <button>'s <aside> parent (I've not included the JQ for this as it's just a dead simple .addClass).
Code example of what I currently have is below, thanks in advanced.
jQuery
$(".pricing3 aside").not('.selected').mouseenter(function() {
$(".desc", this).stop().slideDown('slow');
})
.mouseleave(function() {
$(".desc", this).stop().slideUp('slow');
});
HTML
<div class="pricing3">
<aside>
<i class="fa fa-clock-o"></i>
<h3>1 Hour Pass</h3>
<p class="desc">Description</p>
<p class="pricing">£XX</p>
<button type="submit">BUY NOW</button>
</aside>
<aside class="selected">
<i class="fa fa-clock-o"></i>
<h3>8 Hour Pass</h3>
<p class="desc">Description</p>
<p class="pricing">£XX</p>
<button type="submit">BUY NOW</button>
</aside>
<aside>
<i class="fa fa-clock-o"></i>
<h3>24-7-365 Access</h3>
<p class="desc">Description</p>
<p class="pricing">£XX</p>
<button type="submit">BUY NOW</button>
</aside>
</div>
Need to use event delegation as the target element selection is based on a dynamic state
$(".pricing3").on('mouseenter', 'aside:not(.selected)', function () {
$(".desc", this).stop().slideDown('slow');
}).on('mouseleave', 'aside:not(.selected)', function () {
$(".desc", this).stop().slideUp('slow');
});
It can be written slightly differently as
$(".pricing3").on({
mouseenter: function () {
$(".desc", this).stop().slideDown('slow');
},
mouseleave: function () {
$(".desc", this).stop().slideUp('slow');
}
}, 'aside:not(.selected)')
As the class is shifting you'd be better off checking for the class inside the event handler
$(".pricing3 aside").on('mouseenter mouseleave', function() {
if ( !$(this).hasClass('selected') ) {
$(".desc", this).stop().slideToggle('slow');
}
});
If I understand you correctly, the problem is that you want the .selected to be removed, and then the mouseenter() to run on it as if it hadn't had the .selected on it in the first place?
If this is the case, you should attach your event handler higher up the DOM tree, and use on() to filter down to the <aside>s This way you can flip/flop the class all you want, and the event handler will work as expected. As it's coded, you are only applying the filter at page load, so the state change of the class has no effect.

how can I remove the subnavigation overlap?

I am trying to create a sub navigation. Right now I have two subnav. When i hover over the first item on the main menu the corresponding submenu appears. But when I hover over the second item the second sub nav appears OVER the first one. How can I write the code so that this does not happen?
url: http://arabic001.com
$(document).ready(function() {
$('#arbNavText01').mouseover(function() {
$('#subNav01').show('slow');
});
$('#subNav01').mouseleave(function() {
$('#subNav01').hide('slow');
});
$('#arbNavText02').mouseover(function() {
$('#subNav02').show('slow');
});
$('#subNav02').mouseleave(function() {
$('#subNav02').hide('slow');
});
})
I just tried the below suggestion from Scott and I am not able to show and hide the submenu on hover. Any ideas of how to solve this problem? Here are my new codes:
html
<div id="menu01" class="menu_item">
<div id="engNavText01">Alphabet</div>
<div id="arbNavText01">الأحرف</div>
<div id="subNav01" style="display:none;">
<a href="colors" class="subNav">
<span style="font-size:26px; cursor:pointer;">قراءة</span</a>
<br>reading<br><br>
</div>
</div>
<div id="menu02" class="menu_item">
<div id="engNavText02">Numbers</div>
<div id="arbNavText02">الأحرف</div>
<div id="subNav02" style="display: none; ">
<a href="colors" class="subNav">
<span style="font-size:26px; cursor:pointer;">قراءة</span</a>
<br>reading<br><br>
</div>
</div>
and the JS
$(document).ready(function() {
$('.menu_item').children().hover(
function(){
$subNav = $(this).parents('menu_item').children("div[id^='subNav'");
if ($subNav.css('display', 'none')){
$subNav.show('slow');
}
},
function(){
$(this).parents('menu_item').children("div[id^='subNav'").hide('slow');
});
})
You've created a mouseleave event, but you've only attached it to the submenu. So in order to make a menu disappear, the user will have to hover over the submenu and then move out. You could achieve what you want by hiding other submenus before opening a new one. So keeping your mouseleave events as you have them, you could modify your 2 mouseover events to this:
$('#arbNavText01').mouseover(function() {
$('#subNav02').hide('slow');
$('#subNav01').show('slow');
});
$('#arbNavText02').mouseover(function() {
$('#subNav01').hide('slow');
$('#subNav02').show('slow');
});
Edit for comment:
I was thinking about that when I went and looked at your page originally. I think if you used a slightly different structure in your html this could be done. Right now your menu divs aren't clearly structurally related to each other so maybe add a div that can contain the 3 elements associated with each menu item.
I'm going to spit ball an idea, it may not even work let alone be the best way.
<div id="menu01" class="menu_item">
<div id="engNavText01">Alphabet</div>
<div id="arbNavText01">الأحرف</div>
<div id="subNav01" style="display: none; ">
<span style="font-size:26px; cursor:pointer;">قراءة</span
<br>reading<br><br>
</div>
</div>
<div id="menu02" class="menu_item">...
Edited JS, I think now it could work
$('.menu_item').hover(
function(){
$subNav = $(this).children("div[id^='subNav']");
if ($subNav.css('display', 'none')){
$subNav.show('slow');
}
},
function(){
$(this).children("div[id^='subNav']").hide('slow');
}
);
Was trying it out with a JSFiddle, seems alright there. Might need some modification for your uses.

Categories