placeholder 属性是 html5 中为 input 添加的。在 input 上提供一个占位符,文字形式展示输入字段预期值的提示信息(hint),该字段会在输入为空时显示
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
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 作为显示文本
方式一
- /**
- * 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,添加后可能会对页面布局产生一定影响。
来源: