HTML5 placeholder实际应用经验分享及拓展

一、HTML5 placeholder介绍

placeholder在英汉词典中解释成了“占位符”。我们不妨将placeholder来个临时拆分:place + hold + er.placeholder指的就是:“足以镇住这块区占据位置的字符。无论是传统软件或是web应用中,placeholder都是相当常见的。

如FireFox浏览器右上方的搜索占位符:
FireFox浏览器上自带搜索的占位符效果 张鑫旭-鑫空间-鑫生活

在可输入控件中,“占位符”一般作提示用,简洁明了,空间利用率高。然而,在XHTML的时代,控件元素并没有placeholder这一属性,因此,我们的做法都是通过JavaScript做模拟,例如下面这个未分离的不推荐的写法:

<input value="www.jcodecraeer.com" onfocus="javascript:if(this.value='www.jcodecraeer.com'){this.value='';}" onblur="javascript:if(!this.value){this.value='www.jcodecraeer.com';}" />

在HTML5中,input文本框或是textarea文本域已经有了占位符功能,其属性名就是placeholder

最基本例子:

<input id="email" type="email" placeholder="www.jcodecraeer.com" size="26" />

目前,现代浏览器均早已支持placeholder占位符属性。在前年,我就将HTML5的placeholder占位符属性应用在实际项目中了。在此作为经验分享下。一来加深大家对placeholder的认识,二是希望大家可以积极大胆应用一些HTML5的新特性。

然后,还要对占位符的一些应用做扩展。本文内容多而杂,不过都是些值得花时间咀嚼的东西。

二、placeholder的浏览器表现差异

这里的浏览器指:FireFox, Opera, Chrome. IE浏览器就算了吧!

在上面那个placeholder基本例子的代码中,各浏览器基本没什么差别,现在我们增加点东西 差异就出来了:

input { color: #333; }

在FireFox浏览器下,占位的默认字符颜色变成#333;但是,Chrome浏览器以及Opera浏览器都是坚定的淡灰色。具体参见下面截图们:

placeholder浏览器差异截图placeholder浏览器差异截图placeholder浏览器差异截图

三、在不兼容placeholder的浏览器上模拟实现placeholder

label配合js模拟:

这是方法是通过创建或直接使用label标签元素来模拟。可以使用label元素覆盖,或是藏于文本控件的下方(此时文本控件背景需要transparent透明)。我们先看几个应用实例:

淘宝首页搜索的小图标的placeholder效果就是使用的该方法:

不过,为了方便学习,我们还是看简单通俗易懂的例子。

在支持的浏览器上依然使用的自带placeholder特性,IE浏览器下则是使用label创建的占位符效果。

代码如下:

html代码

<label for="email">邮箱:</label><input id="email" type="email"  placeholder="www.jcodecraeer.com" size="26"/>

js代码

var funPlaceholder = function(element) {
    //检测是否需要模拟placeholder
    var placeholder = '';
    if (element && !("placeholder" in document.createElement("input")) && (placeholder = element.getAttribute("placeholder"))) {
        //当前文本控件是否有id, 没有则创建
        var idLabel = element.id ;
        if (!idLabel) {
            idLabel = "placeholder_" + new Date().getTime();
            element.id = idLabel;
        }
        //创建label元素
        var eleLabel = document.createElement("label");
        eleLabel.htmlFor = idLabel;
        eleLabel.style.position = "absolute";
        //根据文本框实际尺寸修改这里的margin值
        eleLabel.style.margin = "2px 0 0 3px";
        eleLabel.style.color = "graytext";
        eleLabel.style.cursor = "text";
        //插入创建的label元素节点
        element.parentNode.insertBefore(eleLabel, element);
        //事件
        element.onfocus = function() {
            eleLabel.innerHTML = "";
        };
        element.onblur = function() {
            if (this.value === "") {
                eleLabel.innerHTML = placeholder; 
            }
        };
        //样式初始化
        if (element.value === "") {
            eleLabel.innerHTML = placeholder;  
        }
    }  
};
funPlaceholder(document.getElementById("email"));

问题
只是大致效果,其中还有些情况并没有处理。例如你想右键 → 粘贴内容的时候。

原因在与这里的label占位符是采用覆盖的形式显示在文本框上的,于是,当我们右键文本框的时候,实际上是右键的label元素(非可编辑),因此,我们无法通过鼠标粘贴内容。

占位符文字越长,该问题出现的几率就越大。

要解决这个问题,较好的做法是通过CSS/HTML解决,即label元素藏于文本框的下方,但是,文本框背景透明以显示下面的占位符文字。

还有一个问题就是,label元素中提示的文字长度不能超过文本控件的长度。

四、拓展:新的占位符交互形式实现

随着交互体验,以及一些潮流趋势的方法。出现了一种新的占位符交互体验方式,想必使用hotmail时候都注意到了,账户占位符提示focus的时候并不是把占位符的内容隐掉,而是半透明了。还有Opera浏览器携带的搜索引擎框的提示效果也是如此。

当前,在web开发中,也有此形式的占位符交互效果:

QQ邮箱登陆(http://mail.qq.com)
如下截图啦:
QQ邮箱登陆界面 张鑫旭-鑫空间-鑫生活

五、综合:placeholder模拟jQuery插件

最后,附上一个结合了上面诸如讨论的placeholder模拟插件 – jquery.placeholder.js(很小,一百多行)

使用
1. JS部分
如下最简单示例:

<script src="jquery1.7.1-min.js"></script>
<script src="jquery.placeholder.js"></script>
<script>
$(function() {
    $("#test").placeholder();	
});
</script>

2. 对应HTML
上面脚本对应HTML代码如下:

<input id="test" placeholder="测试" />

参数
插件相关参数参见下表:

标题描述默认
labelMode布尔型 是否使用label标签模拟占位符效果。默认为false,表示使用value模拟法false
labelStyle对象 如果使用label模拟法,则创建的label元素重置的或新的样式集{}
labelAlpha布尔型 如果使用label模拟法,其交互方式是否使用透明度切换的形式。默认为false,表示使用值显示与不显示这种交互false
labelAcross布尔型 如果使用label模拟法,同时交互方式是透明度切换,是否让所有的浏览器都是这种效果(重置现代浏览器默认placeholder交互效果)。默认为false,表示浏览器默认使用自带placeholder交互效果。false

说明

  1. 插件支持value模拟法和label模拟法;而且label模拟法支持新式的透明度交互效果;而且可以设置是否让FireFox, Chrome这些浏览器也以这种形式交互。

  2. 使用label模式模拟占位符的时候,如果文本控件没有id,则插件会自动创建一个随机id.

  3. 因为考虑到插件化,让插件藏在元素底部是不显示的(因为不能强行设置文本控件背景透明),因此插件的label元素都是覆盖在文本控件上模拟占位符效果的。因此,右键上下文是有问题的。插件对此所做的处理就是把占位符上下文的事件给墙掉了。您可以通过labelStyle参数改变占位符label元素的层级啊,位置什么的完善这个小问题。