简体   繁体   English

具有方法和全局回调的jQuery插件

[英]jQuery plugin with methods & global callbacks

I want to create a jQuery plugin that has both methods and callbacks, methods work but I can't get the callbacks working, the scope of the callbacks confuses me, 我想创建一个同时具有方法和回调的jQuery插件,方法可以正常工作,但我无法正常工作,回调的范围使我感到困惑,

(function($)
{
    var methods = {

        create: function(options) {

            var defaults = {
                width: 320,
                height: 240,
                background: '#000',
                onstop: function(){}
            };

            var options = $.extend(defaults, options);

            return $(this).each(function(i) {

                console.log('create');

            });

        },
        stop: function(options) {

            var defaults = {
                onstop: function(){}
            };

            var options = $.extend(defaults, options);

            return $(this).each(function(i) {

                console.log('stop');
                options.onstop.call();

            });
        }
    };

    $.fn.myplugin = function(option) {

        if (methods[option]) {
            return methods[option].apply( this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof option === 'object' || ! option) {
            return methods.create.apply(this, arguments);
        } else {
            $.error('Method ' +  option + ' does not exist in jQuery.plugin');
        }    
    };

})(jQuery);

so in the <script> : 所以在<script>

$(document).ready(function(){

    $('#start').click( function(){
        $('#myvideo').myplugin('create', { onstop: function(){ console.log('on stop'); } });
    });

    $('#stop').click( function(){
        $('#myvideo').myplugin('stop');
    });

});

basically it seems I want to make the onstop: function(){} global to the plugin 基本上,我似乎想对插件进行onstop:function(){}

/* ======== updated code (see comments) ======== */ / * ========更新代码(请参阅注释)======== * /

(function($)
{

    var callbacks = {
        onready: $.Callbacks("once memory unique").add(function() {
            //console.log('onready');
        }),
        ondeny: $.Callbacks("unique").add(function() {
            //console.log('ondeny');
        }),
        onerror: $.Callbacks("unique").add(function() {
            //console.log('onerror');
        }),
        onstop: $.Callbacks("unique").add(function() {
            //console.log('onstop');
        })
    };

    var methods = {

        construct: function(){
        },
        create: function(options) {

            var defaults = {
                width: 320,
                height: 240,
                background: '#000',
                onready: function(){},
                onstop: function(){}
            };

            var options = $.extend(defaults, options);

            return this.each(function(i, elements) {

                for (var prop in options) {
                    if (prop in callbacks) {
                        callbacks[prop].add(options.prop);
                    }
                }

                callbacks.onready.fire();

            });

        },
        stop: function() {

            return this.each(function(i, elements) {
                callbacks.onstop.fire();
            });
        }
    };

    $.fn.myplugin = function(option) {

        if (methods[option]) {
            return methods[option].apply( this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof option === 'object' || ! option) {
            return methods.construct.apply(this, arguments);
        } else {
            $.error('Method ' +  option + ' does not exist in jQuery.plugin');
        }    
    };

})(jQuery);

I'd recommend to use some full-fledged jQuery.Callbacks objects: 我建议使用一些成熟的jQuery.Callbacks对象:

var callbacks = {
    onready: $.Callbacks("once memory unique").add(function() {
        console.log('ready');
    }),
    ondeny: $.Callbacks("unique").add(function() {
        console.log('deny');
    }),
    onerror: $.Callbacks("unique").add(function() {
        console.log('error');
    }),
    onstop: $.Callbacks("unique").add(function() {
        console.log('stop');
    })
};

Now, when getting some new options you can do 现在,当获得一些新选项时,您可以

for (var prop in options)
    if (prop in callbacks)
        callbacks[prop].add(options[prop]);

And to invoke them just do 并调用它们就可以了

callbacks.onstop.fire(/*args*/);

or, if you care about the context of the callbacks, use fireWith . 或者,如果您关心回调的上下文,请使用fireWith

I used a globalOptions variable to store the plugins initialization options as global, 我使用globalOptions变量将插件的初始化选项存储为全局变量,

Here's the two files to test things out and use as a stencyl. 这是两个文件,用于测试并用作固定文件。

jquery.plugin.js (function($){ jquery.plugin.js(function($){

    var pluginName = 'myPlugin';

    var globalOptions = '';

    var methods = {

        create: function(options) {

            var defaults = {
                backgroundColor: '#000',
                color: '#fff',
                oncreate: function(){},
                onchangecolor: function(){},
                onloadpage: function(page){}
            };

            globalOptions = $.extend(defaults, options);

            return $(this).each(function(i, elements) {

                $(elements).data('globalOptions', globalOptions);

                globalOptions.oncreate();

            });

        },
        changeColor: function(){

            return $(this).each(function(i, elements) {

                globalOptions = $(elements).data('globalOptions');
                if (!globalOptions) { $.error('Error: ' + pluginName + ' has not been initialized yet'); return false; }

                $(this).css('background-color', globalOptions.backgroundColor);
                $(this).css('color', globalOptions.color);

                globalOptions.onchangecolor();

            });
        },
        loadPage: function(options){

            return $(this).each(function(i, elements) {

                globalOptions = $(elements).data('globalOptions');
                if (!globalOptions) { $.error('Error: ' + pluginName + ' has not been initialized yet'); return false; }

                globalOptions.onloadpage(options.page);
                location.href = options.page;

            });
        }

    };

    $.fn.myPlugin = function(option) {

        if (methods[option]) {
            return methods[option].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof option === 'object' || ! option) {
            return methods.create.apply(this, arguments);
        } else {
            $.error('Error: Method "' + option + '" does not exist in ' + pluginName);
            return false;
        }    
    };

})(jQuery); 

index.html index.html

<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Example</title>
        <script src="jquery.min.js"></script>
        <script src="jquery.plugin.js"></script>
        <script>
$(document).ready(function() {

    var myElement = $('.container').myPlugin({
        color: '#555',
        backgroundColor: '#ddd',
        oncreate: function(){
            console.log('Callback: create');
        },
        onchangecolor: function(){
            console.log('Callback: onchangecolor');
        },
        onloadpage: function(page){
            console.log('Callback: onloadpage = '+page);
        }
    });

    $('.color').click(function(event){
        myElement.myPlugin('changeColor');
    });

    $('.page').click(function(event){
        myElement.myPlugin('loadPage', { page: '#test' });
    });

});
        </script>
    </head>
    <body>
        <div class="container">
            <button class="color">changeColor</button> <button class="page">loadPage</button>
        </div>
    </body>
</html>

If anyone has a better way of doing this and a way to add "private" methods, please share. 如果有人可以更好地做到这一点,并且可以添加“私有”方法,请分享。 :) :)

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

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