Firefox/Chrome/Opera從某一版本開始已經支持這一特性,但ie系列即使是ie9也還不支持,所以需要通過javascript來兼容這些不支持placeholder特性的浏覽器。
普遍的做法
現在普遍使用的做法是通過表單元素的onfocus/onblur事件來改變value值,如下:
復制代碼 代碼如下:
<input type="text" id="text1" />
<script>
var el = document.getElementById("text1");
if (el.value == "")
el.value = "提示信息";
el.onfocus = function() {
if (this.value == "提示信息")
this.value = "";
};
el.onblur = function() {
if (this.value == "")
this.value = "提示信息";
}
</script>
jQuery的各個watermark插件(http://archive.plugins.jquery.com/plugin-tags/watermark)大都是采用這種做法,可能還會有設置一些樣式等操作。
這種做法直接操作表單元素,方便快捷,比較實用。
但它也有弊端:
有些操作同樣需要通過監聽表單元素的value值來實現功能,比如:autocomplete、驗證等
表單提交時需要清空它的值
當然可能還有其他弊端,這裡不再列舉。
更好的做法
為了避免引起不必要的麻煩,就要避免去改變表單元素的value值。
首先,假如有如下一個文本框:
復制代碼 代碼如下: <input type="text" />
既然不能改變文本框的值,那麼只能通過添加一個span或其他元素,並通過絕對定位放置到文本框之上,並在外框加一個position:relative的容器來包裝它們以保證提示信息不會產生偏移,如:
復制代碼 代碼如下:
<span style="position:relative;">
<span style="position:absolute;">提示信息</span>
<input type="text" />
</span>
無意中發現淘寶的登錄頁面並不需要額外加一層position:relative的容器來包裝也不會產生偏移,所以僅需要把提示信息的標記放在文本框之前即可,如下:
復制代碼 代碼如下:
<span style="position:absolute;">提示信息</span>
<input type="text" />
這樣子產生的標記更加簡潔。
相應的樣式
既然最終呈現的標記已經確定,那麼現在就需要定義相應的樣式,來使它看起來更美觀,如下:
復制代碼 代碼如下:
/* 標記的主要樣式 style */
.w-label {
position: absolute;
padding: 0 0 0 6px;
margin: 0;
font-size: .8em;
color: #999;
opacity: 1;
}
/* 隱藏標記 */
.w-hide {
visibility: hidden;
opacity: 0;
}
/* 表單元素獲得焦點時,標記的顏色 */
.w-active {
color: #ddd;
}
那麼html就相應的變成:
復制代碼 代碼如下:
<span class="w-label">提示信息</span>
<input type="text" />
相關的腳本
雖然不需要去改變表單元素的value值來實現效果,但還是需要通過onfocus/onblur事件來控制提示信息的標記,全部實現如下:
復制代碼 代碼如下:
/* 事件綁定 */
var addEvent = document.addEventListener ?
function(element, type, fn) {
element.addEventListener(type, fn, false);
} :
function(element, type, fn) {
element.attachEvent("on" + type, fn);
},
/* 事件解除綁定 */
removeEvent = document.removeEventListener ?
function(element, type, fn) {
element.removeEventListener(type, fn, false);
} :
function(element, type, fn) {
element.detachEvent("on" + type, fn);
},
/* 文本框水印/占位符 */
watermark = function(element, text) {
if (!(this instanceof watermark))
return new watermark(element, text);
var place = document.createElement("span");//提示信息標記
element.parentNode.insertBefore(place, element);//插入到表單元素之前的位置
place.className = "w-label";
place.innerHTML = text;
place.style.height = place.style.lineHeight = element.offsetHeight + "px";//設置高度、行高以居中
element.place = this;
function hideIfHasValue() {
if (element.value && place.className.indexOf("w-hide") == -1)
place.className += " w-hide";
}
function onFocus() {
hideIfHasValue()
if (!element.value && place.className.indexOf("w-active") == -1)
place.className += " w-active";
}
function onBlur() {
if (!element.value) {
place.className = place.className.replace(" w-active", "");
place.className = place.className.replace(" w-hide", "");
}
}
function onClick() {
hideIfHasValue();
try {
element.focus && element.focus();
} catch (ex) {}
}
// 注冊各個事件
hideIfHasValue();
addEvent(element, "focus", onFocus);
addEvent(element, "blur", onBlur);
addEvent(element, "keyup", hideIfHasValue);
addEvent(place, "click", onClick);
// 取消watermark
this.unload = function() {
removeEvent(element, "focus", onFocus);
removeEvent(element, "blur", onBlur);
removeEvent(element, "keyup", hideIfHasValue);
removeEvent(place, "click", onClick);
element.parentNode.removeChild(place);
element.place = null;
};
};
以上代碼分別通過表單元素的focus/blur/keyup事件來控制提示信息標記的顯示、隱藏及樣式;另外還通過提示信息標記的click事件來隱藏它及為表單元素獲得焦點。
最後提供一個unload方法來取消watermark。
具體使用
有了以上的js及css,那麼就可以直接使用它們來實現watermark功能了,如下演示應用及取消watermark:
復制代碼 代碼如下:
<input id="text1" type="text" />
<input type="button" id="button1" value="取消watermark" />
<script>
var m1 = watermark(document.getElementById("text1"), "提示信息");
addEvent(document.getElementById("button1"), "click", function() {
m1.unload();
});
</script>
html5 placeholder兼容
既然有了以上的實現,那麼兼容不支持html5 placeholder的浏覽器也很簡單,首先,需要判斷浏覽器是否支持placeholder:
復制代碼 代碼如下:var html5support = "placeholder" in document.createElement("input");
接著,對不支持html5 placeholder的浏覽器,提取表單元素的placeholder內容,實現如下:
復制代碼 代碼如下:
placeHolderForm = function(form) {
var ph, elems = form.elements,
html5support = "placeholder" in document.createElement("input");
if (!html5support) {
for (var i = 0, l = elems.length; i < l; i++) {
ph = elems[i].getAttribute("placeholder");
if (ph) elems[i].ph = watermark(elems[i], ph);
}
}
}
演示代碼如下:
復制代碼 代碼如下:
<form id="form2">
<fieldset>
<legend><strong>對不支持html5 placeholder的表單元素應用watermark</strong></legend>
<ul>
<li>
文本框:
<input type="text" placeholder="文本框文本框" />
</li>
<li>
密碼框:
<input type="password" placeholder="密碼框密碼框" />
</li>
<li>
多行文本:
<textarea placeholder="多行文本多行文本"></textarea>
</li>
</ul>
</fieldset>
</form>
<script>
placeHolderForm(document.getElementById("form2"));
</script>
結尾
至此,功能全部完成,放上全部代碼:點擊下載,如有額外需要可自行修改。
作者:囧月
出處:http://lwme.cnblogs.com/