由於基礎庫已大體完成,從今天隔三差四就開發一個插件出來。今天給大家介紹的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下如果報錯,請它刷新頁面,再不行,下載回來看。
我的placeholder的完整源碼,請到這里看。