如何使用纯 JavaScript 在 grunt-run qunit 测试中触发 TouchEvent?

Posted

技术标签:

【中文标题】如何使用纯 JavaScript 在 grunt-run qunit 测试中触发 TouchEvent?【英文标题】:How can I trigger a TouchEvent in a grunt-run qunit test with plain javascript? 【发布时间】:2014-05-11 20:22:53 【问题描述】:

我有想要测试的各种触摸事件的回调。例如,“touchstart”事件使用触摸坐标来设置我的类的成员:

NavigationUI.prototype.touchStart = function(evt) 
    this.interacting = true; 
    this.startPoint = this.getTouchXY(evt);
;
NavigationUI.prototype.getTouchXY = function(evt)  
    var rect = this.element.getBoundingClientRect(); 
    return  
         x: evt.targetTouches[0].clientX - rect.left,
         y: evt.targetTouches[0].clientY - rect.top
    ;
;

我没有使用 jQuery。为了测试这个函数,我需要在一个已知位置创建一个 div,创建一个 Touch 事件来正确设置第一个 targetTouches Touch 的 clientX 和 clientY 变量,然后触发该事件并检查回调是否完成了它应该做的事情。我对鼠标事件有类似的回调。样本测试是:

test('test mouseDownCallback', function()                                    
 var div, evt, navElement;                                                   
 div = document.createElement('div');                                        
 div.setAttribute('style', 'position: fixed; left: 0px; top: 0px;');         
 document.body.appendChild(div);                                             
 navElement = new lasertutor.NavigationUI(div);                              
 evt = document.createEvent("MouseEvent");                                   
 evt.initMouseEvent("mousedown", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
 div.dispatchEvent(evt);                                                     
 ok(navElement.interacting, "mousedown doesn't set interacting");            
 return deepEqual(                                                          
   x: 0,                                                                     
   y: 0                                                                      
 , navElement.startPoint);
);

但是,似乎没有文档可以尝试为触摸事件执行此操作。似乎有 a description of the Touch Event Interface 无法触发一个,an Apple Developer page on the initTouchEvent function 没有参考任何构造所需的 Touch 或 TouchList 参数的方法,以及 2011 年的 another SO question 不包括使用任何位置填充触摸事件数据。

我当前的测试看起来像这样,并使用 Apple Dev 页面中的 initTouchEvent 规范和我模拟 TouchList 和 Touch 对象的简单尝试:

test("test TouchStartCallback", function()                                   
 var div, evt, navElement, touch1;                                           
 div = document.createElement('div');                                        
 div.setAttribute('style', 'position: fixed; left: 0px; top: 0px;');         
 document.body.appendChild(div);                                             
 navElement = new lasertutor.NavigationUI(div);                              
 evt = document.createEvent("TouchEvent");                                   
 touch1 = document.createTouch(                                             
   clientX: 0,                                                               
   clientY: 0,                                                               
   id: 0,                                                                    
   pageX: 0,                                                                 
   pageY: 0,                                                                 
   screenX: 0,                                                               
   screenY: 0,                                                               
   target: div                                                               
 );                                                                         
 evt.initTouchEvent("touchstart", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, [touch1], [touch1], [touch1], 1, 0);
 div.dispatchEvent(evt);                                                     
 ok(navElement.interacting, "touchstart doesn't set interacting");           
 return deepEqual(                                                          
   x: 0,                                                                     
   y: 0                                                                      
 , navElement.startPoint);                                                  
);

我将此测试作为 grunt Qunit 任务的一部分运行。它没有错误地失败,说 ok 和 deepEqual 断言都不是真的。此测试的 mouseEvent 版本通过。

【问题讨论】:

【参考方案1】:

您是否正确使用了 document.createTouch?根据Safari developer,您需要传递事件发生的视图(窗口)。

createTouch(DOMWindow view, EventTarget target, long identifier, long pageX, long pageY, long screenX, long screenY)

touch1 = document.createTouch(window, div, 1, 0, 0, 0, 0);

【讨论】:

这绝对有帮助——我没有找到构造函数描述,它还显示了如何初始化 TouchList。不幸的是,测试仍然失败,所以肯定还有其他问题。 我将把它标记为已接受。在进行了这些更改并添加了一些日志记录之后,以下情况是正确的: 1) 在 touchstart 上添加事件侦听器的语句正在执行并且没有引发错误。 2) 定义了所有的 TouchEvent、Touch 和 TouchList 对象。 3) dispatchEvent 调用返回 true 4) 回调没有被执行。如果一个事件被调度但它的处理程序没有被调用,是否可以说它已经发生的问题可能是谷歌哲学博士的一个问题。

以上是关于如何使用纯 JavaScript 在 grunt-run qunit 测试中触发 TouchEvent?的主要内容,如果未能解决你的问题,请参考以下文章

Grunt:查看多个文件,仅编译更改 - livereload 中断?

在 Grunt 任务中运行命令

为啥通过 Grunt 运行 Google JavaScript Linter 会失败?

如何使用动态添加的按钮打开模态窗口 - 纯 JavaScript

如何使用纯 JavaScript 连接到 MSSQL

如何使用纯 Javascript Autodesk 在查看器中离线显示 2d (.dwg) 文件