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 相关文章推荐
document.all的一个比较完整的总结及案例
Jan 31 Javascript
AngularJS入门教程(一):静态模板
Dec 06 Javascript
js函数内变量的作用域分析
Jan 12 Javascript
基于jQuery实现在线选座之高铁版
Aug 24 Javascript
深入解析JavaScript编程中的this关键字使用
Nov 09 Javascript
jQuery给元素添加样式的方法详解
Dec 30 Javascript
详解ECMAScript6入门--Class对象
Apr 27 Javascript
解决vue项目打包后提示图片文件路径错误的问题
Jul 04 Javascript
react的滑动图片验证码组件的示例代码
Feb 27 Javascript
使用VueCli3+TypeScript+Vuex一步步构建todoList的方法
Jul 25 Javascript
js实现简单页面全屏
Sep 17 Javascript
JavaScript编写开发动态时钟
Jul 29 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
再说下636单管机
2021/03/02 无线电
php简单复制文件的方法
2016/05/09 PHP
在Laravel中使用DataTables插件的方法
2018/05/29 PHP
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
JavaScript 解析Json字符串的性能比较分析代码
2009/12/16 Javascript
JQuery UI的拖拽功能实现方法小结
2012/03/14 Javascript
21个JavaScript事件(Events)属性汇总
2014/12/02 Javascript
详细解密jsonp跨域请求
2015/04/15 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
JS插件overlib用法实例详解
2015/12/26 Javascript
Node.js的npm包管理器基础使用教程
2016/05/26 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
2017/10/30 Javascript
利用js给datalist或select动态添加option选项的方法
2018/01/25 Javascript
基于datepicker定义自己的angular时间组件的示例
2018/03/14 Javascript
Vue开发实现吸顶效果的示例代码
2018/08/21 Javascript
vue+element实现表格新增、编辑、删除功能
2019/05/28 Javascript
JavaScript中的类型检查
2020/02/03 Javascript
如何利用vue实现波谱拟合详解
2020/11/05 Javascript
js实现验证码干扰(动态)
2021/02/23 Javascript
python制作企业邮箱的爆破脚本
2016/10/05 Python
详解常用查找数据结构及算法(Python实现)
2016/12/09 Python
Python 生成 -1~1 之间的随机数矩阵方法
2018/08/04 Python
python 通过 socket 发送文件的实例代码
2018/08/14 Python
django框架事务处理小结【ORM 事务及raw sql,customize sql 事务处理】
2019/06/27 Python
Python实现12306火车票抢票系统
2019/07/04 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
2019/10/24 Python
利用python中的matplotlib打印混淆矩阵实例
2020/06/16 Python
澳大利亚100%丝绸多彩度假装商店:TheSwankStore
2019/09/04 全球购物
Unix如何添加新的用户
2014/08/20 面试题
军训生自我鉴定范文
2013/12/27 职场文书
汉语言文学职业规划
2014/02/14 职场文书
弘扬职业精神演讲稿
2014/03/20 职场文书
法学专业毕业生自荐信
2014/06/11 职场文书
英语三分钟演讲稿
2014/08/19 职场文书
安全施工责任书
2014/08/25 职场文书
求职自荐信范文(优秀篇)
2015/03/27 职场文书