Цель состоит в том, чтобы щелкнуть привязку, просто подведя к ней мышку и выполнив щелчок в текущей позиции курсора мыши (которая, будем надеяться, будет в интерактивной области ссылки), вместе с нажатой клавишей Meta (Command on Mac OS, Ctrl в Windows).
Ожидаемый результат - Chrome откроет новую вкладку, загружая связанную страницу. Это прекрасно работает на Mac OS. Но в 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
})();
Версия кукловода:
> npm view puppeteer
puppeteer@1.17.0 | Apache-2.0 | deps: 8 | versions: 642
Версия Chrome для Windows (канарейка):
76.0.3803.0 (Official Build) (64-bit)
Я понимаю, что есть удобные функции Puppeteer, такие как page.click (), которые щелкают прямо в центр данного элемента, но любые такие быстрые решения выходят за рамки этого вопроса.
Он должен работать, не выбирая элемент напрямую, переместив курсор в вероятную активируемую зону и затем щелкнув мышью. Я знаю, что эта кликабельная форма может варьироваться, поэтому такой подход может потерпеть неудачу - также не тот тип совета, который я прошу («Зачем вам это делать !?»). ?
Кроме того, это не дубликат часто звучащей жалобы на то, что Meta + A (выбрать все) отлично работает в Windows, но не работает должным образом в Mac OS.
Но я подозреваю, что это аналогичная проблема, но наоборот, в зависимости от того, где обрабатываются события GUI, на уровне модели DOM, на уровне браузера, на уровне ОС.
Если проблема носит неустранимый характер, есть ли обходной путь, чтобы открыть ссылку в новой вкладке, но на 100% основанную на текущем положении мыши, и ничего не делать "непосредственно" с целевым элементом DOM напрямую? Page.click () и тому подобное делают много «вещей», которые я не хочу, чтобы мой «пользователь» делал.