Akx*_*kxe 5 javascript proxy html5-video
我想检查一下库对我传递给它的视频元素做了什么,所以我天真地做了这个:
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];
}
});
Run Code Online (Sandbox Code Playgroud)
但是我收到了一个错误:
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;
}
});
Run Code Online (Sandbox Code Playgroud)
它用于调试,因此我编辑了编译的代码并用element.___element___.替换了所有DOM操作引用.
接下来我发现通过代理调用函数似乎有问题,所以我添加了.bind(video)部分.
最后设定价值是投掷.所以我不得不用直接视频参考替换目标(事实上,我用视频替换了所有目标参考,只是为了确定),这使它工作......我不知道为什么或如何,但确实如此.
问题是:
document.body.contains(myProxyElement)部分)奖金:游乐场
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);
}Run Code Online (Sandbox Code Playgroud)
video { max-width: 100%; }Run Code Online (Sandbox Code Playgroud)
<video src="//vjs.zencdn.net/v/oceans.mp4">Run Code Online (Sandbox Code Playgroud)
正如评论中已经提到的,调用 时该Proxy对象不会自动转换为.Nodedocument.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;
}
});
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
console.log(document.body.contains(proxy.target));
Run Code Online (Sandbox Code Playgroud)
编辑:
这真的是应该的样子吗?(document.body.contains(myProxyElement) 部分):
是的,我没有看到任何其他方法可以做到这一点。
设置内部代理时设置视频元素抛出的值似乎很奇怪,这是一个错误吗?(第三点,也有点第二点,我想它是相连的):
由于我无法重现这个问题,所以很难说。也许尝试替换new Proxy(video, ...为new Proxy({}, ...,然后将视频设置为proxy.video = video(您还必须更新 和 中的逻辑get)set并查看其行为如何?