使用自定义逻辑将HTMLVideoElement上的属性覆盖到getter / setter

时间:2018-02-09 05:08:44

标签: javascript youtube getter-setter

我想要完成的任务:

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

我试图做的事情:

我试图通过用getter / setter对象替换HTMLVideoElement上的“playbackRate”属性来做到这一点,以便我可以检测到这种情况发生的时间。

问题:

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

守则:

    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.我想也许是因为我没有在setter中返回新值,但那不是它。

最终摘要

我知道还有其他方法可以做我正在尝试做的事情,所以如果这种方法不可能,那就没问题了。但我真的很想知道为什么这不起作用。或者如果我犯了错误。

感谢。

1 个答案:

答案 0 :(得分:0)

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

HTMLVideoElement对于playbackRate没有自己的getter / setter,但是从HTMLMediaElement.prototype继承了一个。这就是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来调整特定元素的描述符。