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 相关文章推荐
Js 获取当前日期时间及其它操作实现代码
Mar 04 Javascript
DOM下的节点属性和操作小结
May 14 Javascript
Mootools 1.2教程 函数
Sep 15 Javascript
20个非常棒的Jquery实用工具 国外文章
Jan 01 Javascript
将函数的实际参数转换成数组的方法
Jan 25 Javascript
javascript 事件处理、鼠标拖动效果实现方法详解
May 11 Javascript
各种页面定时跳转(倒计时跳转)代码总结
Oct 24 Javascript
JavaScript三元运算符的多种使用技巧
Apr 16 Javascript
jQuery实现下拉框左右移动(全部移动,已选移动)
Apr 15 Javascript
在Vue组件上动态添加和删除属性方法
Feb 23 Javascript
Javascript如何实现双指控制图片功能
Feb 25 Javascript
vue-router的hooks用法详解
Jun 08 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中基于ts与nts版本- vc6和vc9编译版本的区别详解
2013/04/26 PHP
jQuery向下滚动即时加载内容实现的瀑布流效果
2016/01/07 PHP
PHP+MySQL存储数据常见中文乱码问题小结
2016/06/13 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
2019/08/23 PHP
javascript 模拟JQuery的Ready方法实现并出现的问题
2009/12/06 Javascript
通过Jscript中@cc_on 语句识别IE浏览器及版本的代码
2011/05/07 Javascript
Node.js操作mysql数据库增删改查
2016/03/30 Javascript
JavaScript仿网易选项卡制作代码
2016/10/06 Javascript
JS中数组重排序方法
2016/11/11 Javascript
php register_shutdown_function函数详解
2017/07/23 Javascript
Js中async/await的执行顺序详解
2017/09/22 Javascript
vue.js整合mint-ui里的轮播图实例代码
2017/12/27 Javascript
vue中阻止click事件冒泡,防止触发另一个事件的方法
2018/02/08 Javascript
vue router总结 $router和$route及router与 router与route区别
2019/07/05 Javascript
vue ssr服务端渲染(小白解惑)
2019/11/10 Javascript
vue-cli3.X快速创建项目的方法步骤
2019/11/14 Javascript
vue 中 elment-ui table合并上下两行相同数据单元格
2019/12/26 Javascript
解决vue下载后台传过来的乱码流的问题
2020/12/05 Vue.js
Python利用ansible分发处理任务
2015/08/04 Python
Python多维/嵌套字典数据无限遍历的实现
2016/11/04 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
python实现简单日志记录库glog的使用
2019/12/13 Python
python 解决flask 图片在线浏览或者直接下载的问题
2020/01/09 Python
如何通过python检查文件是否被占用
2020/12/18 Python
网络、C以及其他硬件方面的面试题
2016/08/23 面试题
保密承诺书范文
2014/03/27 职场文书
协议书的格式
2014/04/23 职场文书
施工单位安全责任书
2014/07/24 职场文书
公司委托书格式
2014/08/01 职场文书
工作失职检讨书范文
2015/05/05 职场文书
大学生饮品店创业计划书范文
2019/07/10 职场文书
利用Selenium添加cookie实现自动登录的示例代码(fofa)
2021/05/08 Python
在Django中使用MQTT的方法
2021/05/10 Python
python利用pandas分析学生期末成绩实例代码
2021/07/09 Python
win7配置本地ftp服务器的图文教程
2022/08/05 Servers