javascript - div 按钮上的 JQuery click() 不会触发

标签 javascript jquery html css simulation

我正在尝试模拟用户对我无法控制的代码的网站的点击。我试图与充当按钮的 div 互动的元素。

<div role="button" class="c-T-S a-b a-b-B a-b-Ma oU v2" aria-disabled="false" style="-webkit-user-select: none;" tabindex="0">
    Generate
</div>

与元素关联的事件监听器(根据 Chrome 的检查器)是:

enter image description here

我只是尝试使用以下方法点击按钮:

var button = $('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2')
button.click()

...但是没有任何反应。选择器有效,经验证:

alert($('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2').length); // alerts "1"

我已经尝试了所有事件处理程序的排列

button.trigger('click');
button.mouseover().mousedown().mouseup()
button.trigger('mouseover', function() { button.trigger('mousedown', function() { button.trigger('mouseup'); });  });

...但仍然没有。我怎样才能模拟点击这个 div?

如果不清楚,我尝试模拟点击这个div并触发原始功能,而不是在元素上定义新的点击功能。

更新

这些答案中的许多确实确实点击了按钮,但不会产生与手动点击按钮相同的结果。所以看起来问题不一定是点击按钮本身,而是模拟真实点击。

最佳答案

我做了一个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 附加的事件,而不会触发 native 附加事件。这意味着:

$(button).trigger('mousedown'); // this doesn't work
button.dispatchEvent(new Event('mousedown')); // this should work

3) 正如 Scimonster 所指出的,没有附加 click-eventListener。这意味着:

$(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 被用来代替它看起来像点击。在 fiddle 中,mouseup 使红色 div 可见。您可以尝试通过将此行添加到代码中来触发 mouseup 事件:

button.dispatchEvent(new Event('mouseup')); // "works", but has no visible result

mouseup-handler 被mouseover“隐藏”了- 和 mouseout -events,第一个附加它,后者删除它。这样 mouseup 只有在鼠标悬停在按钮上时才会产生结果。我假设您的 google-page 做了类似的事情来覆盖点击事件。

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) 按钮本身没有附加 eventListeners。该按钮包裹在 <a> 中-标签。此标记是按钮及其属性 jsaction 的父级的值表明 <a>click 的监听器, focus , 和 mousedown .直接定位它有效:

button.parentElement.dispatchEvent(new Event('click'));

2) 如果您想要单击按钮本身,您必须触发一个事件使 DOM 向上冒泡以到达具有单击处理程序的元素。但是在使用 new Event('name') 创建事件时, 它的 bubbles -属性默认为 false . 我没有想到这一点是我的错。。因此,以下内容直接作用于按钮:

button.dispatchEvent(new Event('click', {bubbles: true}));

EDIT 2 深入挖掘该页面上发生的事情产生了可用的结果:

已经发现页面会处理鼠标指针的位置和事件的正确顺序,可能会区分是人类还是机器人/脚本触发了事件。因此,此解决方案使用 MouseEvent - 包含 clientX 的对象和 clientY属性,保存事件触发时指针的坐标。

元素上的自然“点击”总是按给定顺序触发四个事件:mouseover , mousedown , mouseup , 和 click .模拟自然行为mousedownmouseup被延迟。为了方便起见,所有步骤都包含在一个函数中 模拟 1) 在它的左上角输入元素,2) 稍后在元素中心单击。详情见评论。

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"));

该函数不会模拟给定任务不需要的真实鼠标移动

关于javascript - div 按钮上的 JQuery click() 不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26126663/

相关文章:

javascript - 扩展内置数组,super() 的行为很奇怪

javascript - 使用lodash比较锯齿状数组(项目无序存在)

jquery - 如何使用 jQuery 删除大写单词之间的空格?

html背景图片根本不显示

javascript - "Background"使用 javascript 和 html5 的游戏动画

html - 表 : how to change pictures on mouseover on single rows?

javascript - 无法在 Windows 7 中运行全局安装的 Node 模块

javascript - 如何使用jquery在按钮单击时显示表单?

jquery - 在 Twitter Bootstrap 嵌套选项卡中重置事件子项

javascript - 收集多个输入的更好方法