onclick是web开发中最常用的事件,会在对象被点击时触发,可以使用于绝大多数的HTML元素。对一个普通的web系统,从登录到系统内各种操作如列表查询、表单提交,直到使用完退出,都要用到。就这个用得最多最熟悉的事件,可让我栽了个跟头。
最近做了个任务管理的应用,产品给了一个需求。焦点在输入框时,在下方显示保存按钮,焦点移开则隐藏。下图是输入时的效果。
这还不简单吗?输入框加个focus事件,有焦点时显示按钮,再加个blur事件,焦点移开隐藏不就完了吗。至于保存事件,在按钮上正常处理。三五分钟代码写完了,如下:
<el-input v-model="taskName" type="textarea"
autosize
@focus="showNameButton = true"
@blur="showNameButton = false"
placeholder="添加任务名称"/>
浏览器打开,点击输入框,按钮显示,失去焦点,按钮隐藏,ok,通知测试。
半小时后,“没效果啊,保存不了”,测试反馈。什么情况,我自己试试。这一试,尴尬了,按钮根本不能点击,点击之前先触发blur,按钮隐藏了。知道问题了,好办,给blur加个延时不就行了。
taskNameBlur() {
setTimeout(() => {
this.showNameButton = false;
}, 180)
},
“时好时坏啊,这还是不行”,测试又来了。其实我改完发布的时候就想到了,这个延时不好判断,延时太短可能没点保存就隐藏了,延时太长如果是点其他地方又会隐藏的太慢,体验不好,那怎么办呢?烦人的blur,click只能在blur之后执行啊,加延迟影响用户体验,去掉blur呢,倒是不影响,但显示两个按钮看着怪怪的,产品应该不同意。请教一下前端同学吧。
前端开发居然没处理过这种问题,不过她提了个思路,在组件上加监听。听起来靠谱,试试吧。写到一半突然反应过来了,这有啥用啊,我要是能监听到click,那也可以直接处理click了,现在的问题就是blur先于click执行,我根本拿不到click事件嘛,这方案还是不行啊。难道真的没办法吗?
继续在blur上纠结是没啥结果了,得想想别的办法。既然输入框上没办法,按钮上呢?如果不用click触发,可以吗?对,你是不是也想到了,mousedown不就行了吗?
<span v-if="showNameButton" class="task-name-button"
@mousedown="saveTaskName">
<li class="el-icon-check" style="font-weight: 700"></li>
</span>
页面测试,没问题,肯定生效。“可以了,就这个效果”,产品和测试也通过了。
但是,这其实并不是最好的方案,mousedown这个事件是有风险的,肯定有人尤其是犹犹豫豫的人,点击鼠标但是瞬间后悔,如果是click是可以滑动取消的,但是mousedown不行,太绝对了。因为我的项目对准确度没有特别高的要求,允许这样的操作,所以保留这种处理,但从技术本身来说是不推荐的。
所以各位看官有啥好的方案吗?我的效果,可以移步 狐小E 任务管理 体验。