同一页面上有多个jQuery插件实例?

时间:2013-02-20 17:02:35

标签: jquery jquery-plugins

我见过很多不同的jQuery插件样板,并阅读了许多不同的jQuery插件创作文章,包括官方文章。但是,从根本上说,我似乎仍然缺少一些东西!

我正在使用我在别处见过的代码和jQuery's official authoring guidelines

从代码中可以看出,我正在return this.each(function() { });内部做所有事情。这包括我的私人职能。我认为这意味着对于每个被调用的.pluginName();,代码将被运行并绑定到该实例。例如,我在每个元素ID的末尾添加randID,这样如果创建了多个实例,则实例可以引用正确的元素。

我的问题是,当我在同一页面上有两个实例时,第二个实例的函数(如displayAvailableItems())正在使用第一个实例randID

我假设有两件事是错的:功能在错误的地方,而randID是一种识别元素的坏方法。如果我将displayAvailableItems()移到retun this.each(function() { });的正上方,则availableItem变量将不再可用。

以下是我的代码的缩写版本:(pastebin)http://tny.cz/6d3d52a8

$.pluginName = {
     id: 'PluginName'
    ,version: '1.0'
,defaults: { // default settings
    foo: 'bar'
}
};

(function($) {
    //Attach this new method to jQuery
    $.fn.extend({ 

            pluginName: function(params) {
            //Merge default and user parameters
                    var params =  $.extend($.pluginName.defaults, params)
            ,otherGeneralVars = 'example'
        ;

        return this.each(function() {       
            var $t = $(this);

            //Generate a random ID to attach to the elements, so we can have endless (up to 50k) quantities of the plugin on the page
                            var randID = 1 + Math.floor(Math.random() * 50000);
                            //Make sure the randID hasn't been previously used
                            while ($.inArray(randID, usedRandIDs) > -1)
                            {
                                    randID = 1 + Math.floor(Math.random() * 50000);
                            }
                            usedRandIDs.push(randID);
                            randID = '_PluginName' + randID;

            /*
                                    RUN INITIALIZATION SETTINGS
                            */
                            var availableItemsContainerID = 'availableItemsContainer' + randID
                ,tagSearchContainerID = 'tagSearchContainer' + randID
                ,tagSearchID = 'tagSearch' + randID
                ,availableItemsID = 'availableItems' + randID
                ,selectedItemsContainerID = 'selectedItemsContainer' + randID
                ,selectedItemsID = 'selectedItems' + randID
                ,selectedValuesID = 'selectedValuesInputName' + randID
            ;

            //Build element structure
                            $t.append('<div id="' + availableItemsContainerID + '">' +
                                                            '<div id="' + tagSearchContainerID + '">' +
                                                                    '<input id="' + tagSearchID + '" value="' + params.searchDefaultText + '" />' +
                                                            '</div>' +
                                                            '<div id="' + availableItemsID + '"></div>' +
                                                    '</div>' +
                                                    '<div id="' + selectedItemsContainerID + '">' +
                                                            '<div id="' + selectedValuesID + '"></div>' + 
                                                            '<div id="' + selectedItemsID + '"></div>' +
                                                    '</div>');      

            //Show the list of available items
                            displayAvailableItems();

            $('#' + availableItemsContainerID).css({
                              'width': params.availableItemsContainerWidth + params.unitOfMeasurement,
                              'height': params.availableItemsContainerHeight + params.unitOfMeasurement
                            });
                            $('#' + selectedItemsContainerID + ', #' + selectedItemsID).css({
                              'width': params.selectedItemsContainerWidth + params.unitOfMeasurement,
                              'height': params.selectedItemsContainerHeight + params.unitOfMeasurement
                            });

            function displayAvailableItems() {
                                    //Clear out the available items
                                    $("#" + availableItemsID).html('');

                                    //Do other stuff
                            }
        });
               }
       })
        })(jQuery);

1 个答案:

答案 0 :(得分:14)

首先,您需要将var params移动到您的this.each中,然而您将有一个变量提升(不完全确定这是否真的发生了什么,但这就是它看起来的样子) 问题是由于使用参数名称作为变量名称导致params未定义。要解决这个问题,只需将thisms中的params重命名为其他内容即可。例如:

$.fn.extend({

    pluginName: function (params) {
        //Merge default and user parameters
        var otherGeneralVars = 'example';

        return this.each(function () {
            var $t = $(this), opts = $.extend({},$.pluginName.defaults, params);

            $t.text(opts.foo + uniqueId);
        });
    }
})

http://jsfiddle.net/M99EY/1/