由於基礎庫已大體完成,從今天隔三差四就開發一個外掛程式出來。今天給大家介紹的placeholder外掛程式。由於jQuery已有幾個這樣的外掛程式,下回來研究一下,很快就搞出自己的外掛程式。
目前jQuery中最好的jQuery當屬 danielstocks的jQuery-Placeholder,但細看還是有許多改進。它的思路是這樣,如果瀏覽器已經原生支援HTML5的placeholder就立即返回jQuery執行個體,不做任何修改,要使用者自行設定placeholder。如果不支援,分兩種情況。如果不是密碼框,它就會在這input或textarea控制項添加一個類名placeholder,目的是讓輸入字型變淡,當然這類名只會在輸入框裡面沒有內容時才添加,並將使用者佈建的placeholder屬性的值,賦到value中去。其他就是一系列行為類比了。首先,當輸入框獲得焦點時,就檢測裡面的內容是否等於placeholder,如果不相等,說明使用者正在輸入,要清除placeholder類名,並將使用者內容回填過去。如果失去焦點,又檢測裡面的內容,如果為空白,則再添加placeholder類名,與將使用者佈建的placeholder屬性的值,賦到value中去。為此danielstocks特地寫了一個Placeholder類,來處理這些行為。此外,使用者提交表單時或頁面重新整理時,還要做相應處理。大家聽我說到這裡,頭都大了吧。嗯,是非常複雜。我還沒有說密碼框的情況呢。密碼框還分兩種,一種是可能修改其type屬性,一種不能(因為IE678不充許修改)。我的整個思路就是建立密碼框不能修改的情況下,免去這麼多分支。下面是我的思路,danielstocks的實現自已到github中看源碼。
我的想法,即,如果通過在輸入框的value值來類比placeholder,弊端太多,要注意表單提交與IE不能修改type屬性什麼的,於是決定只做一個層蒙在輸入框上去。當使用者輸入時就讓浮層隱去,如果離開時,發現裡面沒有內容就浮出來。同時我也不管focus, blur等不能冒泡的事件,我只綁定click事件(當使用者點到浮層上時),input事件(使用者輸入時,向前消去內容會有可能重新讓浮層出現),mouseout事件(使用者滑鼠離開輸入框時)。首先是浮層,這個浮層我決定用一個不常用的HTML元素kbd來類比,然後動態產生插入到輸入框的後面,並設法讓它定位到輸入框的左上方。
function fix(input, node, val) {//node = input[0] var placeholder = $._data(node,"placeholder");首先判定它是否已插入了浮層 if(!placeholder){ placeholder = $("").afterTo(input).css({ position: "relative", left: -1 * (input.innerWidth() + parseFloat(input.css("marginRight"))) , top: -1 * parseFloat(input.css("paddingTop")), display: "inline-block", w: input.width() - 4 , h: input.height(), border: 'none', cursor: 'text', bgc: input.css("bgc"),//背景 c: "#808080", "font-weight": input.css("font-weight"), "font-size": input.css("font-size") }); $._data( node,"placeholder", placeholder ); } return placeholder.text(val); }
然後是綁定事件,click事件直接綁到剛才kbd元素上,mouseout,input則綁到輸入框上。由於不知使用者是否已在輸入框綁定了事件,因此我們移除事件時必須傳入回呼函數的引用。不過這樣也好,那麼我們所有輸入框的mouseout回調與input回調都共用一個了。
input.bind("mouseout,input",callback); var NATIVE_SUPPORT = !!("placeholder" in document.createElement( "input" )); $.fn.placeholder = function(val) { return this.each(function() { if( NATIVE_SUPPORT ){ this.setAttribute("placeholder", val) }else{ var input = $(this); var placeholder = fix(input, this, val ); placeholder.css("display" , (input.val() ? "none" : "inline-block")) placeholder.click(function(){ placeholder.css("display","none" ); }); input.bind("mouseout,input",callback); } }); }
共用回呼函數:
function callback( e ){ var placeholder = $._data( this,"placeholder"); if( placeholder ){ placeholder.css("display" , this.value ? "none" : "inline-block"); if(!this.value ){ this.focus(); } }}
它的用法很簡單,比如
$("#password").placeholder("請輸入密碼")
如果對樣式不滿意,我們可以直接使用$._data( input,"placeholder")得到kbd的mass執行個體來設定樣式,而標準瀏覽器下只有webkit系統可以修改樣式,使用::-webkit-input-placeholder虛擬元素。
除此以後,它還有對應的解除綁定方法:unplaceholder
$.fn.unplaceholder = function( ){ return this.each(function() { if( NATIVE_SUPPORT ){ this.setAttribute("placeholder", ""); }else{ var placeholder = $._data( this,"placeholder") if( placeholder ){ var input = $(this); input.unbind("mouseout,input",callback); input.removeData("placeholder",true); placeholder.unbind("click") placeholder.remove(); } } }); }
下面就是完整例子:
IE下如果報錯,請它重新整理頁面,再不行,下載回來看。
<br /><!DOCTYPE html><br /><html><br /> <head><br /> <meta charset="utf-8" /><br /> <title>placeholder by 司徒正美</title></p><p> <style type="text/css"><br /> </style><br /> <script type="text/javascript" src="http://files.cnblogs.com/rubylouvre/mass.js"></p><p> </script><br /> <script type="text/javascript"><br /> window.onload = function(){<br /> $.require("ready,20120217_placeholder",function(){<br /> $("input").placeholder("請輸入密碼")<br /> })<br /> }<br /> </script><br /> </head><br /> <body><br /> <input type="password"><br /> </body><br /></html><br />
運行代碼
我的placeholder的完整源碼,請到這裡看。