JavaScript 实现文本框水印与占位符兼容方案

作者:函数茶馆

时间:2026-10-26

浏览:420

本文详细介绍在HTML5 placeholder属性未被旧版浏览器(如IE9及以下)支持时,如何利用JavaScript实现文本框水印效果。文章对比了直接修改value值的传统做法与通过DOM元素绝对定位实现的更优方案,提供了完整的CSS样式与JS封装代码,并演示了如何兼容处理HTML5 placeholder属性。

文章目录

JavaScript 实现文本框水印与占位符兼容方案

Firefox、Chrome和Opera等现代浏览器已原生支持placeholder特性,但IE系列浏览器(包括IE9)仍不支持。因此,我们需要借助JavaScript来为这些不支持该特性的浏览器提供兼容方案。



普遍的做法

普遍的做法


目前广泛采用的方法是利用表单元素的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值,直接修改value可能会干扰这些功能的正常运行。


在表单提交时,需要额外处理以清空水印值,否则可能提交无效数据。


当然,可能还存在其他未列举的潜在问题。



更好的做法

更好的做法


为了避免上述问题,最佳实践是避免直接修改表单元素的value值。



假设我们有如下一个文本框:


代码如下:

<input type="text" />


既然不能改变文本框的值,我们可以通过添加一个span或其他HTML元素,并利用绝对定位将其放置在文本框上方。为了确保提示信息不产生偏移,通常需要在外部包裹一个设置了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" />

这种结构生成的HTML标记更加简洁。


相应的样式


既然最终生成的HTML结构已确定,接下来需要定义相应的CSS样式,以提升视觉效果,代码如下:


代码如下:

 
/* 标记的主要样式 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事件来控制提示信息标记的显示、隐藏及样式变化;此外,还通过点击提示信息标记来隐藏它并使表单元素获得焦点。


最后,提供一个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兼容


基于上述实现,兼容不支持HTML5 placeholder的浏览器变得简单。首先,需要判断浏览器是否支持placeholder属性:


代码如下:

var html5support = "placeholder" in document.createElement("input");

接着,对于不支持HTML5 placeholder的浏览器,提取表单元素的placeholder属性值并应用watermark,实现如下:


代码如下:

 
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/

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章