【问题标题】:JavaScript - simulate click on contextmenuJavaScript - 模拟点击上下文菜单
【发布时间】:2018-03-29 03:02:57
【问题描述】:

我正在尝试为网站创建网络自动化。我正在模拟点击。通常我会向下面的元素添加一个 ID,然后使用 Chrome 开发者控制台触发一次点击,它总是有效的。

p.s:以下问题已过时。我实际上是在尝试从 web.whatsapp.com 的上下文菜单中单击一个项目

<div id="myapp">button1</div>

<script>
  $("#myapp").click();
</script>

或者,如果这不起作用,我使用下面的纯 JavaScript 使用 mousedown 事件,它会顺利运行。

function triggerMouseEvent(node, eventType) {
  var clickEvent = document.createEvent('MouseEvents');
  clickEvent.initEvent(eventType, true, true);
  node.dispatchEvent(clickEvent);
}

var targetNode = document.querySelector("#myapp");
triggerMouseEvent(targetNode, "mousedown");

现在我的问题是:这不适用于通过 jQuery contextMenu 插件生成的菜单。

您可以看到 contextMenu here 的演示,我正在通过开发者控制台测试上述内容。

因此,当您右键单击上下文菜单时,会列出带有 ulli 标记的菜单项列表。我手动将 ID #myapp 添加到菜单之一,并且使用以下代码它也选择正确元素通过开发者控制台。

var targetNode = document.querySelector("#myapp");
targetNode;

但我无法触发对通过上下文菜单生成的菜单项的点击。我为此挣扎了超过 24 小时。我尝试了所有我能想到的 JavaScript 事件,例如 mouseupmousedownmouseenter

【问题讨论】:

    标签: javascript jquery dom contextmenu


    【解决方案1】:

    您只能在创建上下文菜单时单击菜单项,这是由插件动态完成的。所以,我们首先需要触发菜单。

    据我所知,无法触发原生上下文菜单。触发右键点击但是is possible,你需要使用contextmenu事件。

    特别是,使用$(el).trigger('contextmenu') 似乎工作正常。这似乎有效,因为插件明确supports this。完成后,我们需要触发对我们想要点击的菜单项的点击。

    // first, trigger the context menu
    $('.button-that-has-contextmenu').trigger('contextmenu');
    // then click the menu item you want to click
    // substitute the correct index in `eq(X)` here
    $('.context-menu-item:eq(1)').trigger('mouseup');
    

    因为这个插件不是托管在CDN上的,所以在这里创建sn-p并不容易。然而,我创建了一个JSFiddle 来完整演示这个,我将插件源复制+粘贴到小提琴中。


    在 cmets 中,您询问了 web.whatsapp.com。我碰巧有一个 WhatsApp 帐户并在那里进行了测试。看来他们是 not 使用 jQuery contextMenu 插件。确实定义了一个$ 函数,但它似乎不是jQuery,而只是document.querySelector 的快捷方式。

    我不知道他们的自定义上下文菜单代码是什么,但我确实设法触发了它。基本上,我使用了上述代码的 vanilla JS 版本,然后必须弄清楚要触发哪个元素。后者比我想象的要容易。有一个打开的聊天列表,.infinite-list-item 元素。它们在 DOM 中的顺序与视觉顺序不匹配,但例如可以使用浏览器检查器找到您想要的顺序。鉴于您拥有它,您希望该列表项中的 .chat 元素。假设我们对第二项感兴趣,我们可以选择如下:

    var target = $('.infinite-list-item:nth-child(2) .chat');
    

    您可以在浏览器控制台中检查您获得了正确的元素。然后,触发一个事件,如下所示。

    var evt = new MouseEvent('contextmenu', {
          bubbles: true,
          cancelable: true,
          view: window,
          buttons: 2
        });
    target.dispatchEvent(evt);
    

    这使用现代的MouseEvent 构造函数,代码基于this example

    以上将打开浏览器左上角的上下文菜单。您可以通过将clientXclientY 属性传递给代表窗口中的位置的MouseEvent 构造函数来更改位置。

    完成后,您可以单击上下文菜单中的项目。除非您无法使用 JavaScript 自动执行此操作。我查看了源代码,这些菜单项的点击处理程序会检查是否event.isTrusted,这意味着您无法以编程方式触发对它们的点击。

    您可能希望考虑使用可以在较低级别上模拟点击的东西,例如 Selenium 2.0 (WebDriver),或者像 WebdriverIO 这样的一些包装器。

    【讨论】:

    • 嘿,谢谢你的解决方案,但它在我实际测试的地方不起作用......它实际上是 web.whatsapp.com ..如果你右键单击它列出这个上下文菜单的任何地方......它在那里不工作..我已经把它的示例html代码放在这里jsfiddle.net/adjmpw/ympnzb1c/4 ..它在那里工作。但不在 web.whatsapp.com 中工作。也许它的父级是绝对定位的? .请帮助我,我会给你多少赏金
    • 嗨,非常感谢,我实际上能够使用 mouseover 事件并单击 .icon-down 来触发上下文菜单,但是无法单击静音按钮..现在我知道为什么了..因为 isTrusted .. 我打算使用 selenium .. 即使有 isTrusted ,硒也可以点击这些按钮吗?你能告诉任何优秀的 selenium javascript 包装器在哪里可以执行此操作和任何操作吗?
    • 不客气!是的,它将与 Selenium 一起使用,因为它在那里模拟了较低级别的点击和鼠标移动。我个人没有任何 JS 包装器的经验,但你可以试试 WebdriverIO,我在我的答案中链接了它。
    • 在您授予赏金之前,让我知道我的回答是否有任何改进之处。
    • 我给了你赏金:),我按照你说的尝试了 webdriverJs.. 现在遇到了一些问题,如果你能解决它,我会给你 200 赏金:D -- stackoverflow.com/questions/43353279/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多