Enforcing order of jQuery UI transitions - javascript

I'm working on a site using Twitter bootstrap and the Ace Admin template.
Dropdown menus are implemented using unordered lists in which each list item is an element in the dropdown.
My user requirement is that the dropdown list show a list of notifications and when a notification is clicked, the list of notifications will slide away and the details of the clicked notification will slide into place. I implement all the content as list items and use jquery-ui's hide and show functions to animate the transitions.
The basic flow is supposed to be:
User Clicks notification -> list of notifications is hidden -> Notification detail is shown.
User Clicks "back on detail -> notification detail is hidden -> Notification List is shown.
For some reason, the first scenario above works fine, but in the second, the notification list starts to show before the details are done being hidden, which results in the parent container getting temporarily taller as both are visible.
Here is how I have the code:
$(".notification-item").click(function (e) {
e.stopPropagation();
var guid = $(e.target).closest("li").attr("data-guid");
$(".notification-item").hide("slide", { direction: "left" }, 250, function () {
// This is called when hiding is complete
// show the back button and detail for the correct notification
$("#notificationsBack").add("li#" + guid).show("slide", { direction: "right" }, 250);
});
});
$("#notificationsBack").click(function (e) {
e.stopPropagation();
$(".notification-detail").hide("slide", { direction: "right" }, 250, function () {
// this functions should run after the hide is complete, but appears to start immediately
$(".notification-item").show("slide", { direction: "left" }, 250);
});
});
I've posted a video of how this looks (with the animation slowed down for better visibility).
Any idea why in the second transition the hide actions doesn't complete before the show action starts?

You need to force the .show() event to happen after the other one. The easiest way to do this is with:
$("#notificationsBack").click(function (e) {
e.stopPropagation();
$(".notification-detail").hide("slide", { direction: "right" }, 250);
setTimeout(function(){
$(".notification-item").show("slide", { direction: "left" }, 250);
}, 250);
});
a setTimeout() call.

Related

Script running only once

I'm trying to make a side menu that opens and closes from the left when you press the menu button.
Got the css, html code running properly but I can't figure out what I'm doing wrong with the script. It works perfectly but only once: When I press the menu button it comes out, press it again and it goes back just as intended. The problem is if I press it again it shows and it goes back by itself. Can anyone help me?
Here is my script:
$(document).ready(function(){
$('.menu-icon').click(function(){
$('#navigator').animate({left:'0px'},200);
$(this).animate({left:'250px'},200);
$('.menu-icon').click(function(){
>$('#navigator').animate({left:'-250px'},200);
>$(this).animate({left:'0px'},200);
});
});
>});
You have placed a click handler inside a click handler so it will run multiple times. Twice first time, then three times, then four times etc.
You need to have a single handler and decide how to animate based on the current state of the element. e.g. something like the following (not tested):
$(document).ready(function () {
$('.menu-icon').click(function () {
if ($('#navigator').css("left") != "0px") {
$('#navigator').animate({
left: '0px'
}, 200);
$(this).animate({
left: '250px'
}, 200);
} else {
$('#navigator').animate({
left: '-250px'
}, 200); > $(this).animate({
left: '0px'
}, 200);
}
});
});
I would suggest testing the "current state" using a class you toggle on the element as testing css values is notoriously unreliable during animation.
e.g. something like:
if ($('#navigator').toggleClass("open").hasClass("open")) {
Here you are attaching the click event listener two times. One normal and one after clicking, thats why its happening use jquery toggle
or use in this way
$(document).ready(function(){
$('.menu-icon').click(function(){
var navigator = $('#navigator');
if(navigator.offset().left == 0)
{
navigator.animate({left:'-250px'},200);
$(this).animate({left:'0px'},200);
}
else
{
navigator.animate({left:'0px'},200);
$(this).animate({left:'250px'},200);
}
});
});

jQuery .not() not working properly

I've looked around and researched why this isn't working, but it seems that I am in a sort of different situation.
I have a default action for a navigation item that handles the navigation animation on hover:
$('.logoCont').hover(function(){
someFunction()...
}, function (){
someFunctionReverse()...
});
Now, when it comes to being on the mobile screen, I hide the navigation and place a button there. The button then controls the animation of the menu sliding out from the side. I've added a line of code that adds a class to the navigation elements when this button is clicked.
$('.mobile-menuButton').click(function(){ //When you click the menu-show button
if($(this).hasClass('menuClosed')){ //Check to see if the menu is closed
$('.nav_hover').addClass('mobile_open'); //Add the mobile_open class to the navigation items
} else {
$('.nav_hover').removeClass('mobile_open'); //remove it
}
});
So then I changed the first hover function to say:
$('.nav_hover').not('.mobile_open').hover(function(){
someFunction()...
}, function (){
someFunctionReverse()...
});
I was hoping this would stop the someFunction() from happening when the mobile menu is out.
You can view what I'm doing HERE - When you reduce the screen to under 540px the media query will take effect and you can click on the menu button.
Documentation on .not() HERE. The second example at the end of the page is exactly what I was hoping for.
The class is added later and the event handler is attached to any and all elements that match the selector at pageload (or whenever it is executed) and doesn't really care about what you add later.
You have to check for the class inside the event handler
$('.nav_hover').hover(function(){
if ( !$(this).hasClass('mobile_open') ) {
someFunction()...
}
}, function (){
if ( !$(this).hasClass('mobile_open') ) {
someFunctionReverse()...
}
});
delegation could also work, but it wouldn't really work with not() or hover()
$(document).on({
mouseenter: function() {
someFunction()...
},
mouseleave: function() {
someFunctionReverse()...
}
}, '.nav_hover:not(.mobile_open)');

Hoverintent/Hover Delay jQuery

Hi all I'm trying to accomplish a few things.
I have an element that is displayed one mouse over, it's essentially a submenu but it is not structured like your traditional submenu would be in that it is no within an 'li' element. What I'm attempting to do is when a user hovers over 'products' the subnav is displayed - this works without issue. However when the user moves their mouse from 'products' to the subnav menu itself I want the submenu to remain and not disappear until both elements (a#products and #banner-top) no longer have a mouseover.
I'm currently using hoverintent to accomplish this because it sounded like it would suit my purposes. I was under the impression the 'out' would not be called just so long as the user remained hovering over one of the elements that the .hoverintent is attached to. I also assumed that the 'out' would not trigger even if the user hovers off the initial element that triggered the '#product-sub-nav' to display just so long as they did it in a short period of time. In other words, the user hovers over 'products' the submenu displays then the user hovers over the submenu in a short period of time thus not triggering the function that attaches a 'hidden' class to the subnav to hide it again. I hope I've done a decent job of explaining what I'm trying to do.
Here is my code
var settings = {
sensitivity: 4,
interval: 75,
timeout: 500,
over: mousein_trigger,
out: mouseout_trigger
};
jQuery('.item-134 a, #product-sub-nav').hoverIntent(settings);
function mousein_trigger() {
jQuery('#banner-top').removeClass('hidden')
}
function mouseout_trigger() {
jQuery('#banner-top').addClass('hidden')
}
UPDATE W/ JS FIDDLE
http://jsfiddle.net/M5BN2/
I just wanted to update this in case someone else had a similar issue. This solution works perfectly: https://stackoverflow.com/a/1670561/1108360
jQuery(".item-134 a, #banner-top").mouseenter(function() { //if mouse is over 'products' link or submenu
//clear timeout
clearTimeout(jQuery(this).data('timeoutId'));
//display sub menu
jQuery('#banner-top').removeClass('hidden');
}).mouseleave(function() { //when mouse leaves element
timeoutId = setTimeout(function() {
//delay hiding sub menu
jQuery('#banner-top').addClass('hidden');
}, 650);
//set the timeoutId, allowing us to clear this trigger if the mouse comes back over
jQuery(".item-134 a, #banner-top").data('timeoutId', timeoutId);
});
Didn't properly update JSfiddle: http://jsfiddle.net/M5BN2/5/

Stop & reenable hover with click

I have a container that fades on a timer when hovered on (#module-container) but when clicking on a .return-news, it stops the hover and keeps it from fading. Now I need it where, when called through a function, I need to allow the hover effect again on the #module-container just like before. Here's the hover code:
var module = $('#module-container');
$('.menu-control').add(module).mouseenter(function() {
module.stop().show();
clearTimeout(window.mtimer);
console.log('hovered');
});
$('.menu-control').add(module).mouseleave(function() {
var time = 3000;
window.mtimer = setTimeout(function() {
module.fadeOut(600);
}, time);
console.log(window.mtimer);
});
By clicking .return-news, I've successfully stopping the hover with this line:
$('.return-news').on('click',function(e) {
e.stopPropagation();
module.add('.menu-control').off('mouseenter').off('mouseleave');
console.log('stop it!');
});
NOT WORKING: If I click .next-video then I need to re-enable the hover (which will then use the mouseeneter and mouseleave functions previously declared). I've tried calling this line but it doesn't work:
$('.next-video').on('click',function(e) {
e.stopPropagation();
module.add('.menu-control').on('mouseenter').on('mouseleave');
});
Later, I'll be having the hover re-enabled by calling it using Vimeo's API (instead of the .next-video click) but for the sake of time, I stripped the code to it's basic functionality.
HERE'S THE CODE ON JSFIDDLE.

jCarousel - Continue Scrolling When At First or Last Item On Button Press

I am encountering an issue with jCarousel whereby if a the carousel has started at the beginning and the left button is pressed the carousel doesn't scroll.
What is supposed to happen is that if the carousels first item is displayed and the left button is pressed, the carousel should circle to the end item. At the moment, this does not happen. The carousel just stops working.
This only happens when the carousel is first loaded.
Example of my code is here: http://jsfiddle.net/wquPu/2/.
Thanks.
I don't know exactly what you are doing wrong, but if you look at the jCarousel demo pages you will find a demo of exactly what you are trying to do and it's very simple code.
http://sorgalla.com/projects/jcarousel/examples/static_auto.html
function mycarousel_initCallback(carousel)
{
// Disable autoscrolling if the user clicks the prev or next button.
carousel.buttonNext.bind('click', function() {
carousel.startAuto(0);
});
carousel.buttonPrev.bind('click', function() {
carousel.startAuto(0);
});
// Pause autoscrolling if the user moves with the cursor over the clip.
carousel.clip.hover(function() {
carousel.stopAuto();
}, function() {
carousel.startAuto();
});
};
jQuery(document).ready(function() {
jQuery('#mycarousel').jcarousel({
auto: 2,
wrap: 'last',
initCallback: mycarousel_initCallback
});
});

Categories

Resources