Плагины JQuery: функция, использующая $ (this) в настройках плагина - PullRequest
1 голос
/ 19 марта 2012

Привет всем.

Я пытаюсь разработать плагин Jquery, выполнив шаги, которые я нашел в http://docs.jquery.com/Plugins/Authoring, и у меня, похоже, возникают проблемы с достижением объекта вызывающего (переменная * this)) внутри опции переданы плагину.Это плагин, который я просто хочу использовать, чтобы кнопка имела эффект «мерцания».

Я хотел бы иметь возможность передать функции для выполнения в «показать / скрыть» (или мигать, выключить, если хотите), в качестве опции для плагина.Допустим, пользователь хочет добиться эффекта «мигания», скрывая / показывая всю кнопку каждые 1000 миллисекунд.Тогда я бы хотел, чтобы параметры были примерно такими:

$("#bttnOk").myBlinker ({
    blinkHide: function(){$(this).hide();},
    blinkShow: function(){ $(this).show();},
    interval:1000
});
// … //
// And to make it actually blink:
$("#bttnOk").myBlinker ("blink");

Или, скажем, пользователь хочет перемещать кнопку вверх и вниз, применяя встроенный CSS-симулятор каждые 200 мс.Тогда параметры будут выглядеть примерно так:

$("#bttnOk").myBlinker ({
    blinkHide: function(){$(this).css(“margin-top: 10px”);},
    blinkShow: function(){ $(this).css(“margin-top: 0px”);},
    interval:200
});

Проблема в том, что я теряю ссылку на «$ (this)», когда нахожусь внутри параметров.Когда плагин достигает функций blinkHide/blinkShow, «this» - это все окно DOM, а не кнопка $ («# bttnOk»), к которой подключен мой плагин «myBlinker».

Это первыйПлагин Jquery, который я пытаюсь написать, поэтому я даже не уверен, есть ли способ добиться того, что я пытаюсь сделать.

Мой код плагина имеет следующую структуру:

(function($){
    var defaultOptions = {
        interval: 500
    }

    var methods = {
        init : function( options ) {
            return this.each(function(){
                this.options = {}
                $.extend(this.options, defaultOptions, options);
                var $this = $(this);
                var data = $this.data('myBlinker');

                // If the plugin hasn't been initialized yet
                if ( ! data ) {
                    $this.data('myBlinker', {
                        on : true
                    });
                }
            });
        },
        destroy : function( ) { // Some code here},
        blink: function ( ){
            console.log("Blinking!. This: " + this);
            var current = 0;
            var button=this.get(0);
            setInterval(function() {
                if (current == 0){
                    button.options["blinkShow"].call(this);
                    current=1;
                } else {
                    button.options["blinkHide"].call(this);
                    current=0;
                }
            }, button.options["interval"]);
        }

    };

    $.fn. myBlinker = function( method ) {
        // Method calling logic
        if ( methods[method] ) {
            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.myBlinker ' );
            return null;
        }
    };
})(jQuery);

Будут оценены любые идеи, исправления, ссылки или советы.

Спасибо.

1 Ответ

4 голосов
/ 19 марта 2012

В функции setInterval, this является глобальным объектом, а не текущим элементом DOMElement, как в функции blink.

Решением этой проблемы является сохранение ссылки this и использованиеэта сохраненная ссылка в setInterval:

   blink: function ( ){

        // save a reference of 'this'
        var that = this;

        setInterval(function() {

            // use the saved reference instead of 'this'
            button.options["blinkShow"].call(that);

        }, button.options["interval"]);
    }

DEMO

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...