用自定义逻辑将htmlvideoelement上的属性覆盖为getter/setter



我想完成的工作:

我正在尝试编写Chrome的扩展名,该扩展名为YouTube添加了一些额外的功能。这个特殊的问题与知道用户何时更改播放率有关(可以通过单击设置图标,然后加快速度来完成。

(。

我尝试做的事情:

我试图通过用getter/setter对象替换htmlvideolement上的" ploplackrate"属性来做到这一点。

我可以检测到。

问题:

当用户更改它时,我所有的逻辑都运行,但是视频将不再实际改变速度。

代码:

    let videoObj = document.getElementsByTagName('video')[0];
    let storePlaybackRate = videoObj.playbackRate;
    Object.defineProperty(videoObj,'playbackRate',{
        get(){return storePlaybackRate;},
        set(val){
            storePlaybackRate = val;
            console.log("Updated Value: ",val);
            //Custom Logic that does work.
            return val;
        }
    });

在任何YouTube视频上将代码粘贴到控制台中,然后更改播放速度。Console.Log发生了,但是视频不再改变速度。

我已经检查过的东西

1.此属性已经不是我要覆盖的getter/setter对象。这是通过:

检查的
Object.getOwnPropertyDescriptor(videoObj, 'playbackRate');

2.我以为可能是因为我没有返回设置器中的新值,但不是。

最终摘要

我知道还有其他方法可以做我要做的事情,因此,如果通过这种方法是不可能的,那就很好。但是我真的很想理解为什么这不起作用。或者如果我犯了一个错误。

谢谢。

您正在覆盖继承的getter/setter。

HTMLVIDEOELENT没有其自己的Getter/setter用于ploplackrate,而是从htmlmediaelement.protype继承一个。这就是为什么Object.getOwnPropertyDescriptor(video,'playbackRate')返回undefined

要覆盖它,您必须存储原始描述符,并将其称为您自己的描述符。

originalDescriptor = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'playbackRate');
Object.defineProperty(HTMLVideoElement.prototype,'playbackRate',{
    set:function(value){
        originalDescriptor.set.call(this,value);
        console.log('value changed',value);
    },
    get:originalDescriptor.get
});

我在此示例中使用了视频的原型,可以通过用视频元素的参考替换HTMLVideoElement.prototype来调整特定元素的描述符。

最新更新