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 相关文章推荐
jQuery 方法大全方便学习参考
Feb 25 Javascript
javascript delete 使用示例代码
Mar 29 Javascript
js动态修改input输入框的type属性(实现方法解析)
Nov 13 Javascript
javascript实现在网页中运行本地程序的方法
Feb 03 Javascript
JavaScript开发者必备的10个Sublime Text插件
Feb 27 Javascript
基于jquery fly插件实现加入购物车抛物线动画效果
Apr 05 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
Jan 06 Javascript
Vue.js常用指令之循环使用v-for指令教程
Jun 27 Javascript
vue3.0 CLI - 2.6 - 组件的复用入门教程
Sep 14 Javascript
详解Vue 动态组件与全局事件绑定总结
Nov 11 Javascript
jQuery zTree树插件的使用教程
Aug 16 jQuery
vue iview的菜单组件Mune 点击不高亮的解决方案
Nov 01 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
PHP概述.
2006/10/09 PHP
php查看session内容的函数
2008/08/27 PHP
php获取远程图片并下载保存到本地的方法分析
2016/10/08 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
PHP闭包定义与使用简单示例
2018/04/13 PHP
PHP基于cookie实现统计在线人数功能示例
2019/01/16 PHP
javascript XML数据显示为HTML一例
2008/12/23 Javascript
js 替换功能函数,用正则表达式解决,js的全部替换
2010/12/08 Javascript
jquery easyui 对于开始时间小于结束时间的判断示例
2014/03/22 Javascript
JavaScript避免内存泄露及内存管理技巧
2014/09/05 Javascript
jQuery实现鼠标滑过链接控制图片的滑动展开与隐藏效果
2015/10/28 Javascript
日常收集整理的JavaScript常用函数方法
2015/12/10 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
精通JavaScript的this关键字
2020/05/28 Javascript
基于JS实现带动画效果的流程进度条
2018/06/01 Javascript
Vuejs开发环境搭建及热更新【推荐】
2018/09/07 Javascript
Echarts实现多条折线可拖拽效果
2019/12/19 Javascript
把项目从Python2.x移植到Python3.x的经验总结
2015/04/20 Python
答题辅助python代码实现
2018/01/16 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
pygame实现俄罗斯方块游戏(AI篇2)
2019/10/29 Python
Django单元测试中Fixtures的使用方法
2020/02/26 Python
python开发一个解析protobuf文件的简单编译器
2020/11/17 Python
css3中background新增的4个新的相关属性用法介绍
2013/09/26 HTML / CSS
英语专业应届生求职信范文
2013/11/15 职场文书
先进集体事迹材料
2014/02/17 职场文书
体育之星事迹材料
2014/05/11 职场文书
有限责任公司股东合作协议书
2014/12/02 职场文书
目标责任书格式范文
2015/05/11 职场文书
飞越疯人院观后感
2015/06/09 职场文书
法制教育观后感
2015/06/17 职场文书
2019年教师节活动策划方案
2019/09/09 职场文书
MySQL中in和exists区别详解
2021/06/03 MySQL
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
2021/11/27 Vue.js
4种方法python批量修改替换列表中元素
2022/04/07 Python