• javascript 文本框水印/占位符(watermark/placeholder)


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

  • 相关阅读:
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C# ASP.NET 优化程序性能、降低内存使用、提高程序运行速度
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    几十套业务系统集中统一授权管理、几十万账户同步多系统实现经验分享
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
  • 原文地址:https://www.cnblogs.com/lwme/p/2322831.html
Copyright © 2020-2023  润新知