input点击后placeholder中的提示消息消失
html中,placeholder作为input的一个属性,起到了在输入框中占位并提示的作用。
但是有一些浏览器,如chrome,当鼠标点击输入框时,placeholder的值不消失,只有输入数据才消失,会使前端用户体验大打折扣。
看了很多大神的方法,写了长长的js,看着有点吃力,就想到了下面这种最傻的方法解决了这个问题。
html代码:
<inputtype="text"placeholder="多个关键词空格隔开">
鼠标点击input时,placeholder中的提示信息消失:
<inputtype="text"placeholder="多个关键词空格隔开"onfocus="this.placeholder=‘‘"onblur="this.placeholder=‘多个关键词空格隔开‘">
PlaceHolder的两种实现方式
placeholder属性是HTML5中为input添加的。在input上提供一个占位符,文字形式展示输入字段预期值的提示信息(hint),该字段会在输入为空时显示。
如
<inputtype="text"name="loginName"placeholder="邮箱/手机号/QQ号">
目前浏览器的支持情况
然而,虽然IE10+支持placeholder属性,它的表现与其它浏览器也不一致
•IE10+里鼠标点击时(获取焦点)placeholder文本消失
•Firefox/Chrome/Safari点击不消失,而是键盘输入时文本消失
这相当恶心,如果使用了placeholder属性。产品经理还是不依不饶,会讲为什么IE里是点击的时候提示文本消失,Chrome里却是键盘输入的时候提示文本消失。要求前端工程师改成一样的表现形式。鉴于此,以下两种实现方式均不采用原生的placeholder属性。
两种方式的思路
1.(方式一)使用input的value作为显示文本
2.(方式二)不使用value,添加一个额外的标签(span)到body里然后绝对定位覆盖到input上面
两种方式各有优缺点,方式一占用了input的value属性,表单提交时需要额外做一些判断工作,方式二则使用了额外的标签。
方式一
/** *PlaceHolder组件 *$(input).placeholder({ *word://@string提示文本 *color://@string文本颜色 *evtType://@stringfocus|keydown触发placeholder的事件类型 *}) * *NOTE: *evtType默认是focus,即鼠标点击到输入域时默认文本消失,keydown则模拟HTML5placeholder属性在Firefox/Chrome里的特征,光标定位到输入域后键盘输入时默认文本才消失。 *此外,对于HTML5placeholder属性,IE10+和Firefox/Chrome/Safari的表现形式也不一致,因此内部实现不采用原生placeholder属性 */ $.fn.placeholder=function(option,callback){ varsettings=$.extend({ word:'', color:'#ccc', evtType:'focus' },option) functionbootstrap($that){ //somealias varword=settings.word varcolor=settings.color varevtType=settings.evtType //default vardefColor=$that.css('color') vardefVal=$that.val() if(defVal==''||defVal==word){ $that.css({color:color}).val(word) }else{ $that.css({color:defColor}) } functionswitchStatus(isDef){ if(isDef){ $that.val('').css({color:defColor}) }else{ $that.val(word).css({color:color}) } } functionasFocus(){ $that.bind(evtType,function(){ vartxt=$that.val() if(txt==word){ switchStatus(true) } }).bind('blur',function(){ vartxt=$that.val() if(txt==''){ switchStatus(false) } }) } functionasKeydown(){ $that.bind('focus',function(){ varelem=$that[0] varval=$that.val() if(val==word){ setTimeout(function(){ //光标定位到首位 $that.setCursorPosition({index:0}) },10) } }) } if(evtType=='focus'){ asFocus() }elseif(evtType=='keydown'){ asKeydown() } //keydown事件里处理placeholder $that.keydown(function(){ varval=$that.val() if(val==word){ switchStatus(true) } }).keyup(function(){ varval=$that.val() if(val==''){ switchStatus(false) $that.setCursorPosition({index:0}) } }) } returnthis.each(function(){ var$elem=$(this) bootstrap($elem) if($.isFunction(callback))callback($elem) }) }
方式二
$.fn.placeholder=function(option,callback){ varsettings=$.extend({ word:'', color:'#999', evtType:'focus', zIndex:20, diffPaddingLeft:3 },option) functionbootstrap($that){ //somealias varword=settings.word varcolor=settings.color varevtType=settings.evtType varzIndex=settings.zIndex vardiffPaddingLeft=settings.diffPaddingLeft //defaultcss varwidth=$that.outerWidth() varheight=$that.outerHeight() varfontSize=$that.css('font-size') varfontFamily=$that.css('font-family') varpaddingLeft=$that.css('padding-left') //process paddingLeft=parseInt(paddingLeft,10)+diffPaddingLeft //redner var$placeholder=$('<spanclass="placeholder">') $placeholder.css({ position:'absolute', zIndex:'20', color:color, width:(width-paddingLeft)+'px', height:height+'px', fontSize:fontSize, paddingLeft:paddingLeft+'px', fontFamily:fontFamily }).text(word).hide() //位置调整 move() //textarea不加line-heihgt属性 if($that.is('input')){ $placeholder.css({ lineHeight:height+'px' }) } $placeholder.appendTo(document.body) //内容为空时才显示,比如刷新页面输入域已经填入了内容时 varval=$that.val() if(val==''&&$that.is(':visible')){ $placeholder.show() } functionhideAndFocus(){ $placeholder.hide() $that[0].focus() } functionmove(){ varoffset=$that.offset() vartop=offset.top varleft=offset.left $placeholder.css({ top:top, left:left }) } functionasFocus(){ $placeholder.click(function(){ hideAndFocus() //盖住后无法触发input的click事件,需要模拟点击下 setTimeout(function(){ $that.click() },100) }) //IE有些bug,原本不用加此句 $that.click(hideAndFocus) $that.blur(function(){ vartxt=$that.val() if(txt==''){ $placeholder.show() } }) } functionasKeydown(){ $placeholder.click(function(){ $that[0].focus() }) } if(evtType=='focus'){ asFocus() }elseif(evtType=='keydown'){ asKeydown() } $that.keyup(function(){ vartxt=$that.val() if(txt==''){ $placeholder.show() }else{ $placeholder.hide() } }) //窗口缩放时处理 $(window).resize(function(){ move() }) //cache $that.data('el',$placeholder) $that.data('move',move) } returnthis.each(function(){ var$elem=$(this) bootstrap($elem) if($.isFunction(callback))callback($elem) }) }
方式2对于以下场景不适合
1.input初始隐藏
此时无法取到input的offset,继而无法定位span到input上面。
2.包含input的页面dom结构发生变化
比如页面里删除了一些元素或添加了一些元素,导致input向上或向下偏移,而此时span则没有偏移(span相对body定位)。这比较恶心,可以考虑把span作为input的兄弟元素,即相对内层div定位(而不是body)。但这样必须强制给外层div添加position:relative,添加后可能会对页面布局产生一定影响。