首页 > 解决方案 > 在用户脚本中编辑音频元素音量

问题描述

我正在编写一个用户脚本来尝试减少过于响亮的音频元素。如何访问已创建但未放置在任何 DOM 中的音频元素?

在网站本身上,它类似于:

function () {
    var audioElement = document.createElement('audio');
    audioElement.setAttribute('src', 'http://www.example.com/sound.mp3');

    callbackFn = function() {
        audioElement.volume = way_too_high;
        audioElement.load();
        audioElement.play();
    };

    //...
}();

在我的用户脚本中,我想做类似的事情

function () {
    newCallbackFunction = function() {
        var audioElement = document.querySelector('audio'); // doesn't work, presumably because never added to DOM
        audioElement.volume = 0.1 * audioElement.volume;
        audioElement.load();
        audioElement.play();
    };

    // ...
}();

不过,我似乎无法访问它。我真的不明白这些对象住在哪里。如果它们不在 DOM 中,如何播放它们?它们似乎存在于文档中的某个地方,因为它们可以播放,但对我来说如何找到它们并不明显。

标签: javascripthtml5-audiouserscripts

解决方案


因为callbackFn是异步调用的,所以您可以更改HTMLMediaElement.prototype其属性的设置器volume,以便更改src您感兴趣的元素上的音量将导致调用原始设置器的音量为原来的 1/10默认调用:

const { prototype } = HTMLMediaElement;
const { set: setter, get: getter } = Object.getOwnPropertyDescriptor(prototype, 'volume');
Object.defineProperty(prototype, 'volume', {
  get() {
    return getter.call(this);
  },
  set(arg) {
    const newArg = this.src.endsWith('/sounds/warframe_alarm.mp3')
    ? arg / 10
    : arg;
    setter.call(this, newArg);
  }
});

当然,请注意,这只是当您无法更改页面的现有 JS(例如使用用户脚本)时的一种技巧。

我正在寻找一种方法来访问网页中存在但尚未添加到 DOM 的音频元素

很确定,做这样的事情的唯一方法是使用像覆盖document.createElement在使用运行的页面代码之前运行的代码这样的黑客攻击createElement


推荐阅读