I have no idea what I've done. The idea is to animate an element to slide in from a position and slide back when another element has been click. I've applied the second event within the call back of the original event function.
But, despite this structure, the second event function will run although I've not clicked the second element in the callback function.
If you're not following, the basic idea is this.
Click -> slidein -> outside click -> slide out
$('#mobileList').click(function(){
$('#mobileMenu').css({'display':'block'}).animate({
'left':'30%'
},500,function(){
$('#body').click(function(){
$('#mobileMenu').animate({
'left':'100%'
},500,function(){$('#mobileMenu').css({'display':"none"});/* I tried return false; here, failed to solve problem*/});
});
});
});
Starting CSS
nav#mobileMenu{display:none;width:70%;height:100%;background:#191820;color:#DCDCDC;position:fixed;top:0;left:100%;}
How the elements are structured.
<div id="body">
<a id="mobileList>☰</a>
<!-- content here -->
</div>
<nav id="mobileMenu">
<!-- content -->
</nav>
On the first two attempts it works fine. The next time I come to run, it will animate and then immediately animated out. I really can't see why as it's a call back function? :S
I think it's because the element #mobileList is within the element #body.
Is the call back still running? Can I cease it looking for the event?
Should I use queue() to run the slide in and slide out?
You don't need the callback here, just hook the click handlers up separately:
$('#mobileList').click(function(){
$('#mobileMenu').show().stop(true).animate({
'left': '30%'
}, 500);
});
$('#body').click(function(){
$('#mobileMenu').stop(true).animate({
'left': '100%'
}, 500, function() {
$(this).hide();
});
});
Example fiddle
Note that I used show/hide instead of css and added calls to stop() to prevent the queue being filled up on successive clicks during animation.
UPDATE
To hide the menu when you click anywhere else you need to attach an event handler to the document and check e.target to see what element caused the event. If it was outside the menu, hide it.
$('#mobileList').click(function (e) {
e.stopPropagation();
$('#mobileMenu').show().stop(true).animate({ 'left': '30%' }, 500);
});
$(document).click(function (e) {
var $menu = $('#mobileMenu');
if (!$menu.is(e.target) && !$menu.has(e.target).length) {
$('#mobileMenu').stop(true).animate({ 'left': '100%' }, 500, function () {
$(this).hide();
});
}
});
Updated fiddle
Related
I have a Bootstrap Carousel on my website.
When the user hovers over an element #formcontainer, I'd like to pause the carousel. And when I hover off, I'd like to continue the cycle of the carousel. The first part works fine with the following code, but not the second. Can someone assist?
$(document).ready(function() {
$('.carousel').carousel({
interval: 1200,
pause: "hover"
});
$('#formcontainer').hover(function(){
$("#myCarousel4").carousel('pause');
});
});
Use carousel cycle method on mouseleave event
$('#formcontainer').hover(function(){
$("#myCarousel4").carousel('pause');
},function(){
$("#myCarousel4").carousel('cycle');
});
jQuery's hover function has an implementation that takes two arguments: a hover in handler and a hover out handler:
$('#foo').hover(function() {
// handler in
}, function() {
// handler out
});
When you pass it just one argument, the function you give it handles both the in and out events, so you're pausing it on both mouse enter and mouse out.
You need to pass it separate handlers:
$('#myCarousel4').hover(function() {
$(this).carousel('pause');
}, function() {
$(this).carousel('cycle');
});
Note that we can use this to refer to the carousel rather than rewriting its ID. Inside jQuery event handlers, this always refers to the object you bound the event to when possible.
This will work!
(function($) {
$(document).ready(function(){
$('.carousel').carousel({
pause: 'hover'
});
}); }(jQuery));
I have an issue with a carousel I have built. It has elements inside a container which are moved 'left' by the size of the visible container when the button with class moveCarouselRight is clicked.
My issue is that when the user clicks too fast, ie double click, the animation seems to fire twice, meaning the elements are not properly fitted in the container as if the first 'left' operation had not completed.
As you can see I tried to fix this with the 'disabled' flag but it seems the second click event is fired before the js from the first event has reached that line of code.
var disabled = false;
$('.moveCarouselRight').on('click', function() {
if (!disabled) {
disabled = true;
//change css property 'left' depending on container size
disabled = false;
}
});
Link to jsFiddle:
jsfiddle.net/6TPcT/5
Use this:
JS
$(".moveCarouselRight").dblclick(function(event){
event.preventDefault();
});
OR
$(".moveCarouselRight").dblclick(function(event){
return false;
});
OR
$(".moveCarouselRight").one("click", function(event) {
//do something
});
Link: http://api.jquery.com/one/
I fixed this by binding a click event to the selector on load:
$('.selector').click(moveLeft);
In the method I unbound the click event:
function moveLeft() {
$(this).unbind('click');
//css transition stuff
}
Then, I added a listener to the end of the css transitions:
$("selector").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
$(this).siblings('.nextThree').click(moveThreeRight);
});
Works a charm :)
Thanks for the help on this
I'm coding a button that has a CSS arrow which flips up and down every time it's container is clicked.
It looks fine, but i can't figure out how to fire the toggleClass function as soon as slideToggle has been clicked.
The arrow looks like it is lagging a little because it waits a fraction of a second until the end of the slideToggle animation.
Is it possible to make the toggleClass fire at the start of the animation rather than the end?
$("#content_link").click(function(){
$("#content").slideToggle("fast",function(){
$("div#arrow_container").toggleClass('arrow_down');
$("div#arrow_container").toggleClass('arrow_up');
});
});
not sure if this is what you are asking for but yes call it before the slideToggle() function and not inside its callback function
$("#content_link").click(function(){
$("div#arrow_container").toggleClass('arrow_down')
.toggleClass('arrow_up');
$("#content").slideToggle("fast");
});
Remove that code from the call back and add it after the slideToggle function call like this
$("#content_link").click(function(){
$("#content").slideToggle("fast");
$("div#arrow_container").toggleClass('arrow_down');
$("div#arrow_container").toggleClass('arrow_up');
});
You can set a start callback as well:
$("header#tag_cat1 div#cat1_content_link").click(function(){
$("#tag_cat1_content").slideToggle({
duration: "fast",
complete: function(){
$("section.category header > div#cat1_content_link > div").toggleClass('gt_arrow_down_5px');
$("section.category header > div#cat1_content_link > div").toggleClass('bt_arrow_up_5px');
},
start: function() {...}
});
});
Take a look at the second form of .slideToggle()
$(document).ready(function() {
$("ul li").click(function() {
$(this).find("p").slideToggle("normal");
return false;
});
});
With this piece of jQuery code I can make elements slide in and out. But the problem is that when someone clicks real fast, the slide out will only go until the max height is reached of the latest reached height.
So, if someone would click real fast the element will only slide out a couple of pixels and slide back up. If they´d than click again to slide it out, it will only slide out to the max height it reached the last time.
Can anybody help me to fix this issue to make this work proper?
PS: The height of the p element is set to auto so it automaticly matches the height of the content inside (maybe this detail will help with your answer).
Instead of using the click function to attach the click event, use one instead:
$("ul li").one("click", doStuff);
function doStuff(){
// do your stuff here
$("ul li").one("click", doStuff); // Re-attach event
}
and then re-attach the event in the function.
Try this:
$(document).ready(function() {
$("ul li").click(function() {
if ( ! $(this).find('p:animated').length)
{
$(this).find("p").slideToggle("normal");
return false;
}
});
});
If you want to actually process the additional clicks (rather than ignore them), then you want to use .stop(true, true) to stop the previous animation and jump it to the conclusion so your next animation can run as you want:
$(document).ready(function() {
$("ul li").click(function() {
$(this).find("p").stop(true, true).slideToggle("normal");
return false;
});
});
Whenever you trigger an animation from a user click, you should know about .stop() and figure out which arguments you want to use with it for a given situation. Without it, the animations can pile up in the queue and run sequentially which is usually not what you want.
Here's the jQuery reference info on .stop() and it's arguments.
simple one i hope!
The problem im having is that i have an ('itemID').mouseover, which fires a jquery slide-down animation for a menu box.
The problem is that if the mouse leaves the original item (in this case a text link) before the end of the slideDown() amination, the .mouseleave function is not called.
It works fine otherwise!!
This is what im using: (menu14 is the text link, FunctionsMenu3 is the hidden div containing the menu items)
$('#menu14').mouseover(function() {
$('#FunctionsMenu3').slideDown('fast', function() {
// Animation complete.
});
});
$('#FunctionsMenu3').mouseleave(function() {
$('#FunctionsMenu3').slideUp('fast', function() {
// Animation complete.
});
});
It seem to me that the JS CANT be fired, because its busy doing the slide...
site can be seen at http://www.impero-classroom-management.com
thanks in advance!!
On mouseleave, try .stop() to cancel the current animation.
$('#menu14').hover(
function() {
$('#FunctionsMenu3').slideDown('fast');
},
function() {
$('#FunctionsMenu3').stop().slideUp('fast');
}
);
Well i got around it in the end by not animating the drop down, only the slide up.
not a fix, but it was all i could really do!!
$('#FunctionsMenu5').mouseleave(function() {
$('#FunctionsMenu5').slideUp('fast', function() {
// Animation complete.
});
});
$('#menu15').mouseover(function() {
$('#FunctionsMenu5').show();
});