为什么使用 cloneNode() 创建多个音频文件会阻止我控制音频源的属性,以及我如何覆盖它



我已经制作网页游戏一段时间了,我很快注意到,一旦我使用.cloneNode(true)多次播放相同的音频文件,以避免每次我想播放音频文件时一遍又一遍地重新下载文件,我失去了对播放音量和播放速率等内容的控制, 有谁知道我如何重新控制音频文件每个副本的这些参数?

我尝试为原始文件中的音频副本设置参数,但没有果汁

In the HTML : 
<audio src = "sight.wav" id="sight"/>
<button onclick="playSound()">Play some audio</audio>
In the Js
var get = new Function("id", "return document.getElementById(id)");
function playSound()
{
get(sight).volume = 0.30;
get(sight).playbackRate = 0.40;
get(sight).cloneNode(true).play();
};

对我来说看起来像是有效的代码,但就像我说的,没有果汁,cloneNode 完全忽略音量和播放设置,只播放普通音频。我该怎么办?

Node.cloneNode()在元素上调用时,将创建一个具有与原始节点相同的属性的相同子类型的新元素。

在这里,您不是在修改原始attributes,而只是修改一些未反映并因此未克隆的 IDL 属性。

const original = document.querySelector("audio");
console.log( "default", [...original.attributes].map( (att) => att.name ) ); // []
original.volume = 0.2;
console.log( "volume set", [...original.attributes].map( (att) => att.name ) ); // []
original.controls = true;
console.log( "controls set", [...original.attributes].map( (att) => att.name ) ); // [ "controls" ]
const clone = original.cloneNode();
console.log( "clone volume", clone.volume ); // 1
console.log( "clone controls", clone.controls ); // true
<audio></audio>

因此,您可以重写代码,以便设置克隆元素的volumeplayBackRate,而不是设置原始节点的,但请注意,如果您真的要生成几个相同的音频,则应使用 Web-Audio API 及其 AudioBuffer 接口,这些接口可以更好地控制这些媒体的播放时间, 这将比初始化 DOM MediaElements 占用更少的内存。

最新更新