Mozilla扩展需求:URL动态变化时自动执行指定函数
沃尔玛动态页面自动获取UPC的解决方案
方法一:用MutationObserver监听DOM变化
沃尔玛基于Next.js开发,页面切换时会更新__NEXT_DATA__核心元素,我们可以监听该元素的变化,一旦DOM更新就执行UPC获取逻辑:
function getUpc() { const lotsOfData = document.getElementById("__NEXT_DATA__"); if (!lotsOfData) return null; try { const data = JSON.parse(lotsOfData.innerHTML); return data.props.pageProps.initialData.data.product.upc; } catch (e) { console.error("获取UPC失败:", e); return null; } } // 记录当前URL,避免重复触发 let currentUrl = window.location.href; function checkAndGetUpc() { const newUrl = window.location.href; if (newUrl !== currentUrl) { currentUrl = newUrl; const upc = getUpc(); if (upc) { console.log("UPC: " + upc); } } } // 启动DOM变化监听 const targetNode = document.getElementById("__NEXT_DATA__"); if (targetNode) { const observerConfig = { childList: true, subtree: true }; const observer = new MutationObserver(() => checkAndGetUpc()); observer.observe(targetNode, observerConfig); } // 页面加载完成后初始执行 checkAndGetUpc();
方法二:重写History API监听页面跳转
沃尔玛的搜索跳转依赖history.pushState/replaceState,这两个方法不会触发原生popstate事件,我们可以重写这两个API来捕获页面跳转:
function getUpc() { const lotsOfData = document.getElementById("__NEXT_DATA__"); if (!lotsOfData) return null; try { const data = JSON.parse(lotsOfData.innerHTML); return data.props.pageProps.initialData.data.product.upc; } catch (e) { console.error("获取UPC失败:", e); return null; } } // 保存原生History方法 const originalPushState = history.pushState; const originalReplaceState = history.replaceState; // 重写pushState,跳转后延迟执行获取逻辑 history.pushState = function(...args) { originalPushState.apply(this, args); setTimeout(() => { const upc = getUpc(); if (upc) console.log("UPC: " + upc); }, 500); }; // 重写replaceState history.replaceState = function(...args) { originalReplaceState.apply(this, args); setTimeout(() => { const upc = getUpc(); if (upc) console.log("UPC: " + upc); }, 500); }; // 监听浏览器前进后退 window.addEventListener('popstate', () => { setTimeout(() => { const upc = getUpc(); if (upc) console.log("UPC: " + upc); }, 500); }); // 初始加载时执行 const initialUpc = getUpc(); if (initialUpc) console.log("UPC: " + initialUpc);
注意事项
- 加延迟是为了等待动态DOM更新完成,避免获取不到最新的
__NEXT_DATA__内容 - 错误处理可以避免页面未完全加载时的报错
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

