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 相关文章推荐
深入理解JavaScript系列(26):设计模式之构造函数模式详解
Mar 03 Javascript
js简单实现竖向tab选项卡的方法
May 04 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)
Dec 10 Javascript
基于JS实现的笛卡尔乘积之商品发布
May 13 Javascript
require.js配合插件text.js实现最简单的单页应用程序
Jul 12 Javascript
Javascript中call,apply,bind方法的详解与总结
Dec 12 Javascript
基于javascript实现最简单选项卡切换
Feb 01 Javascript
Bootstrap笔记之缩略图、警告框实例详解
Mar 09 Javascript
前端构建工具之gulp的配置与搭建详解
Jun 12 Javascript
利用yarn代替npm管理前端项目模块依赖的方法详解
Sep 04 Javascript
Vue中实现权限控制的方法示例
Jun 07 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
Sep 16 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
Thinkphp和onethink实现微信支付插件
2016/04/13 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
2016/04/30 PHP
使用SMB共享来绕过php远程文件包含的限制执行RFI的利用
2019/05/31 PHP
js 可拖动列表实现代码
2011/12/13 Javascript
JavaScript之自定义类型
2012/05/04 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
2013/02/18 Javascript
JS随机生成不重复数据的实例方法
2013/07/17 Javascript
jquery获取div距离窗口和父级dv的距离示例
2013/10/10 Javascript
NodeJS的Promise的用法解析
2016/05/05 NodeJs
JavaScript的React Web库的理念剖析及基础上手指南
2016/05/10 Javascript
用原生js统计文本行数的简单示例
2016/08/19 Javascript
vue.js 获取当前自定义属性值
2017/06/01 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
2017/08/17 Javascript
jQuery实现的电子时钟效果完整示例
2018/04/28 jQuery
微信小程序 组件的外部样式externalClasses使用详解
2019/09/06 Javascript
jquery自定义组件实例详解
2020/12/31 jQuery
python使用Berkeley DB数据库实例
2014/09/26 Python
python将MongoDB里的ObjectId转换为时间戳的方法
2015/03/13 Python
python 与GO中操作slice,list的方式实例代码
2017/03/20 Python
Python 使用with上下文实现计时功能
2018/03/09 Python
特征脸(Eigenface)理论基础之PCA主成分分析法
2018/03/13 Python
python读取图片并修改格式与大小的方法
2018/07/24 Python
python实现祝福弹窗效果
2019/04/07 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
2021/03/03 Python
潘多拉珠宝英国官方网上商店:PANDORA英国
2018/06/12 全球购物
俄罗斯最大的在线珠宝大卖场:Nebo
2019/12/08 全球购物
Scotch Porter官方网站:男士美容产品
2020/08/31 全球购物
综合实践活动方案
2014/02/14 职场文书
机械工程师岗位职责
2014/06/16 职场文书
出资证明书范本(标准版)
2014/09/24 职场文书
个人事迹材料范文
2014/12/29 职场文书
营运督导岗位职责
2015/04/10 职场文书
2015小学教师德育工作总结
2015/05/12 职场文书
分享一些Java的常用工具
2021/06/11 Java/Android
VS2019连接MySQL数据库的过程及常见问题总结
2021/11/27 MySQL
Linux下搭建SFTP服务器的命令详解
2022/06/25 Servers