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 相关文章推荐
Javascript技术技巧大全(五)
Jan 22 Javascript
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
Jan 15 Javascript
js快速排序的实现代码
Dec 08 Javascript
JavaScript实现的MD5算法完整实例
Feb 02 Javascript
jQuery模仿阿里云购买服务器选择购买时间长度的代码
Apr 29 Javascript
jQuery Chart图表制作组件Highcharts用法详解
Jun 01 Javascript
Angular中使用ui router实现系统权限控制及开发遇到问题
Sep 23 Javascript
在js中做数字字符串补0(js补零)
Mar 25 Javascript
浅谈vue中慎用style的scoped属性
Nov 28 Javascript
JS实现左边列表移到到右边列表功能
Mar 28 Javascript
详解从react转职到vue开发的项目准备
Jan 14 Javascript
Jquery $.map使用方法实例详解
Sep 01 jQuery
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
深入了解php4(1)--回到未来
2006/10/09 PHP
Windows下的PHP5.0详解
2006/11/18 PHP
解析PHP中的内存管理,PHP动态分配和释放内存
2013/06/28 PHP
表格 隔行换色升级版
2009/11/07 Javascript
JavaScript 继承机制的实现(待续)
2010/05/18 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
2013/01/23 Javascript
jquery实现保存已选用户
2014/07/21 Javascript
JavaScript设计模式之装饰者模式介绍
2014/12/28 Javascript
JS显示下拉列表框内全部元素的方法
2015/03/31 Javascript
jQuery实现自动滚动到页面顶端的方法
2015/05/22 Javascript
JavaScript获取各大浏览器信息图示
2015/11/20 Javascript
AngularJS动态加载模块和依赖的方法分析
2016/11/08 Javascript
jQuery实现的模拟弹出窗口功能示例
2016/11/24 Javascript
jQuery 选择符详细介绍及整理
2016/12/02 Javascript
限时抢购-倒计时的完整实例(分享)
2017/09/17 Javascript
AngularJS实现的select二级联动下拉菜单功能示例
2017/10/25 Javascript
JS中的BOM应用
2018/02/02 Javascript
Vue模拟数据,实现路由进入商品详情页面的示例
2018/08/31 Javascript
Vue.js中对css的操作(修改)具体方式详解
2018/10/30 Javascript
新手快速入门微信小程序组件库 iView Weapp
2019/06/24 Javascript
JavaScript交换变量的常用方法小结【4种方法】
2020/05/07 Javascript
Element Popover 弹出框的使用示例
2020/07/26 Javascript
JS+CSS实现炫酷光感效果
2020/09/05 Javascript
python常用函数详解
2016/09/13 Python
分享一个可以生成各种进制格式IP的小工具实例代码
2017/07/28 Python
Python3 获取一大段文本之间两个关键字之间的内容方法
2018/10/11 Python
python实现连连看辅助之图像识别延伸
2019/07/17 Python
Python笔试面试题小结
2019/09/07 Python
在python里创建一个任务(Task)实例
2020/04/25 Python
弄清Pytorch显存的分配机制
2020/12/10 Python
详解HTML5 canvas绘图基本使用方法
2018/01/29 HTML / CSS
HTML5轻松实现全屏视频背景的示例
2018/04/23 HTML / CSS
介绍一下grep命令的使用
2015/06/12 面试题
日语专业个人求职信范文
2014/02/02 职场文书
报告会主持词
2014/04/02 职场文书
Python基础之元组与文件知识总结
2021/05/19 Python