如何用JavaScript重复执行查找点击元素操作并解决分页跳转问题
解决分页回退导致的内容获取错误问题
问题核心
关闭弹窗后页面自动重定向回第1页,每次处理下一行前必须先回到目标分页(示例为第2页),但原代码中分页跳转逻辑和后续操作没有同步页面加载状态,且重复启动流程导致执行中断。
原代码的关键问题
- 未等待页面跳转完成:在
processNextRow中点击分页按钮后立刻执行viewButton.click(),此时页面还停留在第1页,获取的元素自然是第1页的内容。 - 流程重复启动:跳转分页后调用
runSecondCode(),会重新初始化processRows,重置currentRowIndex并重复启动流程,导致后续操作混乱。
修正方案
将分页跳转逻辑封装为异步等待函数,确保页面成功切换到目标页后,再查找当前行的“查看”按钮并执行操作,避免流程冲突。
修正后的代码
// 获取分页容器的引用 const pagination = document.querySelector('.e-pager'); const TARGET_PAGE_INDEX = "2"; // 目标分页索引,可修改 // 封装跳转至目标页的异步函数,确保页面加载完成 async function navigateToTargetPage() { return new Promise((resolve) => { function checkAndNavigate() { const targetElement = pagination.querySelector(`a[index="${TARGET_PAGE_INDEX}"]`); if (targetElement && targetElement.classList.contains('e-current')) { // 已经在目标页,直接resolve resolve(); return; } if (targetElement) { // 点击目标页按钮 targetElement.click(); // 等待页面加载,1秒后检查是否成功跳转 setTimeout(() => checkAndNavigate(), 1000); } else { // 目标页按钮未显示,点击下一页后重试 const nextButton = pagination.querySelector('.e-next.e-icons.e-icon-next.e-nextpage.e-pager-default'); nextButton.click(); setTimeout(() => checkAndNavigate(), 2000); } } checkAndNavigate(); }); } // 初始化流程:先跳转到目标页,再开始处理行数据 async function initProcess() { await navigateToTargetPage(); processRows(); } // 处理行数据的函数 function processRows() { let currentRowIndex = 1; // 注意:aria-rowindex通常从1开始,根据实际页面调整 async function processNextRow() { // 先确保回到目标页 await navigateToTargetPage(); // 查找当前行的“查看”按钮元素 const viewButton = document.querySelector(`tr.e-row[aria-rowindex="${currentRowIndex}"] b[style="color: blue; cursor: pointer;"]`); // 如果没有下一行,弹出提示并退出函数 if (!viewButton) { alert("No More Tenders"); return; } // 模拟点击当前行的“查看”按钮 viewButton.click(); // 等待弹窗加载完成,提取链接并关闭 setTimeout(async () => { // 查找链接元素 const linkElement = document.querySelector('td[colspan="3"] a[href^="https://tenders.go.ke/OneTender/"]'); const link = linkElement ? linkElement.getAttribute("href") : null; console.log(link); // 模拟点击“关闭”按钮 const closeButton = document.querySelector('button.btn.btn-warning.p-2[type="button"][style*="background-color: rgb(245, 156, 26)"]'); if (closeButton) closeButton.click(); // 递增行索引,处理下一行 currentRowIndex++; // 等待页面回退完成后,处理下一行 setTimeout(processNextRow, 1000); }, 1000); // 调整等待时间,根据弹窗加载速度修改 } // 启动行数据处理流程 processNextRow(); } // 启动整个流程 initProcess();
关键修改点
- 异步分页跳转:用
Promise封装navigateToTargetPage函数,确保页面成功跳转到目标页后再执行后续操作。 - 移除重复流程启动:删除原代码中
processNextRow内调用runSecondCode的逻辑,避免流程冲突。 - 行索引起始值修正:默认
aria-rowindex从1开始,根据实际页面调整,避免找不到第一行元素。 - 等待时间优化:调整各步骤的等待时间,适配页面和弹窗的实际加载速度。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

