由于我不清楚发生了什么,我制作了一段视频:
正如您所看到的那样,该工具在结束时崩溃,之前它只是滚动并显示每个touchevent的接触点(动画圆圈)。我只想清除堆栈,这样就不会发生了。
我正在为触摸屏电脑构建一个非常慢的JavaScript工具。这么慢,当你用手在短时间内触发100多次触摸事件(比如1秒钟)时,计算机开始逐个执行每个触摸事件。
由于执行一个touchevent已经需要几百毫秒,因此工具大约一分钟不可用。
我已经编写了这个脚本以阻止更多的触摸事件
'use strict';
var MultiTouch = Backbone.NativeView.extend({
el: document,
initialize: function () {
console.log('Init MultiTouch');
this.el.addEventListener('touchstart', function(e) {
this.touchstartHandler(e);
}.bind(this));
},
touchstartHandler: function (e) {
if (this.block) {
console.log("block");
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return;
}
console.log("no block");
this.startTimer();
},
startTimer: function () {
this.block = true;
setTimeout(function () {
this.block = false;
}.bind(this), 300);
}
});
module.exports = MultiTouch;
这仍然无法阻止足够的事件,因为我的工具仍然很容易过载。
有没有办法清空整个callstack,这样我的机器就不会连续执行100多个功能?
感谢。
修改
我稍微更新了我的脚本并添加了两个控制台日志。这是我将手放在触摸屏上的原因:
no block MultiTouch.js:31
17 block MultiTouch.js:23
no block MultiTouch.js:31
19 block MultiTouch.js:23
no block MultiTouch.js:31
12 block MultiTouch.js:23
no block MultiTouch.js:31
20 block MultiTouch.js:23
no block MultiTouch.js:31
7 block MultiTouch.js:23
no block MultiTouch.js:31
8 block MultiTouch.js:23
no block MultiTouch.js:31
6 block MultiTouch.js:23
no block MultiTouch.js:31
9 block MultiTouch.js:23
2 no block MultiTouch.js:31
9 block MultiTouch.js:23
no block MultiTouch.js:31
7 block MultiTouch.js:23
no block MultiTouch.js:31
5 block MultiTouch.js:23
no block MultiTouch.js:31
7 block MultiTouch.js:23
no block MultiTouch.js:31
6 block MultiTouch.js:23
no block MultiTouch.js:31
11 block MultiTouch.js:23
no block MultiTouch.js:31
3 block MultiTouch.js:23
因此,将一只手放在屏幕上会触发170多次触摸。移动您的手将触发数千次触摸事件,这将完全导致我的计算机崩溃。我怎样才能防止这种情况发生?
编辑2
其中一位说话者说'你可以忽略大部分事件。'事实并非如此。当数以千计的事件被调用时,我的计算机崩溃了,所以我不能“忽略”它们。
这个问题的重点是让我的电脑不会崩溃。每个touchstart都有多个功能可以监听它,因此每个touchstart事件都会执行多个功能。
由于这些函数需要几百毫秒才能执行,因此工具会持续执行几分钟的功能,使其无法使用。
问题在于,这台计算机速度很慢,以至于他只是“记住”所有已经输入的触摸事件,即使你在一分钟之前做过这件事,而且还在忙于其他事情。所以你只看到工具滚动,而没有人触摸屏幕。
如果仍然不清楚发生了什么,我会记录下来并将其上线。
答案 0 :(得分:1)
您可以忽略大多数事件。
聚合数组中的所有相关触摸事件,然后调用startHandler()
。例如,您可能只需要第一个事件和最后一个事件:
touchstartHandler: function (e) {
this.events.push(e)
this.startTimer();
},
由于您使用的是Backbone,您可以尝试_.debounce
或_.throttle to limit calling
startHandler()`太多次。
startTimer: _.debounce(function () {
//do sth with this.events
console.log(this.events[0])
}, 50);
答案 1 :(得分:0)
尝试使用debounce,它每X ms只调用一次函数。 immediate在X ms之前执行函数的第一次调用,在X ms过去之后立即调用它。
这是它的实现:
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
var touchEvent = function() {
console.log('touched');
};
var debouncedTouchEvent = debounce(touchEvent, 500, true);
for (var i = 0; i < 100000; i++) {
debouncedTouchEvent();
//will only be called once every 500ms.
}
// element.addEventListener('touch', debouncedTouchEvent);
&#13;