在现有的网页上,通过TamperMonkey脚本,我想自动将鼠标悬停在图像上,等待“弹出”(实际上是< DIV>)出现,然后单击该弹出窗口上的按钮
现在,从控制台开始,此代码会触发鼠标悬停事件,并且会出现“弹出窗口”。
$('div.photo.mpHover img').eq(0).mouseover()
在我的TM脚本中,除非我引用unsafeWindow ..
,否则此代码不会触发事件unsafeWindow.$('div.photo.mpHover img').eq(0).mouseover()
为什么会这样?我很困惑,因为例如从TM脚本模拟'click'事件按预期工作而不访问unsafeWindow ..
$('div.photo.mpHover img').eq(0).click()
答案 0 :(得分:1)
jQuery的.click()
和.mouseover()
只是.trigger()
的快捷方式。
来自the docs:
当相应的事件发生时,会触发任何事件处理程序附加
.on()
或其中一种快捷方法。但是,可以使用.trigger()
方法手动触发它们。
和
注意:对于普通对象和窗口以外的DOM对象,如果触发的事件名称与对象上的属性名称匹配,则jQuery将尝试调用属性作为方法,如果不是事件处理程序调用event.preventDefault()。
这在实践中意味着:
.trigger()
或其快捷方法之一,只能可靠地处理由jQuery设置的事件处理程序,而不是其他javascript。
.trigger()
通常仅在相同范围的相同范围中调用时才有效。
除非您注入代码或使用unsafeWindow
跳转范围,否则用户脚本在不同的范围内运行。
但是,如果目标元素具有匹配的本机方法,例如click
,则jQuery将默认尝试调用此方法。
许多元素都使用原生click
方法,但很少(¿none?)具有原生mouseover
方法。
这就是为什么即使没有使用注入,jQuery .click()
有时会从用户脚本工作的原因。但是,这是不可靠的,并且由于尝试访问JS代码跨沙箱的安全限制而经常会失败。
最强大的解决方案是发送实际鼠标事件(更新代码):
triggerMouseEvent ( $('div.photo.mpHover img').eq(0), "mouseover");
function triggerMouseEvent (jNode, eventType) {
if (jNode && jNode.length) {
var clickEvent = new MouseEvent (
eventType, {canBubble: true, cancelable: true}
);
jNode[0].dispatchEvent (clickEvent);
}
}
旧方法:仍有效,但has been deprecated。
triggerMouseEvent ( $('div.photo.mpHover img').eq(0), "mouseover");
function triggerMouseEvent (jNode, eventType) {
if (jNode && jNode.length) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent (eventType, true, true);
jNode[0].dispatchEvent (clickEvent);
}
}
这几乎适用于所有情况,通常无需注射或unsafeWindow
。
有关更复杂的方案,请参阅"Choosing and activating the right controls on an AJAX-driven site"。