代理 HTML 元素

2023-12-13

我想检查一个库对我传递给它的视频元素做了什么,所以我天真地这样做了:

cosnt videoElement = new Proxy(document.querySelector('video'), {
    get(target, key) {
        const name = typeof key === 'symbol'? key.toString() : key;
        console.info(`Accessing video.${ name }`)
        return target[key];
    }
});

但我收到一个错误:

TypeError:无法在“Node”上执行“contains”:参数 1 不是“Node”类型。

有办法让这项工作发挥作用吗?


编辑:我已经获得了一些知识,我用它更新了我的代理如下:

cosnt videoElement = document.querySelector('video');
cosnt proxyElement = new Proxy(videoElement , {
    get(target, key) {
        if (key == '___element___') {
            return video;
        }

        const name = typeof key === 'symbol'? key.toString() : key;
        console.info(`Accessing video.${ name }`);
        const value = video[key];
        if (value instanceof Function) {
            return video[key].bind(video);
        } else {
            return video[key];
        }
    },
    set(target, key, value) {
        const name = typeof key === 'symbol'? key.toString() : key;
        console.info(`Writing video.${ name } = ${ value }`);
        video[key] = value;
        return true;
    }
});

它是为了调试,所以我编辑了编译后的代码,并将所有 DOM 操作引用替换为element.___element___.

接下来我发现通过代理调用函数好像有问题,所以我添加了.bind(video) part.

最后设置值是抛出。所以我必须用直接视频参考替换目标(事实上,我用视频替换了所有目标参考,只是为了确定),这使它工作......我不知道为什么或如何,但它做到了。

问题是:

  • 这真的是应该的样子吗? (这document.body.contains(myProxyElement) part)
  • 设置内部代理时设置视频元素抛出的值似乎很奇怪,这是一个错误吗? (第三点,也有点第二点,我想它是相连的)

奖励:游乐场

const video = document.querySelector('video');
const proxy = new Proxy(video, {
  get(target, key) {
    console.log(`Getting video.${typeof key === 'symbol'? key.toString() : key}`);
    const value = video[key];
    if (value instanceof Function) {
      return value.bind(video);
    } else {
      return value;
    }
  },
  set(target, key, value) {
    console.log(`Setting video.${typeof key === 'symbol'? key.toString() : key} =`, value);
    video[key] = value;
    return true;
  }
});

proxy.muted = true;
proxy.play();
proxy.controls = true;
try {
  console.log(document.body.contains(proxy));
} catch (e) {
  console.error('DOM operation failed', e);
}
video { max-width: 100%; }
<video src="//vjs.zencdn.net/v/oceans.mp4">

正如评论中已经提到的,Proxy对象不会自动转换为Node打电话时document.body.contains(proxy).

因此,您可以设置一个将返回代理目标的特定键:

const video = document.querySelector('video');
const proxy = new Proxy(video, {
    get(target, key) {
        const value = video[key];
        if (value instanceof Function) {
            return value.bind(video);
        } else if (key == 'target') {
            return target;
        } else {
            return value;
        }
    },
    set(target, key, value) {
        target[key] = value;
        return true;
    }
});

然后你可以这样做:

console.log(document.body.contains(proxy.target));

Edit:

这真的是应该的样子吗? (这 document.body.contains(myProxyElement) 部分):

是的,我没有看到任何其他方法可以做到这一点。

设置内部代理时设置视频元素抛出的值 看起来很奇怪,这是一个错误吗? (第三点,也有点第二点,我想是的 已连接):

由于我无法重现这个问题,所以很难说。也许尝试更换new Proxy(video, ... with new Proxy({}, ...然后将视频设置为proxy.video = video(您还必须更新中的逻辑get and set)看看它的表现如何?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代理 HTML 元素 的相关文章

随机推荐