分享一个Vue输入框获取焦点自动选中指令

需求背景:最近项目中遇到很多输入类控件,且有频繁改动需求,如果数值过长,则需要一直按着删除键,于是想能不能获取焦点的时候,就直接选中,这样就可以直接删除了

1、思路分析

记得很早的时候做小程序,输入组件可以直接设置要选中的位数,于是想看看目前使用饿了么组件有无该功能,发现并没有提供,那就只有自己写了;接着之前的思路,想着是不是input聚焦后也需要选择选中的长度,于是查看了文档,刚好发现了这个api ,HTMLInputElement.select(),并且兼容性良好,那简单了直接开干

2、开干

有了上面这个api,那么只需要写一个指令,找到当前input节点,当其聚焦时,调用一下select方法即可,vue的自定义指令,也完美符合需求

Vue.directive('input-select', {
		inserted: function (el) {
			el._select_ = function (e) {
				e.target.select()
			}
			el.addEventListener('focus',el._select_)
		},
		unbind: function (el) {
			if (el._select_) {
				input.removeEventListener('focus',el._select_,false)
			}
		}
	})

经过简单测试,完美,没有任何问题,正当高兴时,准备给所有输入框都加上,突然发现,怎么饿了么输入框添加了之后无效呢(黑人问号脸???),于是看了下
在这里插入图片描述
原来,一般复杂的业务组件,输入框也会被嵌套几成的,而不是直接input标签裸奔,所有开始事件绑定就绑错了

3、优化

有了上面的问题,笔者想了一个办法,既然初始绑定不一定会帮到Input上,那么我直接找出当前节点所有input控件,挨个给他绑上,再挨个卸载,要注意一个小细节,通常开源的组件库,人家也是用原生的组件封装的,也就是说,有可能 switch 啥的也是input写的,所有我们在绑定的时候也可以按需过滤下,比如笔者这里,就指定text、number、tel、password、url、search这几种类型的输入框才绑定事件
完整如下:

Vue.directive('input-select', {
		inserted: function (el) {
			function addSelect(vnodes = []) {
				// 指定几种类型
				const types = ['text','number','tel','password','url','search']
				vnodes.forEach((input) => {
					if(types.includes(input.type) && !input.readOnly) {

						input._select_ = function (e) {
							//修复一个bug 当聚焦瞬间又失焦时,可能会造成事件多次调用
							// 故,选中前判断当前元素是否聚焦
							document.activeElement == e.target && e.target.select()
						}

						input.addEventListener('focus', input._select_, false)
						el._hasInputSelect = true
					}
				})
			}
			addSelect(el.tagName == 'INPUT' ? [el] : [...el.querySelectorAll('input')])
		},
		unbind: function (el) {
			if (el._hasInputSelect) {
				(el.tagName == 'INPUT' ? [el] : [...el.querySelectorAll('input')]).forEach((input) => {
					input._select_ && input.removeEventListener('focus',input._select_,false)
					input._select_ = null
					delete input._select_
				})
				delete el._hasInputSelect
			}
		}
	})

4、总结

看似一个小功能,其实也些许问题,其实还有可以扩展,比如:部分组件如果输入控件比较多,为了节约性能,有可能输入框是动态的,即,没有点击的时候是文本,当用户点了才切换成输入框,对于这种情况,目前笔者未进行探索,只是感觉可能需要围绕vue指令的生命周期进行操作,感兴趣的朋友可自行探索

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值