placeholder属性多浏览器兼容性方案
最近项目开发中遇到不少蛋疼的问题,每一个问题都可单独拿出来探讨,前端领域就是这样,浏览器对标准支持不一,国内IE市场仍有相当的占有率,无端的提高了开发和维护成本。
在本篇文章将来探讨placeholder这个属性,该属性是HTML5提出的一个属性,
占位符的属性值在用户录入数据时用来作为一个简短的提示。规范中明确指出占位符不应该用来代替<code>label</code>标签,如果有较长的描述,可以单独放置比较合适。W3C文档参考地址。
占位符(placeholder),如果使用在M端,则不用考虑兼容问题,浏览器基本上都支持,但是PC端的支持情况却惨不忍睹,不用我提及都会想到万恶的IE吧。关于浏览器的支持情况看以参考placeholder浏览器支持,IE9及以下浏览器都不支持该属性。
从上述可以看出,像京东、QQ等大型互联网注册页面,没有使用placeholder,而是使用label或者label定位来添加描述的原因。
下面说说自己在PC端项目中采用placeholder遇到的问题以及处理方法(兼容IE8+及现代浏览器)。
问题一、placeholder设置文本颜色问题
解决方式:使用placeholder伪类或者伪元素,处理如下:
// Firefox 4-18 input:-moz-placeholder, textarea:-moz-placeholder { color: #f0f; } // Firefox 19+ //::-moz-placeholder 伪元素在Firefox 19+替代了之前的 :-moz-placeholder 伪类. input::-moz-placeholder, textarea::-moz-placeholder{ color: #f0f; } // Internet Explorer 10+ // 经测试,现在这种写法在IE10+上设置没有反应,兼容性还有待探讨 :-ms-input-placeholder, textarea:-ms-input-placeholder{ color: #f0f; } // Safari and Chrome // 必须加上元素标签,不然不生效 input::-webkit-input-placeholder, textarea::-webkit-input-placeholder{ color: #f0f; }
对于不支持设置placeholder文本颜色的浏览器,只能通过js脚本来控制了,将在问题二中一并处理。
问题二、placeholder多浏览器支持问题
解决方式:在不支持的浏览器中可以使用js脚本来统一处理,因IE不同版本支持情况各异,所以统一使用脚本处理,其它现代浏览器不用考虑。
// 判断当前是否是IE浏览器(IE6-11) // 因IE6/7已做特殊处理,在此不再过滤。 if("ActiveXObject" in window){ $('input[placeholder],textarea[placeholder]').each(function() { var $this = $(this), txt_placeholder = $this.attr('placeholder'); if(this.type == 'hidden') return true; // 初始化值 if($this.val() === '') { // 此处的txt-placeholder就是用来设置placeholder文本颜色的。 $this.val(txt_placeholder).addClass('txt-placeholder'); } $this.off('.placeholder'); // 获得焦点事件 $this.on('focus.placeholder', function() { if($this.val() === txt_placeholder) { $this.val('').removeClass('txt-placeholder'); } }) // 失去焦点事件 .on('blur.placeholder', function() { if($this.val() === '') { $this.val(txt_placeholder).addClass('txt-placeholder'); } }); }); }
2015-07-20补充:
在IE中使用JS设置input[type=”password”]控件时,placeholder作为value值形式显示,默认为圆点!
在低版本IE浏览器中不建议使用placeholder,可以使用label定位来代替。下面是IE8/9中对password做的兼容及特殊处理:
if("ActiveXObject" in window){ $('input[placeholder],textarea[placeholder]').each(function() { var $this = $(this), type = this.type, isPassword = type == 'password' ie89 = IE_Version == 8.0 || IE_Version == 9.0, txt_placeholder = $this.attr('placeholder'); if(type == 'hidden') return true; if($this.val() === '') { if(isPassword) { if(ie89) { $this.prev('label').show(); } }else { $this.val(txt_placeholder).addClass('txt-placeholder'); } } $this.off('.placeholder'); $this.on('focus.placeholder', function() { var txt_placeholder = $this.attr('placeholder'); if(isPassword) { if(ie89) { $this.prev('label').hide(); } }else { if($this.val() === txt_placeholder) { $this.val('').removeClass('txt-placeholder'); } } }).on('blur.placeholder', function() { var txt_placeholder = $this.attr('placeholder'); if($this.val() === '') { if(isPassword) { if(ie89) { $this.prev('label').show(); } }else { $this.val(txt_placeholder).addClass('txt-placeholder'); } } }); }); }
问题三、placeholder兼容性方案和validate.js插件校验融合问题
解决方式:如果你的validate.js插件通过input/change/propertychange/foucus/blur等事件来处理的,在IE浏览器中需要增加针对解决问题二的特殊过滤,即:
如果该input控件为必填项,校验是需做如下处理:
// IE支持placholder 兼容 var isIE = "ActiveXObject" in window; if(isIE && $zt.attr('placeholder') === value) { value = ''; }
如果是绑定propertychange事件,因为在IE中JS赋值也会触发propertychange事件,所以需要增加如下过滤:
if(value === $zt.attr('placeholder')) return;
以免placeholder赋值给value时会进行校验。如果想链接propertychange事件相关情况可以查看文章:实时监听输入框值变化的兼容性方案。
当然前端市场上,也有一些javascript ployfill,来解决部分浏览器无法支持的情况。例如:
1.Placeholders.js
Placeholders.js is a JavaScript polyfill for the HTML5 placeholder attribute. It’s lightweight, has zero dependencies and works in pretty much any browser you can imagine.
2.jquery.input-placeholder-polyfill.js
3.jquery-placeholder
看了下上述的源码,从技术层面看,与上述实现方式大同小异。仅供读者参考。
问题四、从产品层面上看,当用户输入文字时,placeholder文本描述就消失了,这个用户体验有点不妥
解决方式:Google了下,还有真有解决该问题的案例,国外技术发展就是快哈,不能不佩服哈~~。但是此种方案要想在国内实现,只能使用JS来写了,CSS写光浏览器支持问题就可以直接pass掉了。附上地址供大家观摩adaptive-placeholders。
转载申请
本作品采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,文章内图片请保留全部内容。