(移动端项目中)长按聊天消息,出现一个弹出层,进行消息撤回操作,点击弹出层之外的其他地方需要隐藏该弹出层。记录下这里遇到的坑。
项目需求:
(移动端项目中)长按聊天消息,出现一个弹出层,进行消息撤回操作,点击弹出层之外的其他地方需要隐藏该弹出层。
基础html代码:
1 2 3 4 5 6 7 8 9 10
| <div> <ul class="press-operation"> <li>复制</li> <li>撤回</li> </ul> <div @touchstart="keepPress($event)" @touchmove="" @touchend="keepPressEnd($event)" @touchcancel=""> <img class="img" src="" /> </div> </div>
|
需求实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
keepPress(event){ let nodeEl = event.currentTarget.parentElement.firstElementChild this.pressTimer = setInterval(() => { nodeEl.style.display = 'block' },500) }
keepPressEnd(event){ clearInterval(this.pressTimer) },
document.addEventListener('click',function () { $('.press-operation').hide() })
|
问题一:
在安卓中,上面的代码能实现我们的需求,但是,在IOS中,长按松开后,弹出层就立马关闭了!!!****
了解了下touch和click事件:
touchstart:
click:
- 1.手指触碰
- 2.手指未在屏幕上移动
- 3.在这个dom上手指离开屏幕
- 4.触摸和离开屏幕之间的时间间隔较短
上网一顿搜索发现touch和click的执行顺序:
touchstart –> touchmove –> touchend –> touchcancel –> click
所以,执行完touch事件后会执行click事件,在ios中就会出现长按松开后就会关闭弹出层。这里我们需要阻止touch事件的默认行为使用event.preventDefault()
修改下keepPress中的代码
1 2 3 4 5 6 7 8
| keepPress(event){ event.preventDefault() let nodeEl = event.currentTarget.parentElement.firstElementChild this.pressTimer = setInterval(() => { nodeEl.style.display = 'block' },500) }
|
这样代码就能满足我们的需求了。
问题二:
当我们发送的消息是图片消息时,我们需要点击图片放大,长按图片也出现撤销的弹出层。通过前面的分析,当click和touch事件同时存在时会先触发touch,再触发click**** 。因为我们阻止了touch事件的默认行为,所以,我们点击图片的时候并不会触发click事件,图片也就不会放大。
这里我们需要在touchend中做处理,如果长按时间短,就用代码触发图片的点击事件,长按时间长,就不触发图片的点击事件。
修改前面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| keepPress(event){ event.preventDefault() this.pressTime = 0 $('.press-operation').hide() let nodeEl = event.currentTarget.parentElement.firstElementChild this.pressTimer = setInterval(() => { this.pressTime = this.pressTime + 1 nodeEl.style.display = 'block' },500) }, keepPressEnd(event){ let el = event.currentTarget.getElementsByClassName('img')[0] clearInterval(this.pressTimer) if(this.pressTime < 1){ if(el){ el.click() }
} },
|
到此为止,应该是满足了我的需求了
感谢您的阅读
如有不对,欢迎指正。如有其他实现方法,欢迎留言讨论~