我制作了一个FIDDLE 来模拟您的“不可点击”按钮。那里的蓝色 div 附加了与您在问题中显示的相同的 eventListeners。到处玩,结果如下:
1) 让我们先获取 DOM 元素:
var button = document.getElementsByClassName('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2')[0];
2) 该页面不包含 jQuery。所以那里的所有 eventListeners 都由native .addEventListener() 附加。如果使用 jQuery 触发事件,它只会触发 jQuery 附加的事件,而不触发原生附加的事件。这意味着:
$(button).trigger('mousedown'); // this doesn't work
button.dispatchEvent(new Event('mousedown')); // this should work
3) 正如 Scimonster 所指出的,没有附加点击事件监听器。这意味着:
$(button).trigger('click'); // doesn't work anyway, see 2)
// next works, but has no visible result on the page,
// because there is no click-handler to do anything:
button.dispatchEvent(new Event('click'));
4) 当鼠标按钮上升时触发点击事件。当使用mouseup-event 时,它看起来像点击。在小提琴中,mouseup 使红色 div 可见。您可以尝试通过在代码中添加这一行来触发 mouseup 事件:
button.dispatchEvent(new Event('mouseup')); // "works", but has no visible result
mouseup-handler 被mouseover- 和mouseout-events “隐藏”,第一个附加它,后者删除它。这样,当鼠标悬停在按钮上时,mouseup 只有一个结果。我假设你的谷歌页面做了类似的事情来覆盖点击事件。
5) 你应该尝试什么:
首先以原生方式触发一些单个事件:
button.dispatchEvent(new Event('eventName'));
如果没有给出可用的结果,请使用一些合理的事件组合:
button.dispatchEvent(new Event('mouseover'));
button.dispatchEvent(new Event('mousedown'));
// or:
button.dispatchEvent(new Event('mousedown'));
button.dispatchEvent(new Event('mouseup')); // or: .....
有很多方法可以组合事件,因此单个事件不会做任何事情,但只有正确的组合才有效。
编辑根据您的调查来源的邀请,我发现了两种方法:
1) 按钮本身没有附加事件监听器。该按钮包含在<a>-tag 中。此标记是按钮的父级,其属性jsaction 的值告诉<a> 具有click、focus 和mousedown 的侦听器。直接定位它有效:
button.parentElement.dispatchEvent(new Event('click'));
2) 如果您想单击按钮本身,您必须触发一个事件,该事件使 DOM 冒泡以到达具有单击处理程序的元素。但是当使用new Event('name') 创建事件时,其bubbles-property 默认为false。 没有想到这一点是我的错。。所以以下直接作用于按钮:
button.dispatchEvent(new Event('click', {bubbles: true}));
编辑 2 深入研究该页面上发生的事情产生了一个可用的结果:
已发现该页面负责事件的鼠标指针位置和正确顺序,可以区分是人还是机器人/脚本触发事件。因此,此解决方案使用 MouseEvent - 包含 clientX 和 clientY 属性的对象,该对象保存事件触发时指针的坐标。
对元素的自然“点击”始终按给定顺序触发四个事件:mouseover、mousedown、mouseup 和 click。为了模拟自然行为mousedown 和mouseup 被延迟。为了方便起见,所有步骤都包含在一个函数中
它模拟 1)在其左上角输入元素,2)稍后在元素中心单击。详情见cmets。
function simulateClick(elem) {
var rect = elem.getBoundingClientRect(), // holds all position- and size-properties of element
topEnter = rect.top,
leftEnter = rect.left, // coordinates of elements topLeft corner
topMid = topEnter + rect.height / 2,
leftMid = topEnter + rect.width / 2, // coordinates of elements center
ddelay = (rect.height + rect.width) * 2, // delay depends on elements size
ducInit = {bubbles: true, clientX: leftMid, clientY: topMid}, // create init object
// set up the four events, the first with enter-coordinates,
mover = new MouseEvent('mouseover', {bubbles: true, clientX: leftEnter, clientY: topEnter}),
// the other with center-coordinates
mdown = new MouseEvent('mousedown', ducInit),
mup = new MouseEvent('mouseup', ducInit),
mclick = new MouseEvent('click', ducInit);
// trigger mouseover = enter element at toLeft corner
elem.dispatchEvent(mover);
// trigger mousedown with delay to simulate move-time to center
window.setTimeout(function() {elem.dispatchEvent(mdown)}, ddelay);
// trigger mouseup and click with a bit longer delay
// to simulate time between pressing/releasing the button
window.setTimeout(function() {
elem.dispatchEvent(mup); elem.dispatchEvent(mclick);
}, ddelay * 1.2);
}
// now it does the trick:
simulateClick(document.querySelector(".c-T-S.a-b.a-b-B.a-b-Ma.oU.v2"));
该函数不会模拟给定任务不需要的真实鼠标移动。