JS dispatchEvent 不起作用

del*_*les 2 javascript google-webmaster-tools

通常我不会在 SO 中提出这种如此具体的问题,但我在这个问题上挣扎了好几天,所以我在这里寻求一些帮助。

我正在构建一个应用程序来自动执行网络版 Whatsapp ( https://web.whatsapp.com/ ) 中的任务。我的目标是点击界面上的一个按钮来显示一些选项,然后再次点击同一个按钮来隐藏它。

模拟我想手动执行的操作:

1 - 打开 Whatsapp Web。

2 - 单击界面右上角的“附加”按钮,如下图所示。

在此处输入图片说明

3 - 将显示附加选项,如下图:

在此处输入图片说明

4 - 再次单击“附加”按钮,附加选项将隐藏。

就是这样,但我想使用 Javascript(纯 JS,没有 JQuery)以编程方式执行此操作。

为了完成第 2 步中的任务,我成功地使用了下面的代码:

var nodes = document.getElementsByTagName('span');
if (typeof lastElementId == 'undefined')
    var lastElementId = 0;
var result = undefined;
for (var i = 0; i < nodes.length; i++) {
    var h = nodes[i].outerHTML;
    var flag = false;
    flag = (h.toLowerCase().indexOf('data-icon="clip') > -1);
    if (flag) {
        result = h;
        lastElementId = i;
        break;
    }
}
if (result !== undefined) {
    function triggerMouseEvent(node, eventType) {
        var clickEvent = document.createEvent('MouseEvents');
        clickEvent.initEvent(eventType, true, true);
        node.dispatchEvent(clickEvent);
    }
    triggerMouseEvent(nodes[i], "mouseover");
    triggerMouseEvent(nodes[i], "mousedown");
} else {
    console.log('Not found');
}
;
Run Code Online (Sandbox Code Playgroud)

上面的代码可以执行第 2 步,但不能执行第 4 步。当我在选项显示后手动单击“附加”按钮时,选项将隐藏。但没有使用我的 JS 代码。

我在这里错过了什么?

提前致谢 !

Kar*_*yan 6

要解决关闭问题:

  1. 右键单击附加元素。
  2. inspect element在chrome浏览器中选择
  3. 在右侧面板中选择Event Listeners选项卡并找到mousedown部分 在此处输入图片说明
  4. 单击处理程序代码并检测我们需要传递特定的screenX并screenY满足此特定业务逻辑并传递到n.uie.requestDismiss()显然执行所说的部分。 在此处输入图片说明

所以现在我们有足够的信息来尝试一个可能的解决方案,它现在显然有效。是这样的:

const toggleAttach = () => {
  // select the span with reliable identification like data-*
  const clipNode = document.querySelector('[data-icon="clip"]');
  // take its element, i.e. the button itself
  const clipButtonNode = clipNode.parentNode;
  // extract the current offset position relative to the document
  // more info here https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
  // we can use this for filling in the non-0 screenX and screenY
  const clipButtonNodeClientRect = clipButtonNode.getBoundingClientRect();

  clipButtonNode.dispatchEvent(new MouseEvent("mousedown", {
    bubbles: true,
    cancelable: true,
    screenX: clipButtonNodeClientRect.x,
    screenY: clipButtonNodeClientRect.y
  }));
}
Run Code Online (Sandbox Code Playgroud)

现在了解为什么第一个 mousedown 可以打开:

这很难逆向工程,但我设法找到的是,如果您安装 React DevTools(因为 whatsapp web 是用 React 编写的)扩展并在 DevTools 中打开其选项卡,您将看到:

在此处输入图片说明

在那里你会发现:

在此处输入图片说明

所以我们可以得出一个非常模糊的结论,即打开和关闭是在单独的函数中处理的。剩下的就看你自己想办法了。

希望这有帮助。