Delaying a drop down menu from hiding - javascript

Thanks to you guys, my menu is now usable because the submenu displays long enough for the user to get their mouse to the links. Unfortunately, it's not exactly right. The submenu closes even when the users mouse is over it. I have added the HTML code below along with the revised js file code. I'm thinking the problem is in the $('.myMenu > li').bind('mouseout', closeSubMenu); line. Perhaps an alternative would be to have a timeout delay AFTER the openSubMenu function is called to at least give users 8 seconds or so before the submenu hides. This would be an acceptable solution to me.
<!-- HTML menu code below -->
<ul class="myMenu">
<li class="menuHeader">Employees <img src="images/arrowdown.gif" alt="Employee Links" width="11" height="8" border="0"/>
<ul class="subMenu">
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
<li>Link4</li>
</ul></li>
</ul>
<!-- js file code below -->
$(document).ready(function() {
$('.myMenu > li').bind('mouseover', openSubMenu);
$('.myMenu > li').bind('mouseout', closeSubMenu);
function openSubMenu() {
$(this).find('ul').css('visibility', 'visible');
};
function closeSubMenu() {
var ul = $(this).find('ul');
setTimeout(function(){
ul.css('visibility', 'hidden');}, 10000);
};
});

Your setTimeout callback did nothing, you should put the code in the callback function.
setTimeout is not something like sleep.
function closeSubMenu() {
var ul = $(this).find('ul');
setTimeout(function(){
ul.css('visibility', 'hidden');
}, 2000);
};

try something like that. if you toggle to hide, then it'll delay for 3 sec before hide. if the toggle to show, $('#toggle-item') will clear the queue and show the item,
function toggle(show){
if (show) {
$('#toggle-item').stop().clearQueue().show();
} else {
$('#toggle-item').delay(3000);
}
}

the setTimeout command works like this setTimeout(the function to execute, delay in milliseconds)
so, this is what you need to do:
setTimeout($(this).find('ul').css('visibility', 'hidden'),3000);
note that from $(this) to 'hidden') is the actual command. if that doesn't work, try this instead:
//place this in your <head> section
function closeDropDownFunction() {
$(this).find('ul').css('visibility', 'hidden');
}
//then place this wherever the timeout needs to be
setTimeout(closeDropDownFunction(), 3000);

Related

animated effect for fadein/fadeout using jQuery

To understand my code please visit this page:
Please click on packaging filter first
http://codepen.io/mariomez/pen/qNrzAr?editors=0010
It's a simplified animated filtering method.
Each red box might have more than one classes as an identifier for the filter.
My goal with this code is to achieve a nice animated way for fade-in and for fade-out. For now I managed to do this only for fade-in.
Even though I wrote the animation for fade-out I can't use it properly in the JS code.
Example for 1 filter: I want all classes except "packaging" to fade-out nicely and have the packaging class fade-in.
jQuery CODE
$(document).ready(function(){
$(".filter-logo").click(function(){
$(".all").fadeOut(normal,addClass('animated fadeOutEffect'));
$(".logo").fadeIn(normal,addClass('animated fadeInEffect'));
});
$(".filter-website").click(function(){
$(".all").fadeOut();
$(".website").fadeIn().addClass('animated fadeInEffect');
});
$(".filter-packaging").click(function(){
$(".all").fadeOut();
$(".packaging").fadeIn().addClass('animated fadeInEffect');
});
$(".filter-forsale").click(function(){
$(".all").fadeOut();
$(".forsale").fadeIn().addClass('animated fadeInEffect');
});
$(".filter-all").click(function(){
$(".all").fadeOut();
$(".logo, .website, .packaging, .forsale, .all").fadeIn().addClass('animated fadeInEffect');
});
});
Trying to use the fade-in animation: (FAILED)
$(".all").not('.packaging').fadeOut().addClass('animated fadeOutEffect');
$(".packaging").fadeIn().addClass('animated fadeInEffect');
});
How can I improve this code?
I have updated your example.
http://codepen.io/jammer99/pen/mEQabN
Essentially you need to set fadeout to finish within 0 seconds forcefully, additionally since you have already used css to generate the animation, you should use hide() and show() instead of fadeOut() and fadeIn()
here's the updated code
$(document).ready(function() {
$(".all").each(function() {
$(this).addClass("animated")
})
$(".filter-logo").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect").hide(0);
$(".logo").show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
});
$(".filter-website").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect").hide(0)
$(".website").show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
});
// UPDATE CODE - START ////////////
$(".filter-packaging").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect").hide(0);
$(".packaging").show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
});
// UPDATE CODE - END ////////////
$(".filter-forsale").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect").hide(0);
$(".forsale").show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
});
$(".filter-all").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeOutEffect').addClass("fadeInEffect").show(0)
});
});
EDIT : Here is updated code. http://codepen.io/jammer99/pen/mEQabN?editors=0010
$(document).ready(function() {
$(".all").each(function() {
$(this).addClass("animated")
})
$(".filter-logo").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect")
setTimeout(function() {
$(".all").hide(0)
$(".logo").stop().show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
}, 500);
});
$(".filter-website").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect")
setTimeout(function() {
$(".all").hide(0)
$(".website").stop().show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
}, 500);
});
$(".filter-packaging").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect")
setTimeout(function() {
$(".all").hide(0)
$(".packaging").stop().show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
}, 500);
});
$(".filter-forsale").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect")
setTimeout(function() {
$(".all").hide(0)
$(".forsale").stop().show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
}, 500);
});
$(".filter-all").click(function(e) {
e.preventDefault();
$(".all").removeClass('fadeInEffect').addClass("fadeOutEffect")
setTimeout(function() {
$(".all").show(0).removeClass("fadeOutEffect").addClass('fadeInEffect');
}, 500);
});
});
For your Example for 1 filter, you're saying you want "packaging" to be the only one to not fade out, but then have "packaging" fade in even though it didn't fade out?
I'm going to assume you want everything to fade out, then have "packaging" fade in. You can do so by calling the fadeIn for "packaging" inside a callback when you fadeOut .all.
Edit:
So the fadeOut function takes a completion callback, a function that will run after the fadeOut animation completes. You just need to pass in an anonymous function to the fadeOut parameter, and inside that function do what you want to do after the animation completes:
$(".filter-packaging").click(function(){
$(".all").fadeOut(function() {
$(".packaging").fadeIn().addClass('animated fadeInEffect');
});
});
Basically your css and js animations are clashing. You should probably stick to one or the other. Also both js animations are running at the same time fadeIn and fadeOut.
An option is to wait until the fadeOut animation ends before starting the fadeIn animation. You can do that with a timeout.
In the example below the function hideThenShow waits until the of the fadeOut animation (500ms) then runs the fadeIn on the selected elements.
As a bonus you could loop through your filters and your list elements instead of repeating the hideThenShow function in the example.
Hope it helps
function hideThenShow($clickedElement, $elementsToShow){
var duration = 500;
$clickedElement.click(function(){
$('.all').fadeOut(duration);
setTimeout(function(){
$elementsToShow.fadeIn();
},duration);
});
}
$(document).ready(function(){
var filterLogo = $(".filter-logo");
var filterWebsite = $(".filter-website");
var filterPackaging = $('.filter-packaging');
var filterForsale = $('.filter-forsale');
var filterAll = $(".filter-all");
var websiteElemetns = $('.website');
var logoElements = $(".logo");
var packagingElements = $('.packaging');
var forsaleElements = $('.forsale');
var allElements = $(".all");
hideThenShow(filterLogo, logoElements);
hideThenShow(filterWebsite, websiteElemetns);
hideThenShow(filterPackaging, packagingElements);
hideThenShow(filterForsale, forsaleElements);
hideThenShow(filterAll, allElements);
});
.ullist li {width:100px;background:#f00; height:100px; display:block; float:left;clear:none; margin:25px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="secmenu">
<ul>
<li>All</li>
<li>Logo</li>
<li>Website</li>
<li>Packaging</li>
<li>For sale</li>
</ul>
</div>
<ul class="ullist">
<li class="website all">text</li>
<li class="website all">text</li>
<li class="website all">text</li>
<li class="packaging all">text</li>
<li class="packaging all">text</li>
<li class="logo all">text</li>
<li class="logo all">text</li>
<li class="logo all">text</li>
<li class="logo all">text</li>
<li class="logo all">text</li>
<li class="forsale all">text</li>
</ul>

Bootstrap nav-tabs with progress bar

I am building a registration system and I have a progress bar and a bootstrap nav-tabs in that page.
I am trying to setup the JQuery so that the progress bar advances with the nav-tabs. Here is a visual.
I tried to come up with a simple if else conditional jquery using hasClass and addCLass functions but never got to make a dent.
Something like this:
$(document).ready(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if (".nav-tabs") hasClass(".active"); {
$(".checkout-bar li").addClass("active");
}
});
});
I am attaching a CODEPEN
Any idea on how to do this client side? I'd rather keep C# out of this one
http://jsfiddle.net/o3637uwh/2/ (update)
in html remove class form all checkout-bar li, except first
HTML
<ul class="checkout-bar">
<li class="active">Get Started</li>
<li class="">About You</li>
<li class="">Looking For</li>
<li class="">Review</li>
</ul>
JQ (update)
$(document).ready(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var href = $(e.target).attr('href');
var $curr = $(".checkout-bar a[href='" + href + "']").parent();
$('.checkout-bar li').removeClass();
$curr.addClass("active");
$curr.prevAll().addClass("visited");
});
});
You are not specifying which .checkout-bar li to select. You have to get the index of the .active tab and with this index select the checkount li, I think you shoud do something like this:
$(document).ready(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
activeTabIndex = $('.nav.nav-tabs > li.active ').index();
(".checkout-bar li.active").removeClass('active');
$(".checkout-bar li:eq("+activeTabIndex+")").addClass('active')
});
});

Fire 2 actions with ONE click on a button

I'm trying to assign two actions to a button in jQuery. The button is supposed to:
open a hidden div, and...
scroll down to get said div into view.
While both actions are working on the button, they currently require 2 clicks. On the first click the div appears, but to scroll it into view I need to click the button a second time.
Any suggestions how I am going wrong?
jQuery
$(document).ready(function () {
"use strict";
$('.footer a').click(function (event) {
event.preventDefault();
$('.impr-text').hide(); // hide previous popup div
var id = $(this).data("id"); // get the div id which to show
$('#' + id).fadeIn(function () { // show cuurent click link's popup
$(this).css({
'display': 'block'
});
});
$.scrollTo( '#impressum-footer', 800, {easing:'elasout'} );
});
});
HTML
<div id="impressum-footer">
<div class="footer">
<div class="inner-wrap-imp">
<ul class="impressum-links">
<li>Impressum</li>
<li>|</li>
<li>Datenschutz</li>
<li class="impressum-button" ></li>
</ul>
</div>
</div>
<div id="impr-text" class="impr-text">
<div class="inner-wrap"> ...
You need to put the scrollTo in the fadeIn completion callback handler. That way callTo is performed on completion of the fadeIn rather than, essentially, at the same time. Currently you seem to also be placing a callback function where another parameter is to go (either duration or options object depending on which method signature you are using). Not sure why you have the css change there at all.
Try something like this:
$(document).ready(function () {
"use strict";
$('.footer a').click(function (event) {
event.preventDefault();
$('.impr-text').hide(); // hide previous popup div
var id = $(this).data("id"); // get the div id which to show
$('#' + id).fadeIn({
duration: 100, // or whatever duration you want to use
complete: function() {
$.scrollTo( '#impressum-footer', 800, {easing:'elasout'} );
}
});
});
});
if you want to assign 2 different actions on one button, set it 2 different classes (or IDs), lets say
<div class="action1 action2">
After, in jQuery you will be able to do:
$('.action1').on('click', function (e) { console.log('#1'); ... });
$('.action2').on('click', function (e) { console.log('#2'); ... });
JsFiddle: http://jsfiddle.net/g2wdd2cb/
I have now managed to get it going. The approach as explained by #euvl was the one...
I changed my code (the scrolling part) after I realized it wasn't working. The final (working) code now looks like this:
jQuery:
$(document).ready(function () {
"use strict";
$('.footer-action-1 a').click(function (event) {
event.preventDefault();
$('.impr-text').hide(); // hide previous popup div
var id = $(this).data("id"); // get the div id which to show
$('#' + id).fadeIn(function () { // show cuurent click link's popup
$(this).css({
'display': 'block'
});
});
});
});
$(document).on('click','.footer-action-2 a', function(event) {
event.preventDefault();
var target = "#" + this.getAttribute('data-target');
$('html, body').animate({
scrollTop: $(target).offset().top
}, 2000);
});
HTML:
<div id="impressum-footer">
<div class="footer footer-action-1 footer-action-2">
<div class="inner-wrap-imp">
<ul class="impressum-links">
<li>Impressum</li>
<li>|</li>
<li>Datenschutz</li>
<li class="impressum-button" ></li>
</ul>
</div>
</div>
<div id="impr-text" class="impr-text">
<div class="inner-wrap">
The only problem now is that it scrolls a little too far. The moment I add an offset it stops working.

Having trouble with jQuery toggle function for dropdown menu

I have a dropdown menu that slides up and down when toggled to reveal it's menu items. The problem is that when i go to click one of the menu items after the menu has slid down, it is recognized as a toggle and the menu slides up without opening the link of the menu item.
HTML
<li class="dropdown">
Carbohydrates, proteins & fats
<ul>
<li>Carbohydrates</li>
<li>Proteins</li>
<li>Fats</li>
</ul>
</li>
dropdown script:
$(document).ready(function () {
$('.dropdown').toggle(
function () {
//show its submenu
$('ul', this).slideDown(300);
},
function () {
//hide its submenu
$('ul', this).slideUp(300);
}
);
});
I'd appreciate any help with this.
Try moving the triggering link outside of the dropdown items
Carbohydrates, proteins & fats
<div class="divdropdown">
<ul>
<li>Carbohydrates</li>
<li>Proteins</li>
<li>Fats</li>
</ul>
</div>​
And then slightly modify your jquery
$(document).ready(function () {
$('.dropdown').toggle(
function () {
//show its submenu
$('ul', $(".divdropdown")).slideDown(300);
},
function () {
//hide its submenu
$('ul', $(".divdropdown")).slideUp(300);
}
);
});​
Why are you individually closing/opening the menu items? Everything gets hidden anyway when the parent <li> element is hidden -- why do anything after that?
I think you want to disable event bubbling.
EDIT 1: You're over-complicating things. Try this:
$(document).ready(function () {
$('.dropdown').toggle();
});
EDIT 2: Can you be more specific about what you want? If you want a particular element, when clicked, to control the motion of a particular list, try this:
$(document).ready(function () {
$('a.someLink').click(function() {
$('.dropdown').toggle();
});
});
Unfortunately none of the above answers were working for me. I found a solution shortly afterwards.
HTML
<li class="dropdown">
<a class="disablelink" href="#">Carbohydrates, proteins & fats</a>
<ul class="sub_navigation">
<li>Carbohydrates</li>
<li>Proteins</li>
<li>Fats</li>
</ul>
</li>
jquery script
$(document).ready(function() {
$('.dropdown').click(function() {
// When the event is triggered, grab the current element 'this' and
// find it's children '.sub_navigation' and display/hide them
$(this).find('.sub_navigation').slideToggle();
});
$(".disablelink").click(function(e) {
e.preventDefault();
});
});
That solution is working perfectly for me. I added in e.preventDefault(); to stop the page jumping up and down when i clicked on the link.

Adding delay to mouse out function

I have one drop down menu,
<ul>
<li><a>link 1</a>
<ul><li><a>link 1</a></li></ul>
</li>
</ul>
I am using the following JS to use hover and show child menus.
I want to add delay to the mouse out function (when the class of the LI removed) about 500ms,
$('li').hover(function(){
$(this).addClass('over');
}, function(){
$(this).removeClass('over');
});
Please do needful in this.
thanks in advance
You can do something like this:
$('li').hover(function(){
var timer = $(this).data('timer');
if(timer) clearTimeout(timer);
$(this).addClass('over');
}, function(){
var li = $(this);
li.data('timer', setTimeout(function(){ li.removeClass('over'); }, 500));
});
This clears any timeout when hovering over it (in case you hover, leave, hover back you need to check this) and sets a 500ms delay when leaving the hover, storing the timeout ID on the li itself using .data().
$('li').hover(function(){
$(this).addClass('over');
}, function(){
setTimeout(function(){$(this).removeClass('over')}, 500);
});

Categories

Resources