寫一個套件。符合如下操作的pattern
$('#id1').ryTooltip() ; //沒參數
$('#id1').ryTooltip({xxx: ooo}) ; //有參數地執行套件
$('#id1').ryTooltip('method', arguments obj) ; //執行套件method
<文章列表>
IT人生組文章
--9/22 : 不要在電梯裡面討論HTML
http://ithelp.ithome.com.tw/question/10128407
--9/21 : IT人的人生觀
http://ithelp.ithome.com.tw/question/10128168
--9/20 : IT人的創意
http://ithelp.ithome.com.tw/question/10127866
--9/19 : 程式設計師的成就感
http://ithelp.ithome.com.tw/question/10127573
--9/18 : 你的職業是甚麼?
http://ithelp.ithome.com.tw/question/10127308
開發技術組文章
--9/22 : jQuery套件開發(七),實作套件。
http://ithelp.ithome.com.tw/question/10128406
--9/21 : jQuery套件開發(六),套件的整個流程的小構思。
http://ithelp.ithome.com.tw/question/10128176
--9/20 : jQuery套件開發(五),套件的定義
http://ithelp.ithome.com.tw/question/10127881
--9/19 : jQuery套件開發(四),預設值與設定值的差別
http://ithelp.ithome.com.tw/question/10127575
--9/18 : jQuery套件開發(三),true false的判斷
http://ithelp.ithome.com.tw/question/10127297
全列表
http://ithelp.ithome.com.tw/ironman6/player/sheephead081/alll/1
寫套件嚕
各位觀眾..
我今天要推出的套件就是~~~tooltip!
你沒看錯,我就是那麼無恥。
對了,程式碼還超長的,神~吧~!
但是我們主要是為了探討寫套件的一些流程
還有,希望能夠有一個小小的架構適應我們大部分寫套件的需求
當你滑鼠滑過SPAN會顯示提示文字( 我恥力真高阿! )
我們先來回想一下上一次我們提到寫套件大概會遇到哪些程序
第一個,套件初始化。( 先把要用到的元素放到畫面中,當然是隱形的嚕 )
第二個,套件觸發。( 悠~碰到了SPAN )
第三個,邏輯計算。( 算出觸發元素的相關資訊用來決定tooltop要顯示在哪裡 )
第四個,畫面改變。( 畫面上顯示一個DIV )
第五個,事件綁定。( 綁定mouseleave事件,滑鼠移開DIV元素就消失。 )
其中,事件綁定的部分要看你元素是在哪裡生成的。
像我是初始化的時候就把元素append到 body 裡面了。
所以,我那時候事件就已經綁定好了。
首先,先來定義我的套件想怎樣使用
$(function()
{
$.ryTooltip('init') ;
$.ryTooltip('testMode') ;
$('#id1').ryTooltip() ;
}) ;
我是習慣套件使用前都要先初始化。
畢竟不見得你的套件是那麼的輕快。
另外有一點很重要就是這樣有助於把畫面跟程式做分割。
舉例而言,如果你做的是一個月曆的套件。
你可以在開發的時候 用$.calender('init')的時候把月曆漂漂亮亮的弄在畫面上。
你還不用想接下來的事件呢~你只要把套件美美的弄出來就好了。
有人會說,我可以套件載入的時候利用立即函式來處理
的確沒錯,但這樣一來你就錯失設定預設值的時機了。
當然你也可以打開程式碼改程式。這沒甚麼大不了的。
;(function ( $, W, D, undefined ) {
var pluginName = 'ryTooltip' ;
$.pg = $[pluginName] = function()
{
if ($.isFunction( $.pg[arguments[0]] ))
{
$.pg[arguments[0]](arguments[1]) ;
}
}
$.pg.defaults =
{
testMode: false,
ttBorder: '1px solid red', //tt means tooltop
ttBgColor: 'blue',
ttPadding: '8px',
ttColor: 'yellow',
ttClass: 'ryttClass',
} ;
$.pg.init = function()
{
$[pluginName].createHero() ;
}
$.pg.createHero = function()
{
$.pg.hero = $('<span />')
//set some would not be changed by settings or defaults
.css(
{
display: 'none', //invisible is important.
position: 'absolute',
})
.appendTo('body') ;
}
$.pg.log = function()
{
if ($[pluginName].defaults.testMode)
{
console.log(arguments) ;
}
}
$.pg.testMode = function(mode)
{
var _flag = true ;
if (mode === false)
{
_flag = false ;
}
$[pluginName].defaults.testMode = _flag ;
if (_flag)
{
console.log('testMode is opened') ;
}
}
})( jQuery, window, document );
然後我習慣打開$.ryTooltip('testMode') ;
這會把測試模式打開,這個模式會把一些設定的log顯示出來
這通常是要修改套件的時候還滿有用的
然後最後才是我們一般使用套件的方法
$('#id1').ryTooltip() ;
那因為我們在初始化的時候早就把套件元素放在文件裡了
所以套件變得超好寫的!只是綁定事件,然後在某個時間點把套件.show()而已。
這部分我有學一些文章。
文章一
http://coding.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns/
文章二
http://www.learningjquery.com/2007/10/a-plugin-development-pattern
剛剛,我們是在設定套件的預設值以及一些檢查機制
接下來,再針對這個套件設計內容
function Plugin(element, args)
{
this.element = element ;
this.ele$ = $(element) ;
this.args = args[0] ;
this.hero = $.pg.hero ;
//如果套件很簡單,只會產生一個元素(巢狀也算在內)。
//那我大部會會取名叫做hero
//這裡的順序,越後面代表越重要。所以是以傳進來的參數為主
this.settings = $.extend({}, defaults, $.pg.defaults, this.args) ;
this.init() ;
}
Plugin.prototype =
{
init: function()
{
var self = this ;
self.hero
.addClass(self.settings.ttClass) //
.html( self.ele$.attr('data-tooltip') ) ;
self.bindEvent() ;
}
, bindEvent: function()
{
var self = this ;
self.ele$
.on('mouseenter', function(e)
{
self.hero
.css(
{
border: self.settings.ttBorder,
'background-color': self.settings.ttBgColor,
padding: self.settings.ttPadding,
color: self.settings.ttColor,
top: e.clientY,
left: e.clientX,
})
.show() ;
})
.on('mouseleave', function()
{
self.hero.hide() ;
}) ;
}
}
$.fn[pluginName] = function() {
//處裡套件全域設定
args = Array.prototype.slice.call(arguments) ;
return this.each(function() {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, args)); //吃參數
}
else if ($.isFunction(Plugin.prototype[args[0]]))
{
$.data(this, 'plugin_' + pluginName)[args[0]](args[1]); //吃參數
}
else
{
console.log('wrong way to use this method:' + args[0]) ;
}
});
}
這樣寫雖然看起來很麻煩
但是擴充功能的時候你就會覺得他很方便。
完全就是物件導向,所以當你的套件生出來的物件很多也不怕。
而且完全支援以下的用法
$('#id1').ryTooltip() ; //沒參數
$('#id1').ryTooltip({xxx: ooo}) ; //有參數地執行套件
$('#id1').ryTooltip('method', arguments obj) ; //執行套件method
另外就是,假如套件產生出來的元素只有一組
我會把它叫做hero
如果是那種產生很多組同階層的元素
那我會取一個soldiers or troops
還滿符合語意的。
最後是DEMO頁面。
http://ry.url.tw/wp/doc/a2.htm
不過當然,現在我們的進度,還很前面。
慢慢地,我們會讓我們的套件設計越發合理。
下一次,我們來寫寫看
如果沒有觸發的元素怎麼辦? 例如說這樣使用: $.showLocation() ;
假如我的套件是一個DIV,上面顯示滑鼠當前座標位置!
除此之外,目前的
1.參數控管也不太好
老是用arguments,到時候真正的參數已經巢狀到不知道第幾層去了。
2.事件的綁定,也是有點問題。
這些我們都會慢慢解決。
期待明天的相會喔