ZBLOG

hook innerHTML 的get 和 set 方法,在set的时候为html加上随机字符串,在get的时候需要还原原始值,如何做到?可能存在N多次调用innerHTML

拦截和修改 innerHTML 的 getter/setter

要实现这个功能,我们需要使用 JavaScript 的 Object.defineProperty 来拦截元素的 innerHTML 属性。以下是完整的解决方案:

实现代码

// 存储原始值和对应的随机字符串标记
const originalHtmlMap = new WeakMap();

function interceptInnerHTML(element) {
    // 保存原始的 innerHTML getter/setter
    const descriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
    
    Object.defineProperty(element, 'innerHTML', {
        get: function() {
            // 获取当前值
            const currentValue = descriptor.get.call(this);
            
            // 如果有存储的原始值,就还原它
            if (originalHtmlMap.has(this)) {
                const { originalHtml, markedHtml } = originalHtmlMap.get(this);
                if (currentValue === markedHtml) {
                    return originalHtml;
                }
            }
            
            return currentValue;
        },
        set: function(value) {
            // 生成随机字符串标记
            const randomStr = Math.random().toString(36).substring(2, 15);
            
            // 在原始 HTML 中添加标记(这里简单地在开头添加)
            const markedValue = `<!-- ${randomStr} -->${value}`;
            
            // 存储原始值和标记后的值
            originalHtmlMap.set(this, { 
                originalHtml: value,
                markedHtml: markedValue 
            });
            
            // 设置标记后的值
            return descriptor.set.call(this, markedValue);
        }
    });
}

// 使用示例:拦截某个元素的 innerHTML
const targetElement = document.getElementById('myElement');
interceptInnerHTML(targetElement);

// 测试设置和获取
targetElement.innerHTML = '<div>Hello World</div>';
console.log(targetElement.innerHTML); // '<div>Hello World</div>'(自动去除了标记)

console.log(targetElement.innerHTML); // '<div>Hello World</div>'(看起来是原始值)

关键点说明

  1. WeakMap存储:使用 WeakMap 来存储元素与其原始 HTML/标记 HTML,避免内存泄漏。

  2. getter逻辑

    • 检查当前元素是否有存储的原始值
    • 如果当前值与存储的标记值匹配,则返回原始值
  3. setter逻辑

    • 为每个设置的 HTML 添加唯一随机字符串标记(这里简单使用了注释)
    • 同时保存原始值和标记后的值
  4. 多次调用处理

    • WeakMap会跟踪每个元素的最后一次设置的值
    • getter总是返回最近一次设置的原始值

注意事项

  1. 性能影响:这种拦截会影响 DOM操作性能,特别是频繁操作时。

  2. 兼容性:确保目标浏览器支持 WeakMap。

  3. 更复杂的场景:如果需要更精确地追踪多次修改,可能需要维护一个修改历史栈而非只保存最新值。

  4. DOM变化检测:某些框架可能会直接操作 DOM而不通过 innerHTML,这种情况下不会被拦截到。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23143

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?