Как остановить плагин анимации jQuery? Должен быть лучший способ сделать это - PullRequest
3 голосов
/ 13 мая 2011

Я болел на прошлой неделе и ужасно скучал, поэтому я решил немного больше научиться писать плагины для jQuery. Я скомбинировал его примерно через полчаса, и он имитирует эффект "покачивания", когда вы нажимаете и удерживаете определенный значок внутри i (Phone | Pad | Pod Touch). Чтобы начать «шевелить» достаточно просто, я просто использовал переходы CSS3.

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

Однако, чтобы получить значки для остановки, оказалось немного сложнее. Я довольно новичок в создании плагинов jQuery, поэтому я не на 100% уверен в том, как сохранить состояние собранных объектов, а затем изменить его позже, скажем, с помощью обратного вызова или события.

Итак, я создал массив, который используется для сбора всех совпадающих объектов. Затем я использую этот массив, чтобы более или менее поддерживать состояние объектов, к которым применен эффект покачивания.

Даже несмотря на то, что это работает, это кажется чрезмерно неэффективным, что заставляет меня поверить, что есть лучший, возможно внутренний (в jQuery) способ сделать это.

Может ли кто-нибудь взглянуть на этот простой плагин и сказать мне, что, если что-нибудь, я могу сделать? Я не прошу кого-то улучшить мой код. Возможно, вам подойдет рабочий пример из реальной жизни или какая-то основательная документация.

Спасибо большое! :)

Плагин Источник: http://area51.thedrunkenepic.com/wiggle/wiggle.jquery.js

Ответы [ 2 ]

3 голосов
/ 13 мая 2011

Вы можете сохранить результат setTimeout в каждом объекте, например:

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

Затем в вашей функции остановки вызовите clearTimeout, например:

clearTimeout(object.timeout);

Полный плагин, включающий эти изменения, выглядит следующим образом:

(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);

Я не знаю, если это хорошая практика для хранения пользовательских данных внутри объектов, как это, но эй, это работает:)

1 голос
/ 13 мая 2011

Я предлагаю вам проверить, если целевой элемент уже шевелится, прежде чем снова его анимировать, потому что пользователь может спамить вашу кнопку запуска, и ваши элементы будут хранить анимации.
Анимация не будет желаемой, иможет произойти сбой браузера.
Другая вещь заключается в поддержании цепочки: ваш плагин разрывает цепочку jquery, и вы не сможете использовать что-то вроде $(selector).wiggle().doSomethingElse();, потому что ваш плагин ничего не возвращает после своего выполнения (return;).
С некоторыми изменениями плагин будет выглядеть так:

(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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...