FED实验室 - 专注WEB端开发和用户体验

placeholder属性多浏览器支持兼容性方案

CSS(3) HTML(5) JAVASCRIPT 煦涵 6778℃ 0评论

最近项目开发中遇到不少蛋疼的问题,每一个问题都可单独拿出来探讨,前端领域就是这样,浏览器对标准支持不一,国内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补充:
1. 在IE中使用JS设置input[type="password"]控件时,placeholder作为value值形式显示,默认为圆点!
2. 在低版本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

下面是「FED实验室」的微信公众号二维码,欢迎扫描关注:

FED实验室

行文不易,如有帮助,欢迎打赏!

赞赏支持 喜欢 (8)
捐赠共勉
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽