JS dispatchEvent不起作用

时间:2018-05-17 11:03:37

标签: javascript google-webmaster-tools

通常情况下我并没有把这种特定的问题放在SO中,但我已经在这个问题上挣扎了好几天,所以我在这里寻求一些帮助。

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

模拟我想手动完成的事情:

1 - 打开Whatsapp网站。

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

enter image description here

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

enter image description here

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');
}
;

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

我在这里缺少什么?

提前致谢!

1 个答案:

答案 0 :(得分:2)

解决结算问题:

  1. 右键单击附加元素。
  2. 在Chrome浏览器中选择inspect element
  3. 在右侧面板中选择Event Listeners标签,然后找到mousedown部分 enter image description here
  4. 单击处理程序代码并检测我们是否需要传递特定的screenXscreenY以满足此特定的业务逻辑,并传递到n.uie.requestDismiss()部分,这显然会执行所说的内容。 enter image description here
  5. 所以现在我们有足够的信息来尝试一种可能的解决方案,这显然适用于现在。是这样的:

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

    现在要了解第一个mousedown开放的原因:

    这对于逆向工程来说要困难得多,但我设法找到的是如果你安装React DevTools(因为whatsapp web是用React编写的)扩展并在DevTools中打开它的标签你会看到:

    enter image description here

    你会发现:

    enter image description here

    因此,我们可以得出一个非常模糊的结论,即在单独的函数中处理打开和关闭。休息由你决定。

    希望这会有所帮助。