WhatsApp网页版号码掩码:循环索引异常与动态元素处理求助
WhatsApp网页版手机号掩码功能实现问题
我想通过预加载脚本在WhatsApp网页版实现手机号掩码功能:查询指定父元素的子元素,将包含+90或0的文本替换为REPLACEDTEXT,不改动无匹配内容的元素。
初始代码
let contactNames = document.querySelectorAll(".l7jjieqr,._11JPr"); let contactNamesLength = contactNames.length; console.log(contactNamesLength) for (let i = 0; i < contactNamesLength; i++) { const element = contactNames[i]; element.title = ""; if (element.textContent && element.innerText.includes("+90", 0) && !element.innerText.includes("REPLACEDTEXT")) { element.innerText = element.textContent.replace( /^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*/g, "REPLACEDTEXT" ); if (element.parentNode.className == "_3q9s6") { element.innerText = element.textContent.replace( /^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*/g, "REPLACEDTEXT" ); } // changing group name on chatlist to Xx if (element.parentNode.className == "Hy9nV") { element.innerText = element.textContent.replace( /^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*/g, "REPLACEDTEXT" ); } } }
遇到的问题
滚动WhatsApp网页版时,循环索引(i)会发生变化,导致即使元素不包含0或+90也被错误替换。
疑问
- 有没有方法可以逐个处理这些子元素,同时支持新元素动态添加?
- 能否用JavaScript在不刷新整页的情况下重渲染(刷新)单个元素?
已尝试的方案
- 使用
forEach循环替代for循环,问题依旧。contactNames.forEach(child => { // 尝试用forEach替代for循环,但结果相同 }); - 使用
MutationObserver,问题仍未解决。
补充说明
基于Electron版本的Altus项目,可修改预加载脚本测试代码。
解决方案
1. 修复元素处理逻辑,避免误替换
代码存在重复替换逻辑,且判断条件可优化。需确保每次处理元素时严格校验匹配条件,同时跳过已处理的元素:
function maskPhoneNumbers(element) { // 跳过已处理过的元素 if (element.innerText.includes("REPLACEDTEXT")) return; const text = element.textContent.trim(); // 匹配包含+90或以0开头的手机号 const phoneRegex = /(\+90|^0)\d+/; if (phoneRegex.test(text)) { element.innerText = text.replace(/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*/g, "REPLACEDTEXT"); element.title = ""; } }
2. 正确使用MutationObserver处理动态元素
之前监听逻辑有误,需监听聊天列表的父容器,当新元素添加时自动处理:
// 目标容器:WhatsApp聊天列表的父容器,需根据实际DOM结构调整 const targetNode = document.querySelector("#pane-side"); // 监听配置:监听子元素添加 const config = { childList: true, subtree: true }; // 回调函数:处理新增节点 const callback = function(mutationsList) { for (let mutation of mutationsList) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { const contactElements = node.querySelectorAll(".l7jjieqr,._11JPr"); contactElements.forEach(maskPhoneNumbers); } }); } } }; // 启动观察者 const observer = new MutationObserver(callback); if (targetNode) { observer.observe(targetNode, config); } // 初始化处理现有元素 document.querySelectorAll(".l7jjieqr,._11JPr").forEach(maskPhoneNumbers);
3. 单个元素重渲染方法
JavaScript没有直接的"重渲染单个元素"API,但可通过触发元素重排实现局部更新:
function rerenderElement(element) { // 强制浏览器触发重排 element.style.display = 'none'; element.offsetHeight; element.style.display = ''; }
不过在你的场景中,修改innerText已经会自动触发元素重渲染,无需额外调用此方法。
内容的提问来源于stack exchange,提问作者Asaf Hekimoğlu
相关产品推荐
相关产品推荐

