最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JS dispatchEvent not working - Stack Overflow

programmeradmin1浏览0评论

Usually i don't put this kind of so specific question in SO, but i'm struggling with this issue for days, so i'm seeking for some help here.

I'm building an app to automate a task in web version of Whatsapp (/). My goal is to click on a button on the interface to show some options, and then click on the same button again to hide it.

To simulate what i want to do manually :

1 - Open Whatsapp Web.

2 - Click on the 'Attach' button on the upper right corner of the interface, as shown in the image below.

3 - The attach options will show, as the image below :

4 - Click on the 'Attach' button again, and the attach options will hide.

That's it, but i want do this programatically using Javascript (pure JS, no JQuery).

To achieve the task in step 2, i'm using the code below with success :

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

The code above will work to do the step 2, but won't work to do step 4. Manually when i click in the Attach button after the options are show, the options will hide. But not using my JS code.

What am i missing here ?

Thanks in advance !

Usually i don't put this kind of so specific question in SO, but i'm struggling with this issue for days, so i'm seeking for some help here.

I'm building an app to automate a task in web version of Whatsapp (https://web.whatsapp./). My goal is to click on a button on the interface to show some options, and then click on the same button again to hide it.

To simulate what i want to do manually :

1 - Open Whatsapp Web.

2 - Click on the 'Attach' button on the upper right corner of the interface, as shown in the image below.

3 - The attach options will show, as the image below :

4 - Click on the 'Attach' button again, and the attach options will hide.

That's it, but i want do this programatically using Javascript (pure JS, no JQuery).

To achieve the task in step 2, i'm using the code below with success :

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

The code above will work to do the step 2, but won't work to do step 4. Manually when i click in the Attach button after the options are show, the options will hide. But not using my JS code.

What am i missing here ?

Thanks in advance !

Share Improve this question asked May 17, 2018 at 11:03 delphirulesdelphirules 7,50818 gold badges69 silver badges131 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

To fix the closing problem:

  1. Right click on the attach element.
  2. Select inspect element in chrome browser
  3. In the right panel select Event Listeners tab and find mousedown section
  4. Click the handler code and detect that we need to pass specific screenX and screenY to satisfy this particular business logic and pass through to n.uie.requestDismiss() part which apparently does what is says.

So now we have enough information to try a possible solution, which apparently works for now. Goes like this:

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

Now to understanding why the first mousedown works for opening:

This is much harder to reverse engineer, but what I managed to find is if you install React DevTools (since whatsapp web is written in React) extension and open its tab in DevTools you will see:

And there you will find:

So we can make a very vague conclusion that opening and closing is handled in separate functions. Rest is up to you to figure out.

Hope this helped.

发布评论

评论列表(0)

  1. 暂无评论