简体   繁体   English

如何停止jQuery动画插件? 有一个更好的方法来做到这一点

[英]How do I stop a jQuery animation plugin? There HAS to be a better way to do this

I've been sick for the past week and terribly bored, so I decided to teach myself a bit more about writing jQuery plugins. 我过去一周都病了,非常无聊,所以我决定自学一些关于编写jQuery插件的东西。 I threw this one together in about half an hour and it emulates the "wiggle" effect when you press and hold down on a particular icon within an i(Phone|Pad|Pod Touch). 我在大约半小时内把这个放在一起,当你按住i(Phone | Pad | Pod Touch)中的特定图标时,它会模仿“摆动”效果。 To get it to start "wiggling" was easy enough, I just used CSS3 transitions. 为了让它开始“摇摆”很容易,我只使用了CSS3过渡。

http://area51.thedrunkenepic.com/wiggle/ http://area51.thedrunkenepic.com/wiggle/

However, to get the icons to STOP wiggling has proven to be a bit more difficult. 然而,要使图标停止摆动已经证明有点困难。 I'm fairly new to creating jQuery plugins, so I'm not 100% clear on how to save the state of collected objects and then modify said state later on by, say, a callback or event. 我是创建jQuery插件的新手,所以我不是100%清楚如何保存收集对象的状态,然后稍后通过回调或事件修改所述状态。

So, I wound up creating an array which is used to collect all matched objects. 所以,我最终创建了一个用于收集所有匹配对象的数组。 I then use this array to maintain, more or less, the state of the objects which have the wiggle effect applied. 然后,我使用此数组或多或少地维护应用了摆动效果的对象的状态。

Even though it works, it seems overly inefficient which leads me to believe there is a better, perhaps intrinsic (within jQuery), way of getting this done. 即使它有效,但它似乎过于低效,这使我相信有更好的,也许是内在的(在jQuery中),这样做的方式。

Could someone take a look at this simple plugin and tell me what, if anything, I can do? 有人可以看看这个简单的插件,并告诉我,如果有的话,我可以做什么? I'm not asking for someone to improve my code. 我不是要求有人改进我的代码。 Perhaps a working example out in the real world or some solid documentation will suffice. 也许现实世界中的一个实际例子或一些可靠的文档就足够了。

Thank you so much! 非常感谢! :) :)

Plugin Source: http://area51.thedrunkenepic.com/wiggle/wiggle.jquery.js 插件来源: http//area51.thedrunkenepic.com/wiggle/wiggle.jquery.js

You could store the setTimeout result in each object, like so: 您可以将setTimeout结果存储在每个对象中,如下所示:

object.timeout = setTimeout(function(){
methods.rotate(object, step+1);
}, options.delay);

Then in your stop function, call clearTimeout on it, like so: 然后在你的stop函数中,调用clearTimeout,就像这样:

clearTimeout(object.timeout);

The full plugin incorporating these changes is as follows: 包含这些更改的完整插件如下:

(function($){
var rotatingObjectCollection = [];

$.fn.wiggle = function(method, options) {
    options = $.extend({
        rotateDegrees: ['1','2','1','0','-1','-2','-1','0'],
        delay: 35
    }, options);

    var methods = {
        rotate: function(object, step){
            if(step === undefined) {
                step = Math.floor(Math.random()*options.rotateDegrees.length);
            }

            var degree = options.rotateDegrees[step];
            $(object).css({
                '-webkit-transform': 'rotate('+degree+'deg)',
                '-moz-transform': 'rotate('+degree+'deg)'
            });

            if(step == (options.rotateDegrees.length - 1)) {
                step = 0;
            }

            object.timeout = setTimeout(function(){
                methods.rotate(object, step+1);
            }, options.delay);
        },
        stop: function(object) {
            $(object).css({
                '-webkit-transform': 'rotate(0deg)',
                '-moz-transform': 'rotate(0deg)'
            });

            clearTimeout(object.timeout);
            object.timeout = null;
        }
    };

    this.each(function() {
        if((method == 'start' || method === undefined) && !this.timeout) {
            methods.rotate(this);
        } else if (method == 'stop') {
            methods.stop(this);
        }
    });
    return;
}
})(jQuery);

I don't know if it's good practice to store custom data inside the objects like this, but hey, it works :) 我不知道将自定义数据存储在像这样的对象中是否是一种好习惯,但是,嘿,它的工作原理:)

I suggest that you check if the targeted element is already wiggling before you animate it again, because a user can spam your start button, and your elements would stock the animations. 我建议您在再次为其设置动画之前检查目标元素是否已经摆动,因为用户可以将您的开始按钮垃圾邮件,并且您的元素将存储动画。
The animation wont be the desired one and the browser may crash. 动画不会是理想的动画,浏览器可能会崩溃。
Another thing is to maintain chainability : your plugin breaks the jquery chain and one won't be able do use something like $(selector).wiggle().doSomethingElse(); 另一件事是保持可链接性:你的插件打破了jquery链,而且一个人不能使用像$(selector).wiggle().doSomethingElse(); because your plugin is returning nothing after its execution ( return; ). 因为你的插件在执行后没有返回任何内容( return; )。
With the few modifications the plugin would look like : 通过少量修改,插件看起来像:

(function($){
$.fn.wiggle = function(method, options) {
    options = $.extend({
        rotateDegrees: ['1','2','1','0','-1','-2','-1','0'],
        delay: 35
    }, options);

    var methods = {
        rotate: function(object, step){
            if(step === undefined) {
                step = Math.floor(Math.random()*options.rotateDegrees.length);
            }

            var degree = options.rotateDegrees[step];
            $(object).css({
                '-webkit-transform': 'rotate('+degree+'deg)',
                '-moz-transform': 'rotate('+degree+'deg)'
            });

            if(step == (options.rotateDegrees.length - 1)) {
                step = 0;
            }

            object.timeout = setTimeout(function(){
                methods.rotate(object, step+1);
            }, options.delay);
            $(object).data('wiggling',true);
        },
        stop: function(object) {
            $(object).css({
                '-webkit-transform': 'rotate(0deg)',
                '-moz-transform': 'rotate(0deg)'
            });
            clearTimeout(object.timeout);
            $(object).data('wiggling',false);
        }
    };

    this.each(function() {
        if($(object).data('wiggling') == true && (method == 'start' || method === undefined)) {
            methods.rotate(this);
        } else if (method == 'stop') {
            methods.stop(this);
        }
    });
    return this;
}
})(jQuery);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM