龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

javascript 文本框水印/占位符实现方法

时间:2012-12-29 08:41来源:未知 作者:admin 点击:
分享到:
本文章介绍了关于javascript水印效果,我们经常会看到一些网站在输入框有友好提示,这些都是在文本框了,除了可以用css实现利用js也可以实现哦。 普遍的做法 现在普遍使用的做法是通
本文章介绍了关于javascript水印效果,我们经常会看到一些网站在输入框有友好提示,这些都是在文本框了,除了可以用css实现利用js也可以实现哦。

普遍的做法
现在普遍使用的做法是通过表单元素的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>

精彩图集

赞助商链接