javascript 文字框浮水印/預留位置實現方法

來源:互聯網
上載者:User

普遍的做法
現在普遍使用的做法是通過表單元素的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>
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.