【问题标题】:JavasScript wait for web element to be visible and click itJavascript 等待 webelement 可见并单击它
【发布时间】:2019-10-12 06:54:33
【问题描述】:

我正在尝试使用 JavaScript 自动执行一些任务。正在生成网站,因此我无法使用 CSS 选择器,因为它们会随着每次网站刷新而改变。它没有在示例中显示,但可以使用其文本内容来操作按钮(遗憾的是,CSS 无法获得)。

我已经弄清楚(感谢 StackOverflow)如何通过其 Xpath 单击 Web 元素,但仍然不知道如何告诉 JS 等到它出现。

点击元素的代码(工作):

var xPathRes = document.evaluate ('//*[@id="tsf"]/div[2]/div/div[3]/center/input[1]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
xPathRes.singleNodeValue.click();

尝试等待元素出现然后单击它(不起作用):

var selector = "//*[@id='tsf']/div[2]/div/div[3]/center/input[1]";
var time = 500;
    if(document.evaluate (selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)) {
        selector.singleNodeValue.click();
        return;
        }
    else {
        setTimeout(function() {
        waitForElementToDisplay(selector, time);
        }, time);    
    }

如您所见,示例中的代码是 Google.com 搜索按钮。

我一直使用 Python Selenium 来做这些事情,但在这种情况下我真的不能。

附言。从发布的代码中可以看出,我很讨厌 JS。

感谢您的帮助!

编辑:

按照@folo 代码,我写了这样的代码:

var element = '//*[@id="tsf"]/div[2]/div/div[3]/center/input[1]';
(function checkIfElemExists() {
   if (!document.evaluate (element, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)) {
     console.log('nope')
     window.requestAnimationFrame(checkIfElemExists);
   } else {
     console.log('okay i exist now! lets do something.') 
   }
 })()

问题是它总是返回“好的,我现在存在!)。即使我在不​​包含此元素的网站上运行它。

【问题讨论】:

  • waitForElementToDisplay 是如何定义的?
  • 我刚刚意识到它不是。感谢您指出这一点,这是从 Stack 复制的代码。

标签: javascript google-chrome browser automation


【解决方案1】:

如果我理解正确,您想确定元素何时开始存在于 DOM 中?

如果是这样,你应该使用 requestAnimationFrame

 (function checkIfElemExists() {
   if (!document.querySelector('.some-element')) {
     window.requestAnimationFrame(checkIfElemExists);
   } else {
     console.log('okay i exist now! lets do something.')
   }
 })()

每当在浏览器中请求一个新框架时,它都会检查该元素是否存在,如果存在,它将停止并执行您想做的任何事情。它既有效又干净。

编辑:

我不确定我是否理解如果你可以使用 xpath,为什么不能使用 css 选择器,如果你要使用 css 选择器,那就是这个:

#tsf>div:nth-of-type(2)>div>div:nth-of-type(3)>center>input:nth-of-type(1)

用那个替换“.some-element”选择器。

【讨论】:

  • 是的,但它必须是由 XPath 标识的元素。 CSS 选择器将不起作用。 Xpath 可以与您的代码一起使用吗?
  • 我已经检查过了,它适用于 CSS,但 Xpath 返回以下错误:无法在 'Document' 上执行 'querySelector':'//*[@id="tsf"]/div [2]/div/div[3]/center/input[1]' 不是有效的选择器。
  • 我修改了您的代码,现在似乎可以使用了。我会做一些进一步的测试,让你知道。现在的代码是: (function checkIfElemExists() { if (!document.evaluate ('//*[@id="tsf"]/div[2]/div/div[3]/center/input[1]' , document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)) { window.requestAnimationFrame(checkIfElemExists); } else { console.log('好吧,我现在存在!让我们做点什么。') } })()
  • 我编辑了问题,请看看你是否知道可以做什么。
  • 更新了我的答案,可能会解决您的 xpath 问题。我希望你能那样做。
【解决方案2】:

该按钮仅在页面 (DOM) 完全加载时出现。在 javascript 中,您可以使用“onload”事件:

window.onload = function () { 
   //Code to execute when page is loaded.
}

或通过 JQuery:

$( document ).ready(function() {
    //Code to execute when page is loaded.
});

我希望这就是你要找的。​​p>

【讨论】:

  • 问题是有几个页面,我需要弄清楚如何等待元素出现。所以加载了一个页面,所有操作都完成了-> JS单击下一步-> JS必须等到另一个站点加载-> 在新页面上做一些事情等。
  • 如果你想观察 DOM 的变化,你可以使用MutationObserver。在旧浏览器中,您可能需要DOMNodeInserted
  • @deValck 您正在假设 X 发生时会发生什么。这是思考编程的一种自然方式,但它是错误的秘诀。更好的方法是永远不要做出假设,准备好感到惊讶。
【解决方案3】:

最后我设法找到一种方法来告诉 Javascript 等待网站上的 Xpath 元素:

var element = '//*[@id="tsf"]/div[2]/div/div[3]/center/input[1]'; 
var clickButton = document.evaluate (element, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 
(function checkIfElemExists() { 
   if (clickButton == null) { 
     console.log('nope') 
     window.requestAnimationFrame(checkIfElemExists); 
   } else { 
     console.log('okay i exist now! lets do something.') 
     clickButton.click() 
   } 
})() 

感谢@folo 的帮助!非常感谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 2015-11-30
    • 2014-11-01
    • 2019-04-30
    相关资源
    最近更新 更多