input点击后placeholder中的提示消息消失


Posted in Javascript onJanuary 15, 2016

html中,placeholder作为input的一个属性,起到了在输入框中占位并提示的作用。

但是有一些浏览器,如chrome,当鼠标点击输入框时,placeholder的值不消失,只有输入数据才消失,会使前端用户体验大打折扣。

看了很多大神的方法,写了长长的js,看着有点吃力,就想到了下面这种最傻的方法解决了这个问题。

html代码:

<input type="text" placeholder="多个关键词空格隔开">

鼠标点击input时,placeholder中的提示信息消失:

<input type="text" placeholder="多个关键词空格隔开" onfocus="this.placeholder=‘‘" onblur="this.placeholder=‘多个关键词空格隔开‘">

PlaceHolder的两种实现方式

placeholder属性是HTML5 中为input添加的。在input上提供一个占位符,文字形式展示输入字段预期值的提示信息(hint),该字段会在输入为空时显示。

<input type="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: // @string focus|keydown 触发placeholder的事件类型
* })
*
* NOTE:
* evtType默认是focus,即鼠标点击到输入域时默认文本消失,keydown则模拟HTML5 placeholder属性在Firefox/Chrome里的特征,光标定位到输入域后键盘输入时默认文本才消失。
* 此外,对于HTML5 placeholder属性,IE10+和Firefox/Chrome/Safari的表现形式也不一致,因此内部实现不采用原生placeholder属性
*/
$.fn.placeholder = function(option, callback) {
var settings = $.extend({
word: '',
color: '#ccc',
evtType: 'focus'
}, option)
function bootstrap($that) {
// some alias 
var word = settings.word
var color = settings.color
var evtType = settings.evtType
// default
var defColor = $that.css('color')
var defVal = $that.val()
if (defVal == '' || defVal == word) {
$that.css({color: color}).val(word)
} else {
$that.css({color: defColor})
}
function switchStatus(isDef) {
if (isDef) {
$that.val('').css({color: defColor}) 
} else {
$that.val(word).css({color: color})
}
}
function asFocus() {
$that.bind(evtType, function() {
var txt = $that.val()
if (txt == word) {
switchStatus(true)
}
}).bind('blur', function() {
var txt = $that.val()
if (txt == '') {
switchStatus(false)
}
})
}
function asKeydown() {
$that.bind('focus', function() {
var elem = $that[0]
var val = $that.val()
if (val == word) {
setTimeout(function() {
// 光标定位到首位
$that.setCursorPosition({index: 0})
}, 10) 
}
})
}
if (evtType == 'focus') {
asFocus()
} else if (evtType == 'keydown') {
asKeydown()
}
// keydown事件里处理placeholder
$that.keydown(function() {
var val = $that.val()
if (val == word) {
switchStatus(true)
}
}).keyup(function() {
var val = $that.val()
if (val == '') {
switchStatus(false)
$that.setCursorPosition({index: 0})
}
})
}
return this.each(function() {
var $elem = $(this)
bootstrap($elem)
if ($.isFunction(callback)) callback($elem)
})
}

方式二

$.fn.placeholder = function(option, callback) {
var settings = $.extend({
word: '',
color: '#999',
evtType: 'focus',
zIndex: 20,
diffPaddingLeft: 3
}, option)
function bootstrap($that) {
// some alias 
var word = settings.word
var color = settings.color
var evtType = settings.evtType
var zIndex = settings.zIndex
var diffPaddingLeft = settings.diffPaddingLeft
// default css
var width = $that.outerWidth()
var height = $that.outerHeight()
var fontSize = $that.css('font-size')
var fontFamily = $that.css('font-family')
var paddingLeft = $that.css('padding-left')
// process
paddingLeft = parseInt(paddingLeft, 10) + diffPaddingLeft
// redner 
var $placeholder = $('<span class="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)
// 内容为空时才显示,比如刷新页面输入域已经填入了内容时
var val = $that.val()
if ( val == '' && $that.is(':visible') ) {
$placeholder.show()
}
function hideAndFocus() {
$placeholder.hide()
$that[0].focus()
}
function move() {
var offset = $that.offset()
var top = offset.top
var left = offset.left
$placeholder.css({
top: top,
left: left
})
}
function asFocus() {
$placeholder.click(function() {
hideAndFocus()
// 盖住后无法触发input的click事件,需要模拟点击下
setTimeout(function(){
$that.click()
}, 100)
})
// IE有些bug,原本不用加此句
$that.click(hideAndFocus)
$that.blur(function() {
var txt = $that.val()
if (txt == '') {
$placeholder.show()
}
})
}
function asKeydown() {
$placeholder.click(function() {
$that[0].focus()
})
}
if (evtType == 'focus') {
asFocus()
} else if (evtType == 'keydown') {
asKeydown()
}
$that.keyup(function() {
var txt = $that.val()
if (txt == '') {
$placeholder.show()
} else {
$placeholder.hide()
}
})
// 窗口缩放时处理
$(window).resize(function() {
move()
})
// cache
$that.data('el', $placeholder)
$that.data('move', move)
}
return this.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,添加后可能会对页面布局产生一定影响。

Javascript 相关文章推荐
js中使用DOM复制(克隆)指定节点名数据到新的XML文件中的代码
Jul 27 Javascript
JS 获取select(多选下拉)中所选值的示例代码
Aug 02 Javascript
jQuery scroll事件实现监控滚动条分页示例
Apr 04 Javascript
使用jQuery中的when实现多个AJAX请求对应单个回调的例子分享
Apr 23 Javascript
AngularJS在IE8的不支持的解决方法
May 13 Javascript
JS获取IMG图片高宽的简单实例
May 17 Javascript
js 动态生成html 触发事件传参字符转义的实例
Feb 14 Javascript
原生JS实现隐藏显示图片 JS实现点击切换图片效果
Jan 27 Javascript
详解从Vue.js源码看异步更新DOM策略及nextTick
Oct 11 Javascript
three.js实现圆柱体
Dec 30 Javascript
JS简单判断是否在微信浏览器打开的方法示例
Jan 08 Javascript
微信小程序文章详情页跳转案例详解
Jul 09 Javascript
jQuery插件imgPreviewQs实现上传图片预览
Jan 15 #Javascript
实例详解AngularJS实现无限级联动菜单
Jan 15 #Javascript
利用CSS3在Angular中实现动画
Jan 15 #Javascript
JavaScript程序开发之JS代码放置的位置
Jan 15 #Javascript
探讨JavaScript标签位置的存放与功能有无关系
Jan 15 #Javascript
JavaScript知识点总结之如何提高性能
Jan 15 #Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
Jan 15 #Javascript
You might like
PHP概述.
2006/10/09 PHP
XAMPP安装与使用方法详细解析
2013/11/27 PHP
仿dedecms下拉分页样式修改的thinkphp分页类实例
2014/10/30 PHP
如何在PHP环境中使用ProtoBuf数据格式
2020/06/19 PHP
jQuery中 attr() 方法使用小结
2015/05/03 Javascript
jquery获得当前html页面源码的方法
2015/07/14 Javascript
详细分析Javascript中创建对象的四种方式
2016/08/17 Javascript
详解JavaScript中this的指向问题
2017/01/20 Javascript
详解React开发必不可少的eslint配置
2018/02/05 Javascript
vue.js 实现点击按钮动态添加li的方法
2018/09/07 Javascript
如何将百度地图包装成Vue的组件的方法步骤
2019/02/12 Javascript
微信小程序的注册页面包含倒计时验证码、获取用户信息
2019/05/22 Javascript
配置node服务器并且链接微信公众号接口配置步骤详解
2019/06/21 Javascript
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
详细介绍Python语言中的按位运算符
2013/11/26 Python
初步解析Python下的多进程编程
2015/04/28 Python
python实现合并两个数组的方法
2015/05/16 Python
Django实现组合搜索的方法示例
2018/01/23 Python
TensorFlow 模型载入方法汇总(小结)
2018/06/19 Python
django开发post接口简单案例,获取参数值的方法
2018/12/11 Python
Python遍历字典方式就实例详解
2019/12/28 Python
Python3打包exe代码2种方法实例解析
2020/02/17 Python
python对文件的操作方法汇总
2020/02/28 Python
Python-for循环的内部机制
2020/06/12 Python
python实现excel公式格式化的示例代码
2020/12/23 Python
AmazeUI 手机版页面的顶部导航条Header与侧边导航栏offCanvas的示例代码
2020/08/19 HTML / CSS
学生会主席事迹材料
2014/01/28 职场文书
企业指导教师评语
2014/04/28 职场文书
中华魂演讲稿
2014/05/13 职场文书
银行求职信范文
2014/05/26 职场文书
七夕情人节促销方案
2014/06/07 职场文书
基层党员对照检查材料
2014/08/25 职场文书
党员民主评议自我评价
2014/10/20 职场文书
微观世界观后感
2015/06/10 职场文书
Django项目配置Memcached和Redis, 缓存选择哪个更有优势
2021/04/06 Python
Python django中如何使用restful框架
2021/06/23 Python