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

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/

(0)

相关推荐

  • .properties文件读取及占位符${...}替换源码解析

    前言 我们在开发中常遇到一种场景,Bean里面有一些参数是比较固定的,这种时候通常会采用配置的方式,将这些参数配置在.properties文件中,然后在Bean实例化的时候通过Spring将这些.properties文件中配置的参数使用占位符"${}"替换的方式读入并设置到Bean的相应参数中. 这种做法最典型的就是JDBC的配置,本文就来研究一下.properties文件读取及占位符"${}"替换的源码,首先从代码入手,定义一个DataSource,模拟一下JDB

  • java遍历properties文件操作指南

    在java项目开发过程中,使用properties文件作为配置基本上是必不可少的,很多如系统配置信息,文件上传配置信息等等都是以这种方式进行保存. 同时学会操作properties文件也是java基础. 复制代码 代码如下: public class PropertiesUtil { public static Map getFileIO(String fileName){ Properties prop = new Properties(); Map propMap=new HashMap()

  • java获取properties属性文件示例

    一个属性列表可包含另一个属性列表作为它的"默认值":如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表. 因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法.但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项.相反,应该使用 setProperty 方法.如果在"不安全"的 Properties 对象(即包含非 String 的键或值)上调用 stor

  • 深入理解结构体中占位符的用法

    复制代码 代码如下: typedef union{    struct x{    char a1 : 2;    char b1 : 3;    char c1 : 3;    }x1;    char c;}my_un;int main(){    my_un a;    a.c = 100;    printf("%d/n",a.x1.c1);    printf("%d/n",sizeof(my_un)); return 0;} 输出结果:31即第一个是3,

  • iOS中修改UITextField占位符字体颜色的方法总结

    前言 最近学了UITextField控件, 感觉在里面设置占位符非常好, 给用户提示信息, 于是就在想占位符的字体和颜色能不能改变呢?下面是小编的一些简单的实现,有需要的朋友们可以参考. 修改UITextField的占位符文字颜色主要有三个方法: 1.使用attributedPlaceholder属性 @property(nullable, nonatomic,copy) NSAttributedString *attributedPlaceholder NS_AVAILABLE_IOS(6_0

  • Java遍历Properties所有元素的方法实例

    复制代码 代码如下: //初始化properties Properties pro = new Properties(); try {    InputStream inStr = ClassLoader.getSystemResourceAsStream("wahaha.properties");    pro.load(inStr);} catch (FileNotFoundException e) {    e.printStackTrace();} catch (IOExcep

  • Android 读取Properties配置文件的小例子

    开发应用的时候会有一些有可能会变得值,例如webservice地址 应用的一些ID等等,之前一直都是直接在应用中改代码,不是忘点这忘点那,于是想到了可以用Properties配置文件,我把网址等变量配置的配置文件中,这样之后再改的话就直接改配置文件就行了,就不用改代码了下面给大家说说Properties的用法 复制代码 代码如下: public static String getPropertiesURL(Context c, String s) {  String url = null;  P

  • Json对象替换字符串占位符实现代码

    例如: 含有占位符的字符串hello,{name},your birthday is {birthday }; 提供的Json对象{name: "czonechan", birthday : "1989-07-02" } ; 替换后为 hello,czonechan,your birthday is 1989-07-02. 实现代码: 复制代码 代码如下: Object.prototype.jsonToString=function(str) { o=this; r

  • Spring加载properties文件的方法

    在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties里面的配置,这样后期只需要改动properties文件即可,不需要修改源代码,这样更加方便.在Spring中也可以这么做,而且Spring有两种加载properties文件的方式:基于xml方式和基于注解方式. 下面分别讨论下这两种方式. 1. 通过xml方式加载properties文件         我们以Spring实例化dataSource为例,我们

  • java读取properties配置文件的方法

    本文实例讲述了java读取properties配置文件的方法.分享给大家供大家参考.具体分析如下: 这两天做java项目,用到属性文件,到网上查资料,好半天也没有找到一个满意的方法能让我读取到.properties文件中属性值,很是郁闷,网上讲的获取属性值大概有以下方法,以下三种方法逐渐优化,以达到最好的效果以下都以date.properties文件为例,该文件放在src目录下,文件内容为: startdate=2011-02-07 totalweek=25 方法一: public class

随机推荐