代理HTMLElement [英] Proxy HTMLElement

查看:60
本文介绍了代理HTMLElement的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检查库对传递给它的视频元素有什么作用,所以我天真地做到了:

I wanted to check what does a library do with video element I pass to it so I naively did this:

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];
    }
});

但是我遇到了一个错误:

But I got an error:

TypeError:无法在节点"上执行包含":参数1的类型不是节点".

TypeError: Failed to execute 'contains' on 'Node': parameter 1 is not of type 'Node'.

有没有办法使这项工作成功?

Is there a way to make this work?

我已经了解了一些知识,并以此将我的代理更新为休假:

I have gained some knowledge, with it I updated my proxy as fallow:

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;
    }
});

这是用于调试的,因此我编辑了编译后的代码,并用 element .___ element ___ 替换了所有DOM操作参考.

It is meant for debugging, so I edited the compiled code and replaced all DOM manipulation references with element.___element___.

接下来,我发现通过代理调用函数似乎存在问题,因此我添加了 .bind(video)部分.

Next I found out that there seem to be problems with calling functions trough proxy, so I added the .bind(video) part.

最后设置值被抛出.因此,我不得不用直接视频参考替换目标(事实上,我肯定用视频替换了所有目标参考),这使它起作用了……我不确定为什么或如何,但是确实如此.

And finally setting values was throwing. So I had to replace target with direct video reference (as matter of fact, I replaced all target references with video, just to be sure), that made it work... I am not sure why or how, but it did.

问题是:

  • 这真的应该是吗?( 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);
}

video { max-width: 100%; }

<video src="//vjs.zencdn.net/v/oceans.mp4">

>

推荐答案

如注释中所述,调用时, Proxy 对象不会自动转换为 Node document.body.contains(proxy).

As already mentioned in the comments, the Proxy object will not get automatically casted into Node when calling document.body.contains(proxy).

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

Therefore, you can i.e. set a specific key that will return the proxy's target:

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;
    }
});

然后您可以执行以下操作:

And then you can do:

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

修改:

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

Is this really how it is supposed to be? (the document.body.contains(myProxyElement) part):

是的,我看不到其他方法.

Yes, I do not see any other way how to do this.

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

Setting values to video element throwing when setting inside proxy seemed weird, is it a bug? (3rd point, kinda second too, I suppose it is connected):

由于我无法重现此问题,因此很难说.也许尝试用 new Proxy({},... 替换 new Proxy(video,... ),然后将视频设置为 proxy.video = video(您还必须更新 get set 中的逻辑)并查看其行为方式?

Since I am not able to reproduce this issue, it is hard to say. Maybe try to replace new Proxy(video, ... with new Proxy({}, ... and then set the video as proxy.video = video (you will have to also update the logic in the get and set) and see how that behaves?

这篇关于代理HTMLElement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆