javascript 文本框水印/占位符(watermark/placeholder)实现方法


Posted in Javascript onJanuary 15, 2012

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/
Javascript 相关文章推荐
innerHTML,outerHTML,innerTEXT三者之间的区别
Jan 28 Javascript
JavaScript中的数学运算介绍
Dec 29 Javascript
修改或扩展jQuery原生方法的代码实例
Jan 13 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
Jul 01 Javascript
使用javascript插入样式
Mar 14 Javascript
RequireJS多页面应用实例分析
Jun 29 Javascript
Bootstrap模态窗口源码解析
Feb 08 Javascript
JQuery查找子元素find()和遍历集合each的方法总结
Mar 07 Javascript
jQuery实现select下拉框获取当前选中文本、值、索引
May 08 jQuery
jQuery之动画ajax事件(实例讲解)
Jul 18 jQuery
详解Vue-cli代理解决跨域问题
Sep 27 Javascript
swiper自定义分页器的样式
Sep 14 Javascript
jQuery-Easyui 1.2 实现多层菜单效果的代码
Jan 13 #Javascript
20个最新的jQuery插件
Jan 13 #Javascript
JSON 数据格式介绍
Jan 13 #Javascript
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
Jan 13 #Javascript
ASP.NET jQuery 实例5 (显示CheckBoxList成员选中的内容)
Jan 13 #Javascript
ASP.NET jQuery 实例4(复制TextBox的文本到本地剪贴板上)
Jan 13 #Javascript
ASP.NET jQuery 实例3 (在TextBox里面阻止复制、剪切和粘贴事件)
Jan 13 #Javascript
You might like
十大催泪虐心动漫,你能坚持看到第几部?
2020/03/04 日漫
在apache下限制每个虚拟主机的并发数!!!!
2006/10/09 PHP
PHP 验证码不显示只有一个小红叉的解决方法
2013/09/30 PHP
php采用file_get_contents代替使用curl实例
2014/11/07 PHP
Yii2框架引用bootstrap中日期插件yii2-date-picker的方法
2016/01/09 PHP
PHP微信PC二维码登陆的实现思路
2017/07/13 PHP
PHP二维数组分页2种实现方法解析
2020/07/09 PHP
怎么让脚本或里面的函数在所有图片都载入完毕的时候执行
2006/10/17 Javascript
innerText 使用示例
2014/01/23 Javascript
JavaScript中join()方法的使用简介
2015/06/09 Javascript
详细分析JavaScript变量类型
2015/07/08 Javascript
基于jQuery实现收缩展开功能
2016/03/18 Javascript
AngularJS打开页面隐藏显示表达式用法示例
2016/12/25 Javascript
js模拟百度模糊搜索的实例
2017/08/04 Javascript
一篇文章让你彻底弄懂JS的事件冒泡和事件捕获
2017/08/14 Javascript
vue+axios 前端实现的常用拦截的代码示例
2018/08/23 Javascript
ES6 系列之 Generator 的自动执行的方法示例
2018/10/19 Javascript
微信小程序实现搜索指定景点周边美食、酒店
2019/05/18 Javascript
JS数组方法slice()用法实例分析
2020/01/18 Javascript
ES6函数和数组用法实例分析
2020/05/23 Javascript
详解Python爬虫的基本写法
2016/01/08 Python
Python正则表达式经典入门教程
2017/05/22 Python
Python序列循环移位的3种方法推荐
2018/04/09 Python
Pandas GroupBy对象 索引与迭代方法
2018/11/16 Python
Python 基于FIR实现Hilbert滤波器求信号包络详解
2020/02/26 Python
python实现梯度下降和逻辑回归
2020/03/24 Python
pytorch查看通道数 维数 尺寸大小方式
2020/05/26 Python
基于TensorFlow的CNN实现Mnist手写数字识别
2020/06/17 Python
使用简单的CSS3属性实现炫酷读者墙效果
2014/01/08 HTML / CSS
德国价格合理的品牌商品购物网站:averdo
2019/03/21 全球购物
动画设计系毕业生求职信
2014/07/15 职场文书
入学证明
2015/06/23 职场文书
2015年教务处干事工作总结
2015/07/22 职场文书
大学生心理健康教育心得体会
2016/01/12 职场文书
SQL Server查询某个字段在哪些表中存在
2022/03/03 SQL Server
Python数据结构之队列详解
2022/03/21 Python