在div按钮上的JQuery click()不会被激活

时间:2014-09-30 17:27:36

标签: 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的点击并触发原始函数,而不是在元素上定义新的单击函数。

更新

其中许多答案确实单击了按钮,但不会产生与手动单击按钮相同的结果。所以问题似乎不一定是点击按钮本身,而是模仿真正的点击。

5 个答案:

答案 0 :(得分:9)

我已经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。因此native .addEventListener()附加了所有eventListener。如果使用jQuery触发事件,它只触发jQuery附加的事件,而不触发本机附加事件。这意味着:

$(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 - 事件时,它看起来像是一次点击。在小提琴中,mouseup使红色div可见。您可以尝试通过在代码中添加以下行来触发mouseup-event:

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

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

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>具有clickfocusmousedown的侦听器。直接针对它起作用:

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

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

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

编辑2 深入挖掘该页面上的最新动态,产生了可用的结果:

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

元素的自然“点击”始终按给定顺序触发四个事件:mouseovermousedownmouseupclick。模拟自然行为mousedownmouseup会延迟。为方便起见,所有步骤都包含在一个函数中 模拟1)在它的topLeft角落输入元素,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"));

该功能不会模拟给定任务不必要的真实鼠标移动

答案 1 :(得分:0)

$('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2').trigger('click');完成工作 - 点击事件被触发。

  

.trigger():执行附加到匹配元素的所有处理程序和行为   对于给定的事件类型。

http://api.jquery.com/trigger/

&#13;
&#13;
$('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2').on('click', function() {
   alert( $( this ).text() );
});

$('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2').trigger('click');
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:-1)

根据您发布的事件处理程序的图像,点击不是其中之一。以编程方式触发点击与自然地这样做是不一样的。此处不会触发鼠标进入/离开/按下事件。

答案 3 :(得分:-1)

我实际上试过了你给的链接并且它有效。页面上没有jquery,因此必须使用本机方法。

var click= document.createEvent("MouseEvents");
click.initMouseEvent("click", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);

document.getElementsByClassName('c-T-S a-b a-b-B')[0].dispatchEvent(click)

答案 4 :(得分:-1)

我为此创建了一个JS Fiddle,它运行正常。我使用了以下

$('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2').click(function(){
    alert("clicked");
});
$('.c-T-S.a-b.a-b-B.a-b-Ma.oU.v2').click();// This will trigger click event programatically