iframe中嵌套threejs使用TrackballControls时touch事件报错
作者:咕魂
时间:2021年8月3日
项目背景:在使用threejs引擎进行游戏开发时,使用iframe嵌套解决bgm在不同页面连续播放的问题,但是iframe中的onPointerDown事件会触发两次导致position出现两个元素无法使用
解决办法:修改TrackballControls的源码中的addPointer函数
原始函数:
function addPointer(event) {
_pointers.push(event)
}
修改后:
function addPointer(event) {
if (_pointers.length == 1) {
return
}
_pointers.push(event)
}
作用:拦截掉一次多余的事件
总结:该方法是在TrackballControls的源码中进行修改,不太推荐,如果有其他拦截iframe多次touch事件的方法欢迎指正
时间:2021年8月5日
之前的修改方法只能使模型旋转生效。但是缩放和平移会出现新的问题,这是之后的修改方案。
修改原理:移动端触发pointerdown和pointercancel时会触发两次,输出event对象查看属性,发现一次是mouse触发的,一次是touch触发的,添加一个判定条件,拦截掉移动端的mouse事件。
新增一个设备标记,来判断这是移动端设备还是pc端设备,该行代码需要加在onPointerDown之前,可以放在class代码内部的最前面。
this.mobile = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)
在onPointerDown,onPointerMove和onPointerUp中添加设备判断代码:
//判断设备
if (scope.mobile && event.pointerType === 'mouse') {
return
}
添加后代码如下:
this.mobile = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)
function onPointerDown(event) {
if (scope.enabled === false) return
if (_pointers.length === 0) {
scope.domElement.ownerDocument.addEventListener('pointermove', onPointerMove)
scope.domElement.ownerDocument.addEventListener('pointerup', onPointerUp)
} //
//判断设备
if (scope.mobile && event.pointerType === 'mouse') {
return
}
addPointer(event)
if (event.pointerType === 'touch') {
onTouchStart(event)
} else {
onMouseDown(event)
}
}
function onPointerMove(event) {
if (scope.enabled === false) return
//判断设备
if (scope.mobile && event.pointerType === 'mouse') {
return
}
if (event.pointerType === 'touch') {
onTouchMove(event)
} else {
onMouseMove(event)
}
}
function onPointerUp(event) {
if (scope.enabled === false) return
//判断设备
if (scope.mobile && event.pointerType === 'mouse') {
return
}
if (event.pointerType === 'touch') {
onTouchEnd(event)
} else {
onMouseUp()
} //
removePointer(event)
if (_pointers.length === 0) {
scope.domElement.ownerDocument.removeEventListener('pointermove', onPointerMove)
scope.domElement.ownerDocument.removeEventListener('pointerup', onPointerUp)
}
}