jquery插件中的公共方法不起作用

时间:2018-06-14 16:43:20

标签: jquery plugins

我使用JQuery编写了以下插件,但我无法触发公共方法。相反,我在控制台中收到一条消息:

  

“TypeError:$(...)。panIt.doSomething不是函数”。

我的插件代码如下:

;(function() {

// custom panel class
$.fn.panIt = function(options) {

    var def = $.Deferred();
    var pan;

    var defaults = {
        container:        '<div class="panel_plugin"></div>',
        url:            '../../../js/plugins/myPanel/plugin.php',
        padding:        true,
        header:         {
                            isHeadline: false,
                            title:      null,
                            subTitle:   null,
                            minPanel: {
                                isAJAX:     false,
                                content:    ''
                            }
                        },
        footer:         false,
        body:        {
                            isAJAX:     false,
                            content:    ''
                        },
        allowScrolling: true,
        button:         {
                            toggle: true,
                            remove: true
                        },
        index:          null,
        panelSize:      'small',
        parent:         null, 
        domID:          null,
        buttons:       {
                        close: true,
                        sizeUp: true
        },
        onLoaded:       $.noop
    };

    var settings =  $.extend(true, defaults, options); // extend (i.e. merge) defaults with options passed across when plugin is invoked

    var deferredList = [];

    this.doSomething= function() { alert("coey"); };

    //Apply to each instance of the plugin
    this.each(function() {

        var innerDef = $.Deferred();
        addContainer(this);
        updateSettings(this);
        pan =  $(this).find("div.panel_plugin"); // reference for this plugin

        $.when ( loadPluginContent() ).done(function(result) {
            if(result === "success") {
                applySettings();
                setupPanEvents();
                console.log("Plugin html successfully loaded for index " + settings.index); // get count of stats plugins loaded on the page
                innerDef.resolve();
            } else {
                alert ("There was an error loading the plugin content for " + settings.index);
            } 
        });

        deferredList.push(innerDef.promise());
    });


    $.when.apply($, deferredList).done(function() {
        def.resolve("All of my inner defs have been resolved"); 
    });

    return def.promise();

};

}) (jQuery);

当我调用我的插件时,我使用它:

$('#total_membership').panIt({
        header:         {
                            title:      'Total Membership',
                            minPanel: {
                                isAJAX:     false,
                                content:    '<div class="panel-subtitle"> 12800</p>'
                            }
                        },
        body:           {
                            isAJAX: true,
                            content: 'membership_total.php'
        }
    });

稍后我使用此代码尝试调用公共方法:

$('#total_membership').panIt.doSomething();

如果省略最后一行代码,插件工作正常(但显然我不能使用我的公共方法)。

我对JQuery插件很新,我很欣赏有很多不同的例子,但是有人能告诉我哪里出错吗?非常高兴。

1 个答案:

答案 0 :(得分:0)

这是关于如何创建自定义插件的基本代码/想法,以便以后能够访问方法。我添加了内联注释以澄清。

通过这个例子,第一个初始化将第一个参数作为对象的选项。后者调用,将第一个参数作为方法名称,将参数的其余部分作为方法的参数。

修改

它还将插件默认定义为可修改的公共对象,因此可以随时覆盖插件默认值。

定义了两种方法,chainable可以与基本方法调用一起使用:$(selector).customPlugin('method', [arguments])nonChainable方法(就像静态方法一样,它不会有访问jQuery所选元素,但可以执行任何其他基本用法。

因此,如果您需要在方法中使用元素,则需要使用第一种方法。如果方法只是帮助者并且不使用选择查询中定义的插件dom元素,则可以使用第二种方法。

希望它有所帮助。

&#13;
&#13;
$(function() {
	
	// Create custom plugin
	$.fn.customPlugin = function() {
		
		// Transforms the arguments to an array
		var args = Array.prototype.slice.call(arguments);
		
		// If the method is defined
		if($.fn.customPlugin.hasOwnProperty(args[0])) {
			
			// Execute the method, passed in first argument
			return $.fn.customPlugin[args[0]].apply(this, args.slice(1));
			
		} else {
			
			// Return all the matched elements so the function can be chained
			return this.each(function() {
				
				// If the plugin has not been initialized for the object
				if(typeof this.customStorage === 'undefined') {
					
					console.log('initialized');
					
					// Set data storage for the current element
					// This will allow to do any data storage for the element, and it will allow to check if the plugin has been initialized for the element
					this.customStorage = {};
					
					// Define custom options
					this.customStorage.options = $.extend(true, {}, $.fn.customPlugin.defaults, args[0]);
					
					// Do all your initialization sfuff...
					
				}
				
			});
			
		}
		
	};
	
	// Default options for the plugin
	$.fn.customPlugin.defaults = {
		message : 'default!'
	};
	
	// Chainable method, invoked by calling the main plugin method
	$.fn.customPlugin.chainable = function(message) {
		
		// If the method can be chained (applied to a jQuery element query)
		if(typeof this.each === 'undefined') throw { message : 'This method is chainable only' };
		
		// Return all the matched elements so the function can be chained
		return this.each(function() {
			
			// If the plugin has not been initialized for the object
			if(typeof this.customStorage === 'undefined') throw { message : 'You must initialize the plugin for the object to apply plugin methods to it' };
			
			$.fn.customPlugin.notChainable(this.customStorage.options.message, message);
			
		});
	};
	
	// Not chainable method
	$.fn.customPlugin.notChainable = function(messages) {
		
		// Can apply any action, but it does not have access to the elements of the jQuery element query
		
		console.log.apply(console, arguments);
		
	};
	
	// Initilizes the plugin
	$('#foo').customPlugin();
	
	// Initializes the option with a custom message
	$('#bar').customPlugin({ message : 'custom!' });
	
	// Then, later, call the custom method 'foo' with different arguments for each instance
	$('#foo').customPlugin('chainable', 'Message to log...');
	
	// Try to use a chaniable method by chaining
	try {
		$('#bar').customPlugin.chainable('Another message to log...');
	} catch(error) {
		console.log('Error!:', error.message);
	}
	
	//
	$('#bar').customPlugin.notChainable('A simple message to log...');
	
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo"></div>
<div id="bar"></div>
&#13;
&#13;
&#13;