如何利用WebView2确保网页资源完全加载并验证指定图片存在?
可靠的WebView2页面元素检测方案
针对你遇到的问题,以下是几种无需盲目延长等待时间的可靠方案:
方案1:基于Promise等待DOM与目标元素(图片)就绪
直接在页面中注入异步脚本,先等待DOM加载完成,再检查目标图片元素是否存在,同时确保图片资源加载完成(或处理加载失败的情况)。这种方式能精准匹配元素的就绪状态,不会提前执行判断。
C#调用代码:
// 注入异步脚本等待元素就绪 var scriptResult = await _view.ExecuteScriptAsync(@" new Promise((resolve) => { // 先判断当前DOM状态,若已就绪直接检查 if (document.readyState === 'complete' || document.readyState === 'interactive') { checkTargetImage(); } else { // 等待DOM加载完成事件触发后检查 document.addEventListener('DOMContentLoaded', checkTargetImage); } function checkTargetImage() { const targetImg = document.getElementById('exerciseCautionId'); if (!targetImg) { resolve(false); return; } // 图片已加载完成(或加载失败)则确认存在 if (targetImg.complete) { resolve(true); } else { // 监听图片加载完成事件 targetImg.addEventListener('load', () => resolve(true)); // 图片加载失败时,元素本身仍存在,故返回true targetImg.addEventListener('error', () => resolve(true)); } } }) "); bool isImagePresent = bool.Parse(scriptResult);
方案2:轮询检查(带超时机制)
如果不想用Promise,可采用轮询方式,每隔固定时间检查一次目标元素状态,直到超时或找到元素。这种方式逻辑简单,适合场景单一的情况。
C#代码示例:
bool isImagePresent = false; const int timeoutSeconds = 30; // 设置最大等待时长 DateTime startTime = DateTime.Now; while ((DateTime.Now - startTime).TotalSeconds < timeoutSeconds) { var checkResult = await _view.ExecuteScriptAsync(@" const img = document.getElementById('exerciseCautionId'); // 检查元素存在且图片已加载完成 img && img.complete "); if (bool.TryParse(checkResult, out bool found) && found) { isImagePresent = true; break; } await Task.Delay(500); // 每隔500毫秒检查一次 }
方案3:针对SPA(单页应用)的DOM变化监听
如果目标页面是单页应用,路由切换不会触发WebView2的NavigationCompleted事件,此时可以用MutationObserver监听DOM变化,直到目标元素出现。
C#调用代码:
var scriptResult = await _view.ExecuteScriptAsync(@" new Promise((resolve) => { // 先检查元素是否已存在 const targetImg = document.getElementById('exerciseCautionId'); if (targetImg) { resolve(true); return; } // 创建DOM变化观察者 const observer = new MutationObserver((mutations) => { const img = document.getElementById('exerciseCautionId'); if (img) { resolve(true); observer.disconnect(); // 找到元素后停止监听 } }); // 监听整个body的子元素变化 observer.observe(document.body, { childList: true, subtree: true }); // 设置超时,防止无限等待 setTimeout(() => { observer.disconnect(); resolve(false); }, 30000); }) "); bool isImagePresent = bool.Parse(scriptResult);
内容的提问来源于stack exchange,提问作者Manvinder
相关产品推荐
相关产品推荐

