Animation namespaces in jQuery

Asked

Viewed 182 times

3

For those who are already used to using jQuery, use the function jQuery.fn.stop is something simple and very common when we work with different animations in a common element.

My doubt is focused on creating jQuery extensions. I have been developing jQuery plugins for some time and to develop any extension I use my own standard based on an international standard created by Addy Osmani where I made some changes.

This standard serves to the developer who uses a plugin, not go through some problems that could occur in various situations and different browser or even to avoid certain types of conflicts with variable names, functions and events among others.

When a user uses the function jQuery.fn.off for example, it removes a chain of delegated events with jQuery functions (jQuery.fn.on for example). In case the user needs to remove only the events delegated by a plugin in specific, the correct one in a pattern would be to use a namespace as in the example below:

jQuery(document).on('click.customNamespace', jQuery.noop);

So the developer could remove only the events that the plugin has delegated with something close to this:

jQuery(document).off('.customNamespace');

My doubt is about performing something similar, but with jQuery animations.

Suppose I have a plugin that moves through an animation the vertical and horizontal scrolling bars of an element in the DOM. When the user fires an undetermined event I want for example to stop the animation only vertically while the horizontal scrolling continues to move. The use of jQuery.fn.stop does not help me in this matter since it for all animations of the element (at least not in a way that I know).

The question then would be: How can I stop only certain animation or part of an animation? How to stop only "scrollTop" and continue with the animation of "scrollLeft" announced in the same instance of the function jQuery.fn.animate? And if this is possible in some way that I do not know, it would be possible to create a kind of namespace for this as I exemplified with events above (something like jQuery(document).stop('.myNamespace'))?

I do not know whether I have complicated a question too much that may be easily resolved by someone or whether I have been clear enough, but in case of doubt I am looking at the comments.

2 answers

2

I found something in SOEN that may be a solution to this question:

Stopping specific jQuery animations

According to the answer it is possible to call the method animate passing the parameter queue: false, and then use the current value of the property to be stopped with an animation runtime of 0. Thus, the animation will stop at the desired property.

Transcribed example of the question in English

$myElement = $("#animateElement");
$myElement.animate({width: 500}, {duration: 5000});
$myElement.animate({height: 500}, {duration: 5000, queue: false});
// ... Esperar 2 segundos ...
$myElement.animate({width: $myElement.width()}, {duration: 0, queue: false});

The last line will stop the animation of the property width.

EDIT Reading a little more the answers of the said question, I think, an answer with 0 votes, stating that jQuery 1.7+ supports named animation queues (named Animation queues), and that can be stopped individually by the method stop:

Example

$myElement.animate({width: $myElement.width()}, {queue: "minhaQueue"});
$myElement.stop("minhaQueue");
  • Very interesting, I had already worked with queues of animations but was unaware of this functionality. I just didn’t think that the example you found about instantiating a new animation with duration 0 applies in a good practice, although it is a good way out if there is no other way to do it. Thank you very much!

2


It is possible to make independent animations both by attributes and by plugins using the queues jQuery effects functions, such as animate() and stop().

Specifying a queue in the animation options, the animations will be lined up independently of each other.

For example:

$('div').animate(
    //define o atributo para animar, movendo o objeto 200 pixels para a direita
    {
        left: '+=200px'
    }, 
    //define as opções, incluindo a fila da animação
    {
        queue: 'x',
        duration: 5000
    }
).dequeue('x'); //inicia a animação

As the documentation says, when a queue is specified, the animation does not start immediately, so it is always necessary to call the function dequeue(). This can generate changes to existing code and make the implementation a little more laborious.

To specifically stop the animation above, we pass the name of the queue to the function stop():

$('div').stop('x');

If we do the same for the axle Y, we can start and stop the animations independently.

However, it is not possible to stop the animation of a single attribute if the animate() was done with several attributes.

See the jsfiddle demo

  • 1

    Instantiating an animation for each property seems a better solution, although I believe there is a loss in performance. It’s really a shame there isn’t a specific way to stop just one property among several of the same animation. Maybe I’ll create an Issue in the jQuery repository to discuss this possibility in a future version... Thank you very much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.