这篇文章发布于 2012年02月6日,星期一,23:15,归类于 Web综合。 阅读 186022 次, 今日 7 次 43 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=2169
一、HTML5 placeholder相关的引言
placeholder
在英汉词典中解释成了“占位符”。要理解并不难,请看此场景:
“咦?”您可能会疑问,“这不是就是狗狗树下撒尿尿”。确实,该场景可以较好的诠释placeholder
“占位符”之意。我们不妨将placeholder
来个临时拆分:place + hold + er.
对于上面场景就有:place指树及附近区域;hold表示镇住了其他狗狗——此处为洒家的地盘;而er则将重点转到了尿上。于是,在这个例子中,placeholder
指的就是:“足以镇住这块区域的狗狗的尿”,即“占据树木的尿”,简称为“占树尿”;至此,“占位符”之意就很好理解了,也就是“占据位置的字符”。无论是传统软件或是web应用中,这个玩意都是相当常见的,瞪大眼睛随便瞄瞄,得,立马有了~~
如我FireFox浏览器右上方的搜索占位符:
或是当前我写这篇文章的后台页面的右侧加标签的小框框:
在可输入控件中,“占位符”一般作提示用,简洁明了,空间利用率高。然而,在XHTML的时代,控件元素并没有placeholder
这一属性,因此,我们的做法都是通过JavaScript做模拟,例如下面这个未分离的不推荐的写法:
<input value="@zhangxinxu" onfocus="javascript:if(this.value='@zhangxinxu'){this.value='';}" onblur="javascript:if(!this.value){this.value='@zhangxinxu';}" />
效果就是下面这个(如果看不到效果,请点击这里查看原文):
时代总是不断变化的,在HTML5中,想input
文本框或是textarea
文本域已经有了占位符功能,其属性名就是placeholder
。
最基本例子:
<input id="email" type="email" placeholder="zhangxinxu@zhangxinxu.com" size="26" />
您可以狠狠地点击这里:HTML5占位符基本实例demo
目前,现代浏览器均早已支持placeholder
占位符属性。好定西不用白不用啊,因此,在前年,我就将HTML5的placeholder占位符属性应用在实际项目中了。在这一年多的应用中,还是有些磕磕碰碰,在此作为经验分享下。一来加深大家与placeholder
的认识,二是希望大家可以积极大胆应用一些HTML5的新特性。
然后,还要对占位符的一些应用做扩展。本文内容多而杂,不过都是些值得花时间咀嚼的东西。
二、placeholder的浏览器表现差异
这里的浏览器指:FireFox, Opera, Chrome. IE浏览器因为没有买到回程的火车票还在家里头过年呢!
在占位符基本demo中,偶们是看不到什么本质差异。都是默认淡灰色,填写的字符都是黑色。那差异在何处呢?
我们做点小动作,就可以看出差异来了:
input { color: #333; }
添加类似上面的一段CSS代码,结果就有差别了~~
在FireFox浏览器下,占位的默认字符颜色变成#333咯;但是,Chrome浏览器以及Opera浏览器都是坚定的淡灰色。具体参见下面截图们:
您可以狠狠地点击这里:出现浏览器兼容性差异的demo
原因?
为何FireFox浏览器下会有如此表现,我觉得应该是FireFox浏览器哪里搞错了。input
选择器覆盖了系统表单样式forms.css
中的如下CSS:
input:-moz-placeholder, textarea:-moz-placeholder { color: graytext; }
如下小Bug下窥视的截图:
而实际上,根据我的理解,标签+伪类选择器的优先级要高于单纯的标签选择器。或许是对于系统CSS,FireFox浏览器走了自己的独木桥吧;而Chrome和Opera浏览器则是走的阳关道,即使如下设置:
input { color: #333!important; }
文本框依然是hold住的淡灰色文字效果。
实际问题
要想FireFox浏览器下placeholder文字默认灰色文本显示,需要不对input
/textarea
重置文字颜色。However, input
等控件默认颜色是纯黑色,对颜色挑剔的设计师们想必难以容忍这不和谐的黑色,于是乎,input
/textarea
的颜色重置在所难免,于是就有了上面展示的问题。
修复
以前,因为经验不足,对placeholder的理解不深,对于FireFox浏览器下的这样显示差异是借助于JavaScript脚本修复的(通过JS改变元素的color)。现在知道了,这完全是公公背媳妇过河——吃力不讨好啊!
较好的做法是使用CSS再次cover一遍,如下:
input { color: #333; }
/* recover again */
input:-moz-placeholder { color: #999; }
于是乎,FireFox下含有placeholder
属性的文本控件们默认颜色又是灰色滴啦~~
颜色自定义
当然,如果您不喜欢沉闷的灰色,可以通过CSS重置placeholder
占位符颜色。FireFox浏览器自然就是上面的:-moz-placeholder
. 那对于其他现代浏览器呢?是不是就是:-webkit-placeholder
以及:-o-placeholder
呢?
嘿嘿,sorry,不是的!
对于Chrome浏览器,可以使用:
::-webkit-input-placeholder { color:#34538b; }
对于Opera浏览器,虽然Opera 11版本中已经支持了placeholder, 但是目前还不支持其占位符颜色的自定义。
Opera 11 supports placeholders too, but you cannot style it (yet), and it is limited to
input
elements. In Opera 11.50textarea
placeholders are implemented too.
您可以狠狠地点击这里:placeholder颜色自定义demo
三、情何以堪的IE浏览器
IE浏览器就像是城隍庙的乌龟,一片固定区域慢慢地爬来爬去。口头上说自己对HTML5的支持怎么样怎么样,但是跟其他现代浏览器比起来,可以自己挖个洞跳进去了。想必都知道:IE6~IE9都不支持HTML5 placeholder. 我们要想渐进使用placeholder, 对于IE浏览器,必须要借助JavaScript交互了。
自然,处理这类兼容性有关的问题,少不了浏览器的判断。这里要判断的不是是不是IE(因以后IE会支持), 而是是否支持placeholder属性。如下检测代码:
var isPlaceholderSupport = "placeholder" in document.createElement("input");
于是,我们就可以自定义一个模拟placeholder效果的方法,如下代码:
var funPlaceholder = function(element) {
var placeholder = '';
if (element && !("placeholder" in document.createElement("input")) && (placeholder = element.getAttribute("placeholder"))) {
element.onfocus = function() {
if (this.value === placeholder) {
this.value = "";
}
this.style.color = '';
};
element.onblur = function() {
if (this.value === "") {
this.value = placeholder;
this.style.color = 'graytext';
}
};
//样式初始化
if (element.value === "") {
element.value = placeholder;
element.style.color = 'graytext';
}
}
};
上面代码原生JS,不依赖JS库,可以凑合使用,不过使用DOM level 1, 无法承受多交互。您可以根据自己实际需求做修改!
您可以狠狠地点击这里:IE浏览器下placeholder模拟
一些经验
为了不影响支持placeholder属性的浏览器上的表现,IE浏览器下默认placeholder占位符的显示,以及文本灰色应该交由JavaScript完成,而不是通过HTML设置,如下做法是不可取的:
<input type="email" placeholder="zhangxinxu@zhangxinxu.com" value="zhangxinxu@zhangxinxu.com" style="color:graytext;" size="26" />
对于现代浏览器,value
值即使与placeholder
一样到原子级,其还是当作value
,也就是鼠标focus
时候,值不会变;同时color:graytext
的设置让正常文本的颜色也置灰了,这是糟糕的。
四、当遇到自定义下拉
这年头,涂鸦的都能亿万富翁,没什么事情遇不到的。placeholder固然犀利,但是,某些情形下,其也会蛋疼菊紧。
如下实例,您可以狠狠地点击这里:当placeholder遇到自定义下拉
文本框focus
的时候,自定义下拉显示。点击下拉列表元素,如果速度不是很快,你会发现,占位符先填充了文本框,而后选择内容才进入!这是因为click
事件慢于blur
事件。
但是,在浏览器自带下拉中木有此问题:
解决
这可以说是很无解的问题。一般,这类问题的做法是将自定义列表的click
事件换成mousedown
事件。例如,携程旅游网首页选择日期那块:
五、表单序列化 – 脚本模拟placeholder的局限
这里所说的脚本模拟是指上面通过value
值改变模拟placeholder
的方法。
value
模拟法的局限性有两个:
其一是value
值扮演了两个角色:当value
值和placeholder
值相等时,value
值就变成了placeholder
,其余时候还是value
.
这很好理解,小张看见A女就装富二代,其他时候是实打实地和B女做朋友。只要不是蒙牛喝多的人都知道,一旦A女和B女同时出现,小张就麻烦咯 – 因为他不是鸣人,无法影分身!类似地,如果实际上的value
与placeholder
相等,value是无法同时扮演两个身份滴,于是,problem来了~~~~
其二就是占位符充当了value
的角色,于是,在表单序列化(或原生的表单提交)的时候,类似“请输入姓名”这样的文字就会误认为是输入value
值而被遍历或提交了。
在实际情况中,第一个局限性很少出现,也容易避免,因此,没什么担忧和说头的。但是,第二个局限 – 表单序列化却是个麻烦的东西!
问题显现
您可以狠狠地点击这里:value模拟法表单序列化下的问题
靠谱浏览器下点击demo页面按钮则结果很OK:
但是,诸如IE这样,使用value
模拟placeholder
属性的浏览器就直接中枪了:
怎么办?
显然,使用value
模拟placeholder
不能应付所有情况。好在,我们还有另外一种模拟方法,使用label
标签,称为label
模拟法。
六、label模拟法
这是方法是通过创建或直接使用label
标签元素来模拟。可以使用label元素覆盖,或是藏于文本控件的下方(此时文本控件背景需要transparent透明)。我们先看几个应用实例:
淘宝首页搜索的小图标的placeholder效果就是使用的该方法:
不过,为了方便学习,我们还是看简单通俗易懂的例子。您可以狠狠地点击这里:label模拟法demo
上面demo在现代浏览器下依然使用的自带placeholder特性,IE浏览器下则是使用label创建的占位符效果。我们用IE开发工具简单窥探一下,就可以看到创建的占位符元素了(此时文本框的value是空的):
限于相关代码篇幅相对长了点,这里就不展示了,您有兴趣可以在demo页面上查看。
问题
demo页面只是大致效果,其中还有些情况并没有处理。例如你想右键 → 粘贴内容的时候。
原因在与这里的label占位符是采用覆盖的形式显示在文本框上的,于是,当我们右键文本框的时候,实际上是右键的label元素(非可编辑),因此,我们无法通过鼠标粘贴内容。
占位符文字越长,该问题出现的几率就越大。
要解决这个问题,较好的做法是通过CSS/HTML解决,即label元素藏于文本框的下方,但是,文本框背景透明以显示下面的占位符文字。如果想通过事件解决,比较折腾,讲起来又是啰哩吧嗦,这个暂时先放着。
还有一个问题就是,label元素中提示的文字长度不能超过文本控件的长度~~
七、拓展:新的占位符交互形式实现
随着交互体验,以及一些潮流趋势的方法。出现了一种新的占位符交互体验方式,想必使用hotmail时候都注意到了,账户占位符提示focus
的时候并不是把占位符的内容隐掉,而是半透明了。还有Opera浏览器携带的搜索引擎框的提示效果也是如此。
当前,在web开发中,也有此形式的占位符交互效果:
QQ邮箱登陆(http://mail.qq.com)
如下截图啦:
我在上面一个demo类似原理上做了下修改,制作了一个这样子交互效果的demo,希望对有兴趣的同行能帮上点忙,您可以狠狠地点击这里:透明度变化的占位符交互demo
上面的demo必须在不支持placeholder属性的浏览器下才看得到效果。下截图来自IE9浏览器:
同样的,相关代码参考demo页面。同样是覆盖形式的label元素,右键上下文是有问题的。
八、综合:placeholder模拟jQuery插件
最后,附上一个结合了上面诸如讨论的placeholder模拟插件 – jquery.placeholder.js(很小,加上注释一百多行)
是自己今儿个晚上冒着家庭不和睦的危险写的(元宵节啊,晚饭后跑公司来了),急急忙忙,简单测试了下,日后有些bug再修补修补。
使用
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 |
实例页面
您可以狠狠地点击这里:jquery.placeholder.js插件简单测试demo
小小demo页面截图一张(后因次日添加了如何让“label提示文字在文本框下方显示”实例,因此demo实际模样与下面有些小出入):
说明
- 插件支持value模拟法和label模拟法;而且label模拟法支持新式的透明度交互效果;而且可以设置是否让FireFox, Chrome这些浏览器也以这种形式交互。
- 使用label模式模拟占位符的时候,如果文本控件没有
id
,则插件会自动创建一个随机id
. - 因为考虑到插件化,让插件藏在元素底部是不显示的(因为不能强行设置文本控件背景透明),因此插件的label元素都是覆盖在文本控件上模拟占位符效果的。因此,右键上下文是有问题的。插件对此所做的处理就是把占位符上下文的事件给墙掉了。您可以通过
labelStyle
参数改变占位符label元素的层级啊,位置什么的完善这个小问题。 - 事件仓促,bug肯定有。如果有幸被您使用了,同时发现了问题,欢迎提交bug.
九、快速结语
在这和谐的日子,我还顶着压力过来折腾文章,不容易啊。想想以前,想写到什么时候就什么时候,现在没那么自由了。一晃23:00, 我必须要撤了。本文的结语啊什么的就委屈下,不让你们出来表演了。
感谢您spend这么多time阅读到here!
本文为原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=2169
(本篇完)
- CSS :placeholder-shown伪类实现Material Design占位符交互效果 (0.284)
- 小tip: 微博新版查看大图前后浏览的另外一种实现 (0.221)
- 小tip: 如何让contenteditable元素只能输入纯文本 (0.221)
- 文本框/域文字提示自动显示隐藏jQuery小插件 (0.200)
- 小tip:FireFox下文本框/域百分比padding bug解决 (0.184)
- 残忍:IE10↘IE7-IE9 type=email的完全抛弃 (0.116)
- 有意思:textarea resize属性下纯CSS交互效果 (0.074)
- 详细了解CSS :focus-within伪类及其交互应用 (0.074)
- gitee上撸了个类似飞书OKR输入框的@提及项目 (0.074)
- 完善:HTML5表单新特征简介与举例 (0.069)
- 翻译-高质量JavaScript代码书写基本要点 (RANDOM - 0.006)
if中的判断写成了单等号
有个问题,有的时候placeholder有点长,小屏手机就不显示,求大神帮忙
当ie种文本框为密码的时候,你这种就不能适用了
jquery.placeholder.js label模拟的形式支持
OLD
placeholder.js-dome在ie下删除键入值是不会重复显示原来占位符
图片占位符placeholder.js,求推荐:http://github.atool.org/placeholder.js.html
厉害。将技术文章写得风趣幽默,膜拜!
整个文章写得清晰易于理解,膜拜!
我在用这个的时候用了一个插件enpalaceholder 但是出现ie不兼容的问题,
登录时保存密码会密码和提示重叠,不知道是什么原因??
有时候希望您能赐教
冒昧的问下,这个属性可以换行吗?
大赞。Google到这篇文章,考虑周全,行文幽默,还动手提供解决方案。大神呼之欲出!
这几天把前端重新架构了一下,用到了placeholder, 顺便在 zxx 的基础上做了一些小修改。 比如去掉了value, 模拟,去掉了点击淡化,ie效果和firefox 基本一致。添加了事件绑定去重,添加了更新placeholder 机制。添加 seajs 模块化。今天刚好闲下来没事,把更新后的代码公布一下,仓促之间,或许会有bug,欢迎指证。下载连接 http://www.dao-e.com/Common/Js/jquery.placeholder.js
光标与字体对不齐
如果同一个input 更新了 placeholder。 没有更新 placeholder 机制。重复执行$(xx).placeholder();会造成 事件重复绑定。还有就是没有 绑定 mousedown 事件,会造成,input focus 状态下placeholder显示状态,再点击,placeholder 不会消失。
“jquery.placeholder.js插件简单测试demo” 这个Demo没有加载jQuery。
@KEEN 好的,多谢提醒。已更换。
鑫旭师兄。我按照您的方法,在IE下面我的input类型是password结果出来的效果是几个圆点。希望师兄能够继续完善这个插件!
ie10怎么弄?
楼主,你好。
text框里要求提示信息为“0.00”,但是这个text框里输入的数据必须大于0.01,若小于0.01,就会出现数据错误信息。在IE8下,“0.00”会被当作text框的value而进行数据合法性检测,使用上面“六、label模拟法”,还是不行,楼主有没有什么好的建议?谢谢!
@爱吃抹茶 来份详细的描述,最好有源代码或demo之类,发送到我邮箱:zhangxinxu@zhangxinxu.com
在textarea中使用placeholder,当提示语过长时,不会换行
這個對付密碼框可不行
我的Ie6不显示,而且和“多种基于myFocus库TAB效果”js有点冲突
本地IE7/8下测试,focus后,test4和test5中placeholder字段会变的重影。。。暂时还没找到原因,求教
js设置placeholder是不是无效的?感觉并没有渲染
不错,分析的很好。
感谢分享。。
考虑了很多很全 学习了。。
楼主这种不断探求的精神非常好。文章层层深入,写得不错!
不过貌似IE下还是不能点右键进行粘贴啊?
Hi, 老张,
谢谢你的分享,我在自己的项目中应用了你介绍的方法,使用的是你在文章最后给的js插件,在IE下面运行良好。现在我遇到一个问题需要你的帮助:
在IE下面,如果启用浏览器自动填表功能,那么自动填充的内容就会和placeholder的内容叠加在一起,不知道你有没有遇到过,这种问题怎么解决呢?
谢啦~
@月光下的海芋 我倒是没有遇到过。您可以试试在页面完全load后再绑定该插件。
这个貌似和load无关,比如我网站的登录页面。当填入账号的时候,浏览器就自动填充了密码了,但是这个是并没有触发focus事件,所以内容就会和placeholder重叠了,而且如果把label放于input下面,那input就必须透明,但是对于有放于有背景色的容器里的input框来说,背景透明就更不行了
@ 清香茶韵Me 刚才测试了一下,webkit 行高设置为与字体一样大小即可。
height: 32px;
line-height:18px; /* webkit bug */
line-height: 32px\9;
@ 清香茶韵Me 这个是 行高的问题,针对 safari 单独设置不同的行高即可。
placeholder 在中safari 会有两个问题
1、设置height和line-height时, 提示语在其他浏览器中都居中,在safari不居中,但输入内容的时候,内容却是居中的;去了line-height 就可以都居中了;
2、在textarea中使用placeholder,当提示语过长时,不会换行;
这是什么问题呢?
感谢老张,好文,学习了。
感谢博主分享
好文章,楼主,demo页面重复打开,左侧js,html,css显示不出来
看好html5
http://www.zhangxinxu.com/study/201202/html5-placeholder-jquery-plugin.html 例子中test4在各浏览器中显示效果有些差异。
之前可以直接用Chrome开发工具查看到浏览器默认样式::-webkit-input-placeholde
最新的18.0 placeholder无效,也差不到这个属性了
问下博主是怎么在firebug下查看到form.css input:-moz-placeholder的?
我的是firefox10 firebug 1.91
@哀音 右半侧面板:样式 → 显示浏览器默认样式
顶个
圆霄快乐。