HTML5中文字方塊的新屬性placeholder是個非常好用的屬性,但是IE系列直至IE9都不支持這一屬性,這就讓大家在用這一屬性的時候有些猶豫不決。自己曾經寫過很多類似共的小控件,但是都不是很通用,這裡分享一個漸進增強的自訂placeholder的jQuery插件。有點是使用簡單,大家也可以依照自己的需求來改進。平常寫jQuery插件比較少,考慮到用jQuery的同學比較多,這裡就用jQuery插件的形式編寫了。
在這裡簡單的介紹一下實作思路。
1.表現與html5原生的placeholder盡量類似
2.漸進增強對於支援placeholder的瀏覽器不做處理
一、首先是幾個工具方法:
1.supportProperty(nodeType, property),取得瀏覽器是否支援某一控制項的某一屬性
2.getPositionInDoc(target, parent),取得物件在文檔中的位置
3.$c,一個快速創建Dom物件的方法
這幾個工具方法都是一些比較常見通用的方法,如果你有自己的或更合適的可以自行替換。
二、主體,CustomPlaceholder物件。 這個物件主要是維護每一個文字方塊的訊息,包括其位置,應該顯示的提示訊息等等,另外它還包含建立提示訊息以及定位等方法以及物件的相應事件。
事件主要是在initEvents函數中進行的處理,這裡特別要注意的是對提示訊息事件的處理,當提示訊息被點擊時焦點應該被重新定位到文字方塊。而文字框要處理的則是focus和blur事件。
$(self.input).bind( 'focus', function(e){
self.hint.style.display = 'none';
});
$(self.input).bind( 'blur', function(e){
if(this.value == ''){
self.hint.style.display = 'inline';
}
});
CustomPlacehodler物件的兩個主要方法是createHintLabel(text, position)和position()。 createHintLabel是用來建立提示訊息的DOM物件並對其進行定位,並傳回這個物件。 position方法用於強制對提示訊息進行重新定位。主要用於頁面大小改變的情況。這兩個方法的功能和實作都比較簡單。
三、插件的功能實現部分。 jQuery外掛實作方式就不多說了。這裡首先進行了能力檢測,如果原生支援placeholder則直接回傳。
接下來是根據選擇的input對象,生成相應的CustomPlaceholder對象,保存在數組中,並獲取每個對象的提示信息的DOM對象,添加到容器中,最後將容器附加到body對像中。
document.body.appendChild(box);
}
最後還有一件比較重要的事情,為window物件綁定resize事件,當window物件觸發resize事件時對所有的customPlacehoder物件進行重新定位。
});
這個簡單的小插件到這裡就寫完了。
外掛程式原始碼:
(function($){ var eles = { div: document.createElement('div'), ul: document.createElement('ul'), li: document.createElement('li'), span: document.createElement('span'), p: document.createElement('p'), a: document.createElement('a'), fragment: document.createDocumentFragment(), input: document.createElement('input') } var supportProperty = function(nodeType, property){ switch(arguments.length){ case 0: return false; case 1: var property = nodeType, nodeType = 'div'; property = property.split('.'); if(property.length == 1){ return typeof eles[nodeType][property[0]] !== 'undefined'; }else if(property.length == 2){ return typeof eles[nodeType][property[0]][property[1]] !== 'undefined'; } case 2: property = property.split('.'); if(property.length == 1){ return typeof eles[nodeType][property[0]] !== 'undefined'; }else if(property.length == 2){ return typeof eles[nodeType][property[0]][property[1]] !== 'undefined'; } return false; default: return false; } }; var getPositionInDoc = function(target, parent) { if (!target) { return null; } var left = 0, top = 0; do { left += target.offsetLeft || 0; top += target.offsetTop || 0; target = target.offsetParent; if(parent && target == parent){ break; } } while (target); return { left: left, top: top }; } var $c = function(tagName, id, className){ var ele = null; if(!eles[tagName]){ ele = eles[tagName] = document.createElement(tagName); }else{ ele = eles[tagName].cloneNode(true); } if(id){ ele.id = id; } if(className){ ele.className = className; } return ele; }; var CustomPlaceholder = function(box, input, option){ var self = this; var position = getPositionInDoc(input); self.input = input; self.option = {xOffset:0, yOffset:0}; for(var item in option){ self.option[item] = option[item]; } self.hint = self.createHintLabel(input.getAttribute('placeholder'), position); box.appendChild(self.hint); self.initEvents = function(){ $(self.hint).bind( 'click', function(e){ self.input.focus(); }); $(self.input).bind( 'focus', function(e){ self.hint.style.display = 'none'; }); $(self.input).bind( 'blur', function(e){ if(this.value == ''){ self.hint.style.display = 'inline'; } }); }; self.initEvents(); }; CustomPlaceholder.prototype = { createHintLabel: function(text, position){ var hint = $c('label'); hint.style.cusor = 'text'; hint.style.position = 'absolute'; hint.style.left = position.left + this.option.xOffset + 'px'; hint.style.top = position.top + this.option.yOffset + 'px'; hint.innerHTML = text; hint.style.zIndex = '9999'; return hint; }, position: function(){ var position = getPositionInDoc(this.input); this.hint.style.left = position.left + this.option.xOffset + 'px'; this.hint.style.top = position.top + this.option.yOffset + 'px'; } }; $.fn.placeholder = function(option){ if(supportProperty('input', 'placeholder')){ return; } var customPlaceholders = []; if(this.length > 0){ var box = $c('div', 'dk_placeholderfixed_box'); for(var i = 0, len = this.length; i < len; i++){ var input = this[i]; if($(input).is(':visible')){ customPlaceholders.push(new CustomPlaceholder(box, input, option)); } } document.body.appendChild(box); } $(window).bind( 'resize', function(e){ for(var i = 0, len = customPlaceholders.length; i < len; i++){ var customPlaceholder = customPlaceholders[i]; customPlaceholder.position(); } }); }; })(jQuery);