从 addEventListener 中提取带有此关键字的绑定函数
extracting bound function with this keyword out of addEventListener
我想修改一个 library function 如下所示:
this.map.getContainer().addEventListener('touchstart', this.fire.bind(map, 'mousedown'));
现在(如果我做对了),该函数侦听触摸事件,如果发生触摸事件,则调度相应的鼠标事件。所以它告诉地图对象像处理鼠标事件一样处理触摸事件。
this.map.on('mousedown', this.eventHandlers.mouseDown);
this.eventHandlers = {
mouseDown: this.events.mouseDown.bind(this),
};
我想修改上面的函数,让它区分单指触摸事件和多点触摸事件,像这样:
element.addEventListener('touchstart', onTouchStart);
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
但是,仅仅将上面的侦听器函数放在那里是行不通的。我尝试使用 e.currentTarget 并创建一个 var otherThis = this 然后用 otherThis 替换它,但它没有用。
我收到以下错误:
Uncaught TypeError: Cannot read property 'bind' of undefined
at HTMLDivElement.onTouchStart
非常感谢帮助!
这里:
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
问题是 this.fire.bind(map, 'mousedown')
。这段代码没有副作用,它只是定义了一个函数。参见 bind。但实际上并没有调用它。
要调用它,您可以使用:
this.fire('mousedown');
这是 XY problem 的实例。
不需要将触摸事件转化为鼠标事件(touchstart
→mousedown
,touchmove
→mousemove
,touchend
→mouseup
) 或者反之亦然:浏览器已经为您完成了。
我强烈建议您观看 "Getting Touchy" presentation from 2015 as well as reading the corresponding slide deck。它深入解释了不同的浏览器如何在触摸事件的同时发送鼠标(和指针)事件。
即使您仅在触摸事件的某些条件下发送 mousedown
/up
/move
,您也会收到 重复 mousedown
/up
/move
单次触摸事件。
另一方面:此处绑定事件处理程序的简洁方法...
element.addEventListener('touchstart', onTouchStart);
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
...会...
element.addEventListener('touchstart', onTouchStart.bind(this));
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire('mousedown') }
};
请注意如何将 bind()
调用应用于事件处理程序函数,而 不会 应用于事件处理程序内部的函数调用。这使得事件处理程序内部的 this
的值成为 bind()
.
的参数
"The Leaflet way" 会是...
L.DomEvent.on(element, 'touchstart', onTouchStart, this)
...这是 bind
和 addEventListener
的两个包装器。 L.DomEvent
还处理浏览器怪癖(dblclick
在某些情况下在触摸屏上),并翻译非标准 IE10 的 MSPointerDown
(等),以便 touch*
在 Win7 机器上的事件使用 IE10 和触摸屏即可。
我想修改一个 library function 如下所示:
this.map.getContainer().addEventListener('touchstart', this.fire.bind(map, 'mousedown'));
现在(如果我做对了),该函数侦听触摸事件,如果发生触摸事件,则调度相应的鼠标事件。所以它告诉地图对象像处理鼠标事件一样处理触摸事件。
this.map.on('mousedown', this.eventHandlers.mouseDown);
this.eventHandlers = {
mouseDown: this.events.mouseDown.bind(this),
};
我想修改上面的函数,让它区分单指触摸事件和多点触摸事件,像这样:
element.addEventListener('touchstart', onTouchStart);
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
但是,仅仅将上面的侦听器函数放在那里是行不通的。我尝试使用 e.currentTarget 并创建一个 var otherThis = this 然后用 otherThis 替换它,但它没有用。
我收到以下错误:
Uncaught TypeError: Cannot read property 'bind' of undefined at HTMLDivElement.onTouchStart
非常感谢帮助!
这里:
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
问题是 this.fire.bind(map, 'mousedown')
。这段代码没有副作用,它只是定义了一个函数。参见 bind。但实际上并没有调用它。
要调用它,您可以使用:
this.fire('mousedown');
这是 XY problem 的实例。
不需要将触摸事件转化为鼠标事件(touchstart
→mousedown
,touchmove
→mousemove
,touchend
→mouseup
) 或者反之亦然:浏览器已经为您完成了。
我强烈建议您观看 "Getting Touchy" presentation from 2015 as well as reading the corresponding slide deck。它深入解释了不同的浏览器如何在触摸事件的同时发送鼠标(和指针)事件。
即使您仅在触摸事件的某些条件下发送 mousedown
/up
/move
,您也会收到 重复 mousedown
/up
/move
单次触摸事件。
另一方面:此处绑定事件处理程序的简洁方法...
element.addEventListener('touchstart', onTouchStart);
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
...会...
element.addEventListener('touchstart', onTouchStart.bind(this));
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire('mousedown') }
};
请注意如何将 bind()
调用应用于事件处理程序函数,而 不会 应用于事件处理程序内部的函数调用。这使得事件处理程序内部的 this
的值成为 bind()
.
"The Leaflet way" 会是...
L.DomEvent.on(element, 'touchstart', onTouchStart, this)
...这是 bind
和 addEventListener
的两个包装器。 L.DomEvent
还处理浏览器怪癖(dblclick
在某些情况下在触摸屏上),并翻译非标准 IE10 的 MSPointerDown
(等),以便 touch*
在 Win7 机器上的事件使用 IE10 和触摸屏即可。