2011-09-26 34 views
0

這是我第一次嘗試創建一個JQuery插件,所以我爲我的noobbery道歉。我的問題是,當我嘗試調用公共方法時,我相信該插件正在重新初始化。這是一個簡單的插件,創建一個div,並用瓦片填充它,方法.reveal()應該刪除瓦片。jquery插件重新調用方法時調用

插件聲明:

(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插件來解決它。看起來我閱讀得越多,我就變得越困惑,因爲看起來有很多方法可以實現這一目標。

+0

您正在使用'data('boxAnimate')',您是否將插件實例存儲在'jQuery.data()'某處? –

+0

對不起,這不是我正在使用的實際方法,我將其更改爲我正在使用的方法。我在這裏讀過一個例子:http://msdn.microsoft.com/en-us/scriptjunkie/ff608209我應該使用它。數據 – jreed121

+0

我認爲你將插件的一個實例存儲到data()中是正常的約定。 $('el')。boxAnimate()創建一個插件實例並將其附加到集合中的每個元素。 $('el')。data('boxAnimate')用於檢索附加實例。 –

回答

1

當指定插件「構造」像你裏面的方法在這裏做的:

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/

+0

很簡單,謝謝! – jreed121

2

我喜歡將我的插件分成四個部分。

1:$ .fn實現迭代jQuery元素集合並附加插件。

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(); 
    }); 
+0

這真棒,謝謝 - 如果我選擇重寫,我遵循這個。 – jreed121

1

首先,請閱讀本教程:http://docs.jquery.com/Plugins/Authoring

其次,你的問題肯定是用法:

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

我聯繫的教程介紹了多種方式,包括對插件的方法。您還可以使用jQuery UI小部件工廠,它提供了包含方法的鉤子。