placeholder是html5表单特性中比较好用的一条,但是苦于其向下兼容性,所以一般要做向下兼容的站点都不敢用,如果有用到的地方,也是用js简单模拟而实现的,那么有没有一个一劳永逸的方法去解决这个问题呢?
接下来我就来带大家实现这个方案:
if ('placeholder' in document.createElement('input')) return;
这句代码的意思是判断是否是支持placeholder属性的,如果支持则return,不执行下面代码。
if (this.type == 'submit' || this.type == 'button' || this.type == 'reset') return;
当然,如果input的type是一个按钮,也不需要placeholder。
接下来,就开始实现了
$.fn.placeholderSupport = function(opts){ opts = $.extend({},opts); return this.each(function(){ //main code }); }
上述代码是编写扩展$.fn插件的基本代码,后面方法会被放置进jQuery选择器返回值中,也就是$(选择器)里面直接调用。
由于$()返回可能是个jQuery对象数组,所以插件里面一般会进行each,return是标准写法,让jQuery能链接起来,如$().function()......
基础框架就搭好了,开干!
var _this = $(this); var placeholderText = _this.attr('placeholder') || ''; if (this.type == 'text' || this.type == 'email') { this.value = placeholderText; _this.on('focus', function() { if (this.value === placeholderText) this.value = ''; }); _this.on('blur', function() { if (this.value === '') this.value = placeholderText; }); }
this是each里面的每个input,先得到placeholder的值,并缓存起来。
判断type是'text'||'email'时候执行下面(html5的input type比较多,这里先做了这两个的支持,此处不做email验证);
上面代码是解决普通容器的方法,接下来就是最难缠的type='password'的时候。
var id = this.id; if (id === '') { this.id = 'placeholderBuild_' + Base.supportId; id = 'placeholderBuild_' + Base.supportId; } var label = $('<label for="' + id + '">' + placeholderText + '</label>'); var css = { 'left': 5 - $(this).outerWidth(true), 'width': $(this).outerWidth(true), 'height': $(this).outerHeight(true), 'line-height': $(this).outerHeight(true) + 'px', 'position': 'absolute', opacity: '0.5' }; var valiM = $('<span></span>').css({ position: 'relative' }); label.css(css).appendTo(valiM); valiM.insertAfter($(this)); $(this).on('focus', function() { label.hide(); }).on('blur', function() { if (this.value === '') label.show(); });
赋值id,Base是全局变量对象。
大致思路是创建一个空的<span>放到input后面,然后在这个空的span里append个label,并把label 的for id设置成input的id,(for是html5特性,所以此处略矛盾)。
给label赋值宽高,position, left,top,opacity等。
然后继续绑定focus,blur方法。
就这么简单。
调用的时候,直接在
$(function(){
$('input').placeholderSupport();
});
当有异步dom处input需要支持时候,也只组要找到这个input,然后:
$(input).placeholderSupport();
代码写很老了,没怎么优化过,Base可以用$替换,也可以用自己的全局变量对象搞定。
附上完整源代码:
placeholderSupport: function() { if ('placeholder' in document.createElement('input')) return this; if (!Base.supportId) { Base.supportId = 0; } return this.each(function(e) { Base.supportId++; if (this.type == 'submit' || this.type == 'button' || this.type == 'reset') return; var placeholderText = $(this).attr('placeholder') || ''; if (this.type == 'text' || this.type == 'email') { this.value = placeholderText; $(this).on('focus', function() { if (this.value === placeholderText) this.value = ''; }); $(this).on('blur', function() { if (this.value === '') this.value = placeholderText; }); } else if (placeholderText !== '' && this.type === 'password') { var id = this.id; if (id === '') { this.id = 'placeholderBuild_' + Base.supportId; id = 'placeholderBuild_' + Base.supportId; } var label = $('<label for="' + id + '">' + placeholderText + '</label>'); var css = { 'left': 5 - $(this).outerWidth(true), 'width': $(this).outerWidth(true), 'height': $(this).outerHeight(true), 'line-height': $(this).outerHeight(true) + 'px', 'position': 'absolute', opacity: '0.5' }; var valiM = $('<span></span>').css({ position: 'relative' }); label.css(css).appendTo(valiM); valiM.insertAfter($(this)); $(this).on('focus', function() { label.hide(); }).on('blur', function() { if (this.value === '') label.show(); }); } }); }