【问题标题】:Jquery plugin re-inits when method is called调用方法时 Jquery 插件重新初始化
【发布时间】:2011-09-26 21:22:44
【问题描述】:

这是我第一次尝试创建 JQuery 插件,所以我为我的菜鸟道歉。我的问题是,当我尝试调用公共方法时,我相信插件正在重新初始化。这是一个简单的插件,它创建一个 div 并用瓷砖填充它,方法 .reveal() 应该删除瓷砖。

插件声明:

(function($){

$.fn.extend({

    //pass the options variable to the function
    boxAnimate: function(options) {


        //Set the default values, use comma to separate the settings, example:
        var defaults = {
    bgColor: '#000000',
            padding: 20,
            height: $(this).height(),
    width: $(this).width(),
    tileRows:25,
    tileHeight:$(this).height()/25,
    tileCols:25,
    tileWidth:$(this).width()/25,
    speed: 500
        }

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

    this.reveal = function(){
    var lastTile = $('.backDropTile:last').attr('id');
    var pos1 = lastTile.indexOf("_");
    var pos2 = lastTile.lastIndexOf("_");
    var lCol = parseInt(lastTile.substr(pos2+1));
    var lRow = parseInt(lastTile.substr(pos1+1,(pos2-pos1)-1));
    alert(lCol+' '+lRow+' #bdTile_'+lRow+'_'+lCol);
    for(lRow;lRow>=0;lRow--){
         //Iterate by col:
         for(lCol;lCol>=0;lCol--){
        $('#bdTile_'+lRow+'_'+lCol).animate({
            opacity: 0
            }, 100, function() {
            $('#bdTile_'+lRow+'_'+lCol).remove();
        });
         }
     }
     alert(lCol+' '+lRow);
    }

        return this.each(function(index) {
            var o = options;
    //Create background:
    $(this).prepend('<div id="backDrop" style="color:white;position:absolute;z-index:998;background-color:'+o.bgColor+';height:'+o.height+'px;width:'+o.width+'px;"></div>');
             //create boxes:
     //First iterate by row:

     for(var iRow=0;iRow<o.tileRows;iRow++){
         //Iterate by col:
         for(var iCol=0;iCol<o.tileCols;iCol++){
         $('#backDrop').append('<span class="backDropTile" id="bdTile_'+iRow+'_'+iCol+'" style="z-index:998;float:left;background-color:green;height:'+o.tileHeight+'px;width:'+o.tileWidth+'px;"></span>');
         }
     }

        });
    }
});

})(jQuery);

用法:

    $(document).ready(function() {
        $('#book').boxAnimate();
        $('#clickme').click(function() {
            $('#book').boxAnimate().reveal();
        });
    });

所以我几乎知道我的问题是什么,但我对创建 jQuery 插件来修复它还不够熟悉。似乎我读得越多,我就越感到困惑,因为实现这一目标的方法似乎有很多。

【问题讨论】:

  • 您使用的是data('boxAnimate'),您是否将插件实例存储在jQuery.data() 的某个地方?
  • 对不起,这不是我使用的实际方法,我将其更改为我正在使用的方法。我在这里读过一个例子:msdn.microsoft.com/en-us/scriptjunkie/ff608209 我应该使用 .data
  • 我认为将插件实例存储到 data() 中是正常的约定。 $('el').boxAnimate() 创建一个插件实例并将其附加到集合中的每个元素。 $('el').data('boxAnimate') 旨在检索附加的实例。

标签: jquery jquery-plugins methods


【解决方案1】:

我喜欢将我的插件分成四个部分。

1:迭代jQuery元素集合并附加插件的$.fn实现。

2:插件“构造函数”或init。

3:插件默认选项

4:插件实例方法或实现。

以下是我构建插件的方式。我认为这比你提供的更容易理解。

(function($){

// constructor or init task
var boxAnimate = function(el, options) {
    this.element = $(el);
    this.options = options;

    if (this.options.height == 'auto') this.options.height = this.element.height();
    if (this.options.width == 'auto') this.options.width= this.element.width();
    if (this.options.tileHeight == 'auto') this.options.tileHeight = this.options.height/25;
    if (this.options.tileWidth == 'auto') this.options.tileWidth = this.options.width/25;

    //Create background:
    this.element.prepend('<div id="backDrop" style="color:white;position:absolute;z-index:998;background-color:'+this.options.bgColor+';height:'+this.options.height+'px;width:'+this.options.width+'px;"></div>');

    //create boxes:
    for(var iRow=0;iRow<this.options.tileRows;iRow++){
        for(var iCol=0;iCol<this.options.tileCols;iCol++){
             $('#backDrop').append('<span class="backDropTile" id="bdTile_'+iRow+'_'+iCol+'" style="z-index:998;float:left;background-color:green;height:'+this.options.tileHeight+'px;width:'+this.options.tileWidth+'px;"></span>');
        }
    }
}

// default options
boxAnimate.defaults = {
    bgColor: '#000000',
    padding: 20,
    height: 'auto',
    width: 'auto',
    tileRows:25,
    tileHeight: 'auto',
    tileCols:25,
    tileWidth: 'auto',
    speed: 500
};

// instance methods
boxAnimate.prototype = {
    reveal: function() {
        var lastTile = $('.backDropTile:last').attr('id');
        var pos1 = lastTile.indexOf("_");
        var pos2 = lastTile.lastIndexOf("_");
        var lCol = parseInt(lastTile.substr(pos2+1));
        var lRow = parseInt(lastTile.substr(pos1+1,(pos2-pos1)-1));

        for(var row=lRow;row>=0;row--) {
            for(var col=lCol;col>=0;col--) {
                $('#bdTile_'+row+'_'+col).animate({
                    opacity: 0
                }, 1000, function() {
                    $('#bdTile_'+row+'_'+col).remove();
                });
             }
         }
    }      
}

// $.fn registration
$.fn.boxAnimate = function(options) {
    return this.each(function() {
        var el = $(this);
        var o = $.extend({}, boxAnimate.defaults, options)
        if (!el.data('boxAnimate'))
            el.data('boxAnimate', new boxAnimate(el, o));
    });
}
})(jQuery);


    $('#book').boxAnimate(); 
    $('#clickme').click(function(e) {
        $('#book').data('boxAnimate').reveal();
        e.preventDefault();
    });

【讨论】:

  • 这太棒了,谢谢 - 如果我选择重写,我会遵循这个。
【解决方案2】:

当你在插件“构造函数”中分配一个方法时,就像你在这里做的那样:

this.reveal = function(){}

您将其分配为jQuery.prototype.boxAnimate 对象的静态方法。这意味着您可以在将从构造函数返回的对象上调用它:

$('#element').boxAnimate().reveal();

或:

var instance = $('#element').boxAnimate();
instance.reveal();

如果您希望将其放在 $.data 对象内(个人推荐),您可以这样做(在 this.each 循环内):

$.data(this, 'boxAnimate', {
    reveal: function() {
        // some code
    }
});

示例:http://jsfiddle.net/AyffZ/

【讨论】:

    【解决方案3】:

    首先,阅读本教程:http://docs.jquery.com/Plugins/Authoring

    第二,你的问题肯定是用法:

    $(document).ready(function() {
        $('#book').boxAnimate(); // First Init
        $('#clickme').click(function() {
            $('#book')
                .boxAnimate() // Second Init
                .reveal();
        });
    });
    

    我链接的教程解释了在插件中包含方法的多种方法。您还可以使用 jQuery UI 小部件工厂,它提供了包含方法的钩子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2012-09-09
      • 1970-01-01
      相关资源
      最近更新 更多