javascript - Windows 上的 Puppeteer : Clicking anchor while Meta key pressed won't open link in new tab as expected

标签 javascript node.js puppeteer

目标是通过仅将鼠标移动到 anchor 并在当前鼠标光标位置(希望位于链接的可点击区域上)发出单击,同时按下 Meta 键(命令上)来单击 anchor Mac 操作系统,Windows 上为 Ctrl)。

预期结果是 Chrome 打开一个新选项卡,加载链接页面。这在 Mac 操作系统上效果很好。但在 Windows 上,它只是加载当前选项卡中的页面,就好像在单击过程中没有按住 Ctrl 键一样。

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        headless: false,
        executablePath: process.platform === "darwin" ?
            "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
            // Location of Chrome for Windows Canary v76.x on my Windows system, yours may vary
            : "C:\\Users\\ADMINI~1\\AppData\\Local\\Google\\CHROME~2\\APPLIC~1\\chrome.exe"

    });
    const page = await browser.newPage();
    await page.goto("https://example.com", { waitUntil: 'networkidle0', timeout: 30000 });
    let mySelector = "a";
    let myElems = await page.evaluate(function(myThis) {
        const domElemA = Array.from(document.querySelectorAll(myThis.selector));
        const outElemA = domElemA.reduce(function(acc, cur) {
            let r = cur.getBoundingClientRect();
            let myObj = { rectLeft: Math.round(r.left), rectTop: Math.round(r.top), rectRight: Math.round(r.right), rectBottom: Math.round(r.bottom) };
            // optionally do some filtering here, for objects outside the viewport.
            // I know I could use Array.map() here if no filtering desired.
            return [...acc, myObj];
        }, []);
        return outElemA;
    }, { selector: mySelector });
    console.log(myElems);   // output the anchors we found
    let e = myElems[0];
    // determine the center of the anchor element
    let x = Math.round((e.rectRight - e.rectLeft) / 2 + e.rectLeft);
    let y = Math.round((e.rectBottom - e.rectTop) / 2 + e.rectTop);
    let k = "Meta"  // Command on MacOS, Ctrl on Windows
    await page.mouse.move(x, y);
    await page.waitFor(100);
    await page.keyboard.down(k);
    await page.waitFor(100);
    await page.mouse.down();
    await page.waitFor(100);
    await page.mouse.up();
    await page.waitFor(100);
    await page.keyboard.up(k);
    // Expected result: Link is opened in new tab due to Meta key held down while clicking
    // Actual result on Mac OS: Behaves as expected
    // Actual result on Windows: Opens link in the same tab, as if no Meta key were pressed
})();

puppeteer 师版本:

> npm view puppeteer
puppeteer@1.17.0 | Apache-2.0 | deps: 8 | versions: 642

Windows 上的 Chrome 版本(金丝雀):

76.0.3803.0 (Official Build) (64-bit) 

我知道有一些方便的 Puppeteer 函数,例如 page.click() 可以直接单击给定元素的中心,但任何此类快捷解决方案都超出了这个问题的范围。

它必须在不直接选择元素的情况下工作,通过将光标移动到可能的可点击区域,然后单击鼠标。我知道这个可点击的形状可能会有所不同,因此这种方法可能会失败——也不是我所要求的建议类型(“你为什么要这样做!?”)。 😂

此外,这并不是经常听到的提示的重复,即 Meta+A(全选)在 Windows 上工作正常,但在 Mac OS 上无法按预期工作。

但我确实怀疑这是一个类似的问题,但相反,具体取决于处理 GUI 事件的位置、DOM 模型级别、浏览器级别、操作系统级别。

如果问题具有不可修复的性质,是否有解决方法可以在新选项卡中打开链接,但 100% 基于当前鼠标位置,而不是直接“对”目标 DOM 元素执行任何操作? Page.click() 等做了很多我不希望我的“用户”做的“事情”。

最佳答案

这可能是因为 meta 键引用 Windows 上的“Windows”键。

如果它在 Windows 上运行,您可以使用 ctrl:

let k = process.platform == "win32" ? "Control" : "Meta";

https://nodejs.org/api/process.html#process_process_platform

关于javascript - Windows 上的 Puppeteer : Clicking anchor while Meta key pressed won't open link in new tab as expected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56307148/

相关文章:

javascript - 获取当前对象中先前对象的值

node.js - Nodejs Firebase 和 Angular4 身份验证

node.js - Mocha——before() 没有按预期执行 'before'?

javascript - Jest 测试中的异步代码问题

javascript - 使用按钮隐藏/显示 iframe

javascript - 编辑简单网站模板的表单不起作用

javascript - 将表字段名从 php 保存到 excel

javascript - 查询框架内的选择器

node.js - nodejs Puppeteer 缓存

javascript - 按 Enter 时超越链接