JavaScript类仅移动端报错:this.getDragPointer is not a function
问题原因及解决方案
错误this.getDragPointer is not a function的核心原因是事件回调中的this指向错误:
当onTouchStart作为touchstart事件的回调触发时,this指向的是触发事件的DOM元素,而非Draggable类的实例。DOM元素上不存在getDragPointer方法,因此抛出错误。你提到onMouseDown正常工作,大概率是该事件的回调已经做了this绑定处理,但onTouchStart没同步处理。
下面是几种可靠的解决方式:
方式1:构造函数中绑定this
在类的构造函数里,将所有事件回调的this绑定到实例,确保回调执行时this指向当前Draggable对象:
export class Draggable { constructor(el) { this.el = el; // 绑定回调的this到实例 this.onMouseDown = this.onMouseDown.bind(this); this.onTouchStart = this.onTouchStart.bind(this); this.onMouseMove = this.onMouseMove.bind(this); // 同步处理mousemove的this // 绑定事件到元素 this.el.addEventListener('mousedown', this.onMouseDown); this.el.addEventListener('touchstart', this.onTouchStart); } onMouseDown(e) { this.getDragPointer(e.clientX, e.clientY) this.prepareElement() this.moveElementTo(e.pageX, e.pageY) document.addEventListener('mousemove', this.onMouseMove); } onTouchStart(e) { this.isTouch = true; this.getDragPointer(e.touches[0].clientX, e.touches[0].clientY) this.prepareElement() this.moveElementTo(e.touches[0].pageX, e.touches[0].pageY) document.addEventListener('touchmove', this.onMouseMove); } // 改为标准类方法,更简洁 getDragPointer(x, y) { const elRect = this.el.getBoundingClientRect() this.shiftX = x - elRect.left this.shiftY = y - elRect.top } }
方式2:使用箭头函数作为类字段
箭头函数会自动捕获当前上下文的this,直接将事件回调和getDragPointer定义为箭头函数类字段,无需手动绑定:
export class Draggable { // other vars and functions.... onMouseDown = (e) => { this.getDragPointer(e.clientX, e.clientY) this.prepareElement() this.moveElementTo(e.pageX, e.pageY) document.addEventListener('mousemove', this.onMouseMove); } onTouchStart = (e) => { this.isTouch = true; this.getDragPointer(e.touches[0].clientX, e.touches[0].clientY) this.prepareElement() this.moveElementTo(e.touches[0].pageX, e.touches[0].pageY) document.addEventListener('touchmove', this.onMouseMove); } getDragPointer = (x, y) => { const elRect = this.el.getBoundingClientRect() this.shiftX = x - elRect.left this.shiftY = y - elRect.top } }
方式3:绑定事件时用箭头函数包裹
如果不想修改类的内部实现,在给DOM元素绑定touchstart事件时,用箭头函数包裹回调:
// 假设你在某个地方绑定事件 const draggable = new Draggable(yourElement); yourElement.addEventListener('touchstart', (e) => draggable.onTouchStart(e));
额外注意
别忘了同步处理onMouseMove的this绑定,因为你在onMouseDown和onTouchStart中给document绑定了这个方法,如果该方法内用到了实例属性或方法,同样会出现this指向错误。
内容的提问来源于stack exchange,提问作者quilkin
相关产品推荐
相关产品推荐

