javascript 文本框水印/占位符(watermark/placeholder)
来源:广州中睿信息技术有限公司官网
发布时间:2012/10/21 23:25:16 编辑:admin 阅读 510
html5为表单元素(type为text/password/search/url/telephone/email)新增了一个placeholder属性,为输入框提供一种提示。Firefox/Chro

html5为表单元素(type为text/password/search/url/telephone/email)新增了一个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)大都是采用这种做法,可能还会有设置一些样式等操作。

这种做法直接操作表单元素,方便快捷,比较实用。

但它也有弊端

  1. 有些操作同样需要通过监听表单元素的value值来实现功能,比如:autocomplete、验证等
  2. 表单提交时需要清空它的值

当然可能还有其他弊端,这里不再列举。

更好的做法

为了避免引起不必要的麻烦,就要避免去改变表单元素的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";//设置高度、行高以居中        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", "").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);    };  };

以上代码分别通过表单元素的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) 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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

联系我们CONTACT 扫一扫
愿景:成为最专业的软件研发服务领航者
中睿信息技术有限公司 广州•深圳 Tel:020-38931912 务实 Pragmatic
广州:广州市天河区翰景路1号金星大厦18层中睿信息 Fax:020-38931912 专业 Professional
深圳:深圳市福田区车公庙有色金属大厦509~510 Tel:0755-25855012 诚信 Integrity
所有权声明:PMI, PMP, Project Management Professional, PMI-ACP, PMI-PBA和PMBOK是项目管理协会(Project Management Institute, Inc.)的注册标志。
版权所有:广州中睿信息技术有限公司 粤ICP备13082838号-2