HTML5中文本框的新屬性placeholder是個非常好用的屬性,但是IE系列直至IE9都不支持這一屬性,這就讓大家在用這一屬性的時候有些猶豫不決。自己曾經寫過很多類似共的小控件,但是都不是很通用,這里分享一個漸進增強的自定義placeholder的jQuery插件。有點是使用簡單,大家也可以根據自己的需要進行改進。平常寫jQuery插件比較少,考慮到用jQuery的同學比較多,這里就用jQuery插件的形式編寫了。
在這里簡單的介紹一下實現思路。
1.表現與html5原生的placeholder盡量類似
2.漸進增強對于支持placeholder的瀏覽器不做處理
一、首先是幾個工具方法:
1.supportProperty(nodeType, property),獲取瀏覽器是否支持某一控件的某一屬性
2.getPositionInDoc(target, parent),獲取對象在文檔中的位置
3.$c,一個快速創(chuàng)建Dom對象的方法
這幾個工具方法都是一些比較常見通用的方法,如果你有自己的或者更合適的可以自行替換。
二、主體,CustomPlaceholder對象。這個對象主要是維護每一個文本框的信息,包括其位置,應該顯示的提示信息等等,另外它還包含創(chuàng)建提示信息以及定位等方法以及對象的相應事件。
事件主要是在initEvents函數中進行的處理,這里特別要注意的是對提示信息事件的處理,當提示信息被點擊時焦點應該被重新定位到文本框。而文本框要處理的則是focus和blur事件。
$(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';
}
});
CustomPlacehodler對象的兩個主要方法是createHintLabel(text, position)和position()。createHintLabel是用于創(chuàng)建提示信息的DOM對象并對其進行定位,并返回這個對象。position方法用于強制對提示消息進行重新定位。主要用于頁面大小改變的情況。這兩個方法的功能和實現都比較簡單。
三、插件的功能實現部分。jQuery插件實現方式就不多說了。這里首先進行了能力檢測,如果原生支持placeholder則直接返回。
if(supportProperty('input', 'placeholder')){
return;
}
接下來是根據選擇的input對象,生成相應的CustomPlaceholder對象,保存在數組中,并獲取每個對象的提示信息的DOM對象,添加到容器中,最后將容器附加到body對象中。
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];
customPlaceholders.push(new CustomPlaceholder(box, input, option));
}
document.body.appendChild(box);
}
最后還有一件比較重要的事情,為window對象綁定resize事件,當window對象觸發(fā)resize事件時對所有的customPlacehoder對象進行重新定位。
$(window).bind( 'resize', function(e){
for(var i = 0, len = customPlaceholders.length; i < len; i++){
var customPlaceholder = customPlaceholders[i];
customPlaceholder.position();
}
});
這個簡單的小插件到這里就寫完了。
插件源碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
( 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); |