我正在为某些功能编写测试,该功能涉及用户按住Shift键并单击复选框。我正在使用$('input').trigger($.Event('click', { shiftKey: true }));
进行模拟。
但是当事件监听器被调用时,源自我的合成事件的event.shiftKey
属性总是被报告为false
,而真正的点击会产生所需的效果。更令人困惑的是,在非input
元素上触发相同事件似乎正常。例如,请参见http://jsfiddle.net/huskssk1/。
我在浏览器(Chrome 39,OS X)和测试堆栈(Poltergeist 1.5.1 + PhantomJS 1.9.8)中都观察到此行为。
是什么原因造成的?有什么办法解决吗?
PS我完整的测试堆栈是Ruby on Rails + RSpec + Capybara + Poltergeist + PhantomJS,如果您知道触发shift-click的更好方法,请告诉我!
body.on('click', function(e) {
//e.stopPropagation();
console.log('body', e.shiftKey);
});
我刚刚更新了您的jsfiddle:http://jsfiddle.net/huskssk1/1/
我所做的唯一更改是将jQuery版本更改为1.8.3,因为它没有触发输入的click事件,所以我在主体click事件处理程序中评论了[[e.stopPropogation。
这清楚地表明,两个版本的jQuery之间有所不同。因此,您可以通过在JavaScript中添加以下代码来对jQuery进行猴子补丁:
delete jQuery.event.special.click.trigger
和复选框单击将按预期方式工作:http://jsfiddle.net/ofbazqvo/(注意,我也在主体上评论了e.stopPropogation()
),但有一个例外:input.checked
值在您的'onclick'回调中将无效,但稍后将更新为正确的值(令人惊讶的是,这就是为什么将这种特殊的复选框处理添加到jquery的原因)。或者,您也可以通过普通的javascript:http://jsfiddle.net/6dutftkt/1/手动调度事件。这在Chrome中没有任何古怪之处。
您只需要按Shift键并单击Result区域,即可单击检测Shift键。
代码如下:
function mouseDown(e) {
var shiftPressed=0;
if (parseInt(navigator.appVersion)>3) {
var evt = e ? e:window.event;
if (document.layers && navigator.appName=="Netscape" && parseInt(navigator.appVersion)==4) {
var mString =(e.modifiers+32).toString(2).substring(3,6);
shiftPressed=(mString.charAt(0)=="1");
self.status="modifiers="+e.modifiers+" ("+mString+")"
} else {
shiftPressed=evt.shiftKey;
self.status=""
+ "shiftKey="+shiftPressed
}
if (shiftPressed)
alert ("Mouse clicked with the following keys:\n"
+ (shiftPressed ? "Shift ":"")
);
}
return true;
}
if (parseInt(navigator.appVersion)>3) {
document.onmousedown = mouseDown;
if (navigator.appName=="Netscape") {
document.captureEvents(Event.MOUSEDOWN);
}
}
希望这会有所帮助
Body
是什么,其中包含一些元素,而不是整个页面(表示空白页面)。因此,如果body在其中没有任何元素,则click事件将不会触发。还要指出一件事,您的复选框单击事件会发生,因为它本身就是一个元素。如果要在单击时触发页面,则必须使用$(document)
代替$(document.body)
$(document).on('click', function(e) {
e.stopPropagation();
console.log('body', e.shiftKey);
});
Working Demo此外,要验证身体部位,您可以添加
CSS进行测试
body{ border:1px solid #F00; }
在Demo中查看您的代码,为什么不起作用(仅在演示的红色边框区域中起作用)