在 JS 中动态更新一个变量

Dynamically Updating a Variable in JS

我的页面上有多个视频,我正在尝试通过 YouTube API 对所有视频启用搜索。这些视频是动态生成的,所以很遗憾,我不能一次预先定义它们。如果可以的话,以下方法可行:

<script>
function onYouTubePlayerAPIReady() {
      player = new YT.Player('ytplayer1', {
      });
      player2 = new YT.Player('ytplayer3', {
      });
      player3 = new YT.Player('ytplayer3', {
      });
      etc. etc.
}
function onPlayerReady(event) {
    event.target.playVideo();
}
function seek(sec){
    if(player){
        seconds += sec;
        player.seekTo(seconds, true);
    }
}

</script>

但是因为每个页面都有不同数量的动态生成的视频,所以我 运行 遇到了问题。

我可以使用以下代码制作第一个和最后一个视频:

#Initial javascript + first video
<script>
function onYouTubePlayerAPIReady() {
      player = new YT.Player('ytplayer1', {
      });
}
function onPlayerReady(event) {
    event.target.playVideo();
}
function seek(sec){
    if(player){
        seconds += sec;
        player.seekTo(seconds, true);
    }
}
var old_foo = onYouTubePlayerAPIReady;
</script>

<iframe id="ytplayer1" width="789" height="444" src="https://www.youtube.com/embed/p4vLPmVAwlo?enablejsapi=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<button type="button" onclick="player.seekTo(60)">60s</button>
<button type="button" onclick="player.seekTo(120)">120s</button>



#Second video plus the JS to go with it
<iframe id="ytplayer2" width="789" height="444" src="https://www.youtube.com/embed/_9ahu4c5zdI?enablejsapi=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<button type="button" onclick="player2.seekTo(60)">60s</button>
<button type="button" onclick="player2.seekTo(120)">120s</button>


<script>
function onYouTubePlayerAPIReady() {
  old_foo();
  player2 = new YT.Player('ytplayer2', {
  });
}

</script>

但是每当我尝试添加另一个时,中间的就停止工作了。似乎我对 onYouTubePlayerAPIReady 函数的最后一次调用覆盖了它之前的所有内容,而不是在每一步都执行该函数。我已尝试更新我的 old_foo 变量、onYouTubePlayerAPIReady 函数、定义新变量等。None 似乎有效!但我也很讨厌 javascript,所以我确定我只是漏掉了一些简单的东西。

帮忙?

onYouTubePlayerAPIReady() 函数会在播放器 API 代码加载后自动调用,因此您只需定义一次。在其中,您应该能够定义多个玩家。您的 JS 可以浓缩为以下内容:

<script>
    function onYouTubePlayerAPIReady() {
      player = new YT.Player('ytplayer1', {
      });
      player2 = new YT.Player('ytplayer2', {
      });
    }
</script>

使用 onYouTubeIframeAPIReady 而不是 onYouTubePlayerAPIReady 的工作 CodePen:https://codepen.io/edlucas/pen/wvKVVaP

另见:https://developers.google.com/youtube/iframe_api_reference

编辑

如果您需要动态创建标记并且仍然想在 API 准备就绪时加载它们,一种方法是将视频排入一个数组中,在 onYouTubePlayerAPIReady 时使用] 被调用。

var videos = ['ytplayer1', 'ytplayer2'];
var players = [];

function onYouTubeIframeAPIReady() {
    videos.forEach((video, i) =>
        players[i] = new YT.Player(video, {
            events: {
                'onReady': onPlayerReady,
            }
        });
   };
}

然后您可以使用您喜欢的方法将视频添加到数组中(例如 videos.push('ytplayer3')),只要您在 API 添加到页面之前或至少之前这样做准备好了。

以下是使用 seekTo 按钮动态添加 yt 播放器的方法

let players = [];
const button = document.querySelector("#button");
const newId = (() => {
  const prefix = "player";
  let id = 1;
  return () => {
    let newId = id;
    id = id + 1;

    return {
      id: newId,
      cssId: `${prefix}${newId}`
    }
  }
})()

const createButton = (text, clickEvent) => {
  const element = document.createElement("button");
  element.textContent = text;
  element.setAttribute("type", "button");
  element.addEventListener("click", clickEvent);
  return element;
}

const seekPlayer = (id, value) => {
  const player = players.find(pl => pl.id === id);
  player.seekTo(value);
}

const createPlayer = () => {
  const parent = document.body;
  const container = document.createElement("div");
  const playerPlaceholder = document.createElement("div");
  const result = newId();
  playerPlaceholder.setAttribute("id", result.cssId);

  const button1 = createButton('60s', () => seekPlayer(result.id, 60));
  const button2 = createButton('120s',() => seekPlayer(result.id, 120));
  container.appendChild(playerPlaceholder);
  container.appendChild(button1);
  container.appendChild(button2);

  parent.appendChild(container);

  const player = new YT.Player(result.cssId, {
    height: '100',
    width: '100',
    videoId: 'M7lc1UVf-VE',
    events: {
      'onReady': (event) => {

        players = [...players, {
          id: result.id,
          player: event.target
        }]
      },
    }
  });
}

button.addEventListener("click", () => {
  createPlayer();
})
<script src="https://www.youtube.com/iframe_api"></script>
<button id="button">Add player</button>