如何在 DOM 元素出现时跳出循环?

How to break out from loop when a DOM element appears?

我想点击画廊。由于我不知道画廊中有多少张图片,我想我需要一个 while 循环。当我到达最后一张图片时,下一张图片的按钮类名变为 next-photo is-hidden,直到那时它只是 next-photo。 所以我的目标是有一个 while 循环,当这个按钮被隐藏时,从循环中跳出,直到那时它应该被重复调用。 我现在站在这里:

async function openGallery(page) {
  await page.evaluate(async () => {
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
    let randomTime = 250;
    let clickOnImage = document.querySelector('div.image');
    let nextbutton = document.querySelector('button[class="next-photo"]');
    let closeGallery = document.querySelector('button[class="close-gallery"]');
    let lastImage = document.querySelector('button[class="next-photo is-hidden"]');
    if (clickOnImage) {
      clickOnImage.click();
    }
    while (nextbutton) {
      nextbutton.click();
      if (lastImage) {
        closeGallery.click();
        break;
      }
      await delay(randomTime);
    }
  });
}

但是现在,当我执行到最后一张图的时候,程序不会跳出循环,也就是说,这一段之后的代码不会执行。而且画廊不会关闭。

我错过了什么?

在添加 is-hidden class 之前,您在开头设置了一次 lastImage。一旦稍后添加 is-hidden class 就没关系了,因为 lastImage 已经设置了。

您可以在 if (lastImage) { 之前再次执行 lastImage = document.querySelector('button[class="next-photo is-hidden"]');

您的主要问题可能是在所有点击完成之前您只是在搜索 lastImage,这意味着它还不存在。解决办法是将该行移到 while 循环内,但总的来说,您提供的所有代码看起来都有些冗长。我可能会改用某种递归函数,类似于以下内容:

function updateContent() {
  setTimeout(function() {
      var button = document.getElementById('button');
      button.innerHTML = parseInt(button.innerHTML) + 1
      if (button.innerHTML === '5') {
          button.className = "unclickable"
          button.disabled = true
      } else {
          button.click()
      }
  }, 500)
}
<button id="button" class="clickable" onclick="updateContent()">1</button>