我正在为AngularJS指令编写测试,该指令会<textarea>在按下某些键时触发a事件。按照我的手动测试,一切正常。我想成为一个好人,也有完整的单元测试套件,但是遇到了一个我自己无法解决的问题:
<textarea>
我想送一个特定的keyCode在我的triggerHandler()电话在我的测试,但我不能找到一种方法来指定键 ,实际工作 。我知道关于使用特定数据构建和发送事件的 许多 问题和解答,但是在我的设置中没有一个起作用:
keyCode
triggerHandler()
var event = document.createEvent("Events"); event.initEvent("keydown", true, true); event.keyCode = 40; // in debugging the test in Firefox, the event object can be seen to have no "keyCode" property even after this step textarea.triggerHandler(event); // my keydown handler does not fire
奇怪的是,我可以在Chrome的控制台中输入前三行,然后看到该事件是在属性设置为40的情况下创建的 。keyCode因此,似乎应该可以使用。
另外,当我像这样调用最后一行时,textarea.triggerHandler("keydown");它会起作用,并且会触发事件处理程序。但是,由于无法keyCode使用,因此毫无意义。
textarea.triggerHandler("keydown");
我怀疑这可能与针对与浏览器中运行的常规页面不同的DOM运行的测试的性质有关。但是我无法弄清楚!
我已经使用以下解决方案对其进行了测试,并根据此答案在Chrome,FF,PhantomJS和IE9 +中运行了该解决方案。它在Safari中不起作用-尝试了数百万种其他解决方案,但均未成功…
function jsKeydown(code){ var oEvent = document.createEvent('KeyboardEvent'); // Chromium Hack: filter this otherwise Safari will complain if( navigator.userAgent.toLowerCase().indexOf('chrome') > -1 ){ Object.defineProperty(oEvent, 'keyCode', { get : function() { return this.keyCodeVal; } }); Object.defineProperty(oEvent, 'which', { get : function() { return this.keyCodeVal; } }); } if (oEvent.initKeyboardEvent) { oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, false, false, false, false, code, code); } else { oEvent.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, code, 0); } oEvent.keyCodeVal = code; if (oEvent.keyCode !== code) { console.log("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ") -> "+ code); } document.getElementById("idToUseHere").dispatchEvent(oEvent); } // press DEL key jsKeydown(46);
希望能帮助到你
今天,我已经找到并测试了此解决方案,该解决方案提供了更广泛的浏览器覆盖范围(启用了传统支持):
https://gist.github.com/termi/4654819
所有的功劳归功于该GIST的作者。该代码确实支持Safari,PhantomJS和IE9-已针对前2个进行了测试。