I have a custom accordion menu. To display second-level options in the menu, I chose to use slideToggle()
. For some reason, There is a delay between when they click and when the animation occurs.
This is evident when seen in contrast with another accordion menu on the same page... I found out that the function that is bound (on click) to the menu item gets executed almost immediately. The problem is that the slideToggle
animation seems to start later than it should.
I believe this may be happening because of the way I am targeting the element that slideToggle()
is being called on.
var $expandableMenu = $(".expandable .level1");
$expandableMenu.bind('click', function () {
$(this).next().slideToggle(200, function () {
$(this).parent().toggleClass("opened");
});
});
Maybe the problem is that $(this).next()
is a slow way to target the element that I need to use slideToggle()
on?
What are your thoughts?
Edit: I made a jsFiddle test case... Oddly enough the issue does not happen here. http://jsfiddle.net/nYZNP Still looking for the issue.
To delay execution of animation, use . delay() method which allows to delay the execution of functions that follow it in the queue. It accepts duration as parameter. Durations are given in milliseconds; higher values indicate slower animations, not faster ones.
The delay() is an inbuilt method in jQuery which is used to set a timer to delay the execution of the next item in the queue. para1: It specifies the speed of the delay. para2: It is optional and specifies the name of the queue.
jQuery delay() Method The delay() method sets a timer to delay the execution of the next item in the queue.
The slideToggle() method toggles between slideUp() and slideDown() for the selected elements. This method checks the selected elements for visibility. slideDown() is run if an element is hidden. slideUp() is run if an element is visible - This creates a toggle effect.
If you are trying this on a mobile device, it may indeed take longer for the animation to start, as the device is waiting (even 200ms+) to make sure you are not attempting a double-tap. If this is the case you could go for libraries like zepto.js, which has a tap event or fastclick.js which emulates tap events.
in terms of selector performance, $(this).parent()
should be fine. In this case however, you could eliminate a few milliseconds by not writing and reading the variable first, like this:
$(".expandable .level1").bind('click', function () {
$(this).next().slideToggle(200, function () {
$(this).parent().toggleClass("opened");
});
});
Also, "As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document." (jQuery api). Or in other words, bind()
is deprecated!
And finally there is the general rule that filtering by tag name is faster than by classname or id, so $("li.expandable .level1")
should be faster than $(".expandable .level1")
.
Maybe you can also be more specific about the exact circumstances, such as browser/device or any other difference to your fiddle?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With