公司以前要上线一个移动支付项目,主要页面以下:
问题来了,移动端click事件通常至少有300ms的延迟,若是输入频率不高,彻底能够忽视这个问题;
可是,变态的测试要求跟原生效果同样(当时我内心是懵逼的,由于彻底没搞过啊).
老板逼得紧,强行上呗(公司就我一个前端).
搞完后的状况是:
借用领导一句话,安卓如丝般顺滑,iPhone卡成翔.当时测试那边简直是想要搞事啊,分分钟就要来个自爆.
好吧,想办法解决呗.就找到了fastclick.js.具体使用以下:javascript
function NoClickDelay(el) {
this.element = typeof el == 'object' ? el: document.getElementById(el);
if (window.Touch) this.element.addEventListener('touchstart', this, false);
}
NoClickDelay.prototype = {
handleEvent: function(e) {
switch (e.type) {
case 'touchstart':
this.onTouchStart(e);
break;
case 'touchmove':
this.onTouchMove(e);
break;
case 'touchend':
this.onTouchEnd(e);
break;
}
},
onTouchStart: function(e) {
e.preventDefault(); this.moved = false;
this.theTarget = document.elementFromPoint(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
if (this.theTarget.nodeType == 3) this.theTarget = theTarget.parentNode;
this.theTarget.className += ' pressed';
this.element.addEventListener('touchmove', this, false);
this.element.addEventListener('touchend', this, false);
},
onTouchMove: function(e) {
this.moved = true;
this.theTarget.className = this.theTarget.className.replace(/ ?pressed/gi, '');
},
onTouchEnd: function(e) {
this.element.removeEventListener('touchmove', this, false);
this.element.removeEventListener('touchend', this, false);
if (!this.moved && this.theTarget) {
this.theTarget.className = this.theTarget.className.replace(/ ?pressed/gi, '');
var theEvent = document.createEvent('MouseEvents');
theEvent.initEvent('click', true, true);
this.theTarget.dispatchEvent(theEvent);
}
this.theTarget = undefined;
}
};
再调用NoClickDelay这个方法
window.addEventListener('load', function() {
FastClick.attach(document.body);
});
new NoClickDelay(document.getElementById('el'));
FastClick.attach(document.body); 这里面的document.body是要作无延迟点击的区域 NoClickDelay里面的元素ID就是该区域ID.而后在这个区域内正常写点击事件,以下:
ele.addEventListener('click',handler, true);
看官请注意:金额数字非法或为0确定要有提示是吧,坑就出在这儿了.不知道各位看官对JS自带的alert函数了解多少. 最近书看多了才知道,alert会停止当前JS进程,注意是'停止'而不是'终止'.若是没有其余事件触发, 页面会中止在当前状态,保持不变.而fastclick是要求咱们一套大保健所有走完,才会给出咱们想要的结果 异常停止的后果就是: 在咱们看来,alert就表示当前操做已经完成, 可是fastclick认为你流程没有走完,反馈给咱们的实际结果就是相似于'继承(当前按钮继承上一个被停止按钮)'. 实际上fastclick是认为alert完过后的下一次点击操做用来弥补被停止流程的下半段. 再下一次才是正常点击事件. 至于我为何要用alert,由于简单粗暴,彻底没考虑事后果. 当时不知道为何会出现这个问题,也就没法解决. 最终上线版本,仍是用的触摸事件:touchStart和touchEnd.一样,给出一个区域,在上面绑定touchStart事件,给单个按钮绑定touchEnd.不过仍然存在可容忍范围内的延迟.