Playwright - 如何检查元素是否在视口中?

Ars*_*son 6 javascript viewport puppeteer playwright

我有一个类似数组的节点对象(它是一个轮播),它们的顺序是在每次页面刷新时随机生成的,剧作家发现所有元素都是可见的,但其中一些元素在视口之外(基于收到的错误) 。我需要确保在尝试单击该元素时该元素位于视口内,否则我会收到一条错误消息,指出该元素位于视口外。

如何确定类似数组对象的随机选取的节点元素是否确实在视口内?

car*_*alX 5

不幸的是,Playwright 在 Puppeteer 中还没有像 isInterSectingViewport 这样的方法。(就像这样

\n

所以 Playwright 的作者在 Slack 社区帮助我(你可以在官方网站上找到它)。

\n
    const result = await page.$eval(selector, async element => {\n      const visibleRatio: number = await new Promise(resolve => {\n        const observer = new IntersectionObserver(entries => {\n          resolve(entries[0].intersectionRatio);\n          observer.disconnect();\n        });\n        observer.observe(element);\n        // Firefox doesn\'t call IntersectionObserver callback unless\n        // there are rafs.\n        requestAnimationFrame(() => {});\n      });\n      return visibleRatio > 0;\n    });\n
Run Code Online (Sandbox Code Playgroud)\n

我使用此方法的情况:\n我想知道在我\xe2\x80\x99m 单击某个元素后 - 我已滚动到另一个元素。不幸的是,boundingBox 方法对我的情况没有帮助。

\n

您也可以将此功能添加到我的 BasePage 类中

\n
/**\n     * @returns {!Promise<boolean>}\n     */\n  isIntersectingViewport(selector: string): Promise<boolean> {\n    return this.page.$eval(selector, async element => {\n      const visibleRatio: number = await new Promise(resolve => {\n        const observer = new IntersectionObserver(entries => {\n          resolve(entries[0].intersectionRatio);\n          observer.disconnect();\n        });\n        observer.observe(element);\n        // Firefox doesn\'t call IntersectionObserver callback unless\n        // there are rafs.\n        requestAnimationFrame(() => {});\n      });\n      return visibleRatio > 0;\n    });\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

PS\n其实除了一行之外的所有代码均取自GitHub Puppeteer中 isInterSectingViewport 方法的实现

\n


Ars*_*son 0

const firstId = "#someId"; 

// it happens that I am evaluating in a frame, rather than page 
const result = await frame.evaluate((firstId) => {

  // define a function that handles the issue
  // returns true if element is within viewport, false otherwise 
  function isInViewport(el) {

    // find element on page 
    const element = document.querySelector(el); 

    const rect = element.getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <=
        (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <=
        (window.innerWidth || document.documentElement.clientWidth)
    );
  }; 

  return isInViewport(firstId); 

}, firstId);



// back to node context 
console.log(result); 
Run Code Online (Sandbox Code Playgroud)