You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JS数组存储游戏名与URL 修复按钮首次点击加载失效问题

网页游戏列表加载功能修复与实现方案

一、游戏信息数组结构实现

使用对象数组存储游戏元信息是可维护性最高的方案,无需把URL硬编码在按钮id属性中,后续增删游戏只需要修改数组即可,不需要编写重复的HTML标签。

  • 基础数组结构:整个游戏列表用[]包裹为数组,每个数组项是{}格式的对象,分别用两个字段存储游戏名和加载地址
// 游戏列表数组,新增游戏直接按格式追加数组项即可
const gameList = [
  {
    name: "Run 3",
    url: "https://theadvancedsociety-tam.tbt.mx/tam-run3/"
  },
  {
    name: "Slope Game",
    url: "https://bigfoot9999.github.io/Slope-Game/"
  }
]

如果需要按游戏分类管理,可以扩展数组结构,给每个分类建单独项,嵌套存储对应分类下的游戏,后续优化版代码会提供对应实现。

二、现有交互bug根因与修复

问题根因

你遇到的两个交互异常来自三处逻辑错误:

  • 首次点击无响应:点击按钮触发reply_click时,仅为页面第一个按钮绑定了二次点击的onclick事件,没有执行任何加载逻辑,必须点击第二次才会触发加载动作。
  • 按钮加载地址不匹配:document.querySelector('button')只会匹配页面中排在最前面的第一个按钮,无论点击哪个按钮,事件绑定、样式修改操作都只会作用在第一个按钮上;同时存储弹窗引用的win变量定义在函数内部,多次点击会生成多个独立的弹窗引用,加上闭包缓存的url值,最终出现点击按钮和加载地址不对应的问题。
  • 样式无效:代码中写的背景色值#00000是无效十六进制色值,少一位字符,正确纯黑色值为#000000。

最小修复版本(保留原有手写HTML结构)

只需要修改JS逻辑和HTML内的事件传参,不需要重构现有页面结构:

  1. 修改为以下JS代码:
// 全局存储弹窗引用,所有按钮共用同一个弹窗实例
let gameWindow = null;

function reply_click(activeBtn) {
  const targetUrl = activeBtn.id;
  if (!targetUrl) return;

  if (gameWindow && !gameWindow.closed) {
    // 已打开弹窗则直接聚焦,替换iframe加载地址
    gameWindow.focus();
    const gameIframe = gameWindow.document.querySelector('iframe');
    if (gameIframe) gameIframe.src = targetUrl;
  } else {
    // 未打开弹窗则新建窗口,注入iframe
    gameWindow = window.open();
    gameWindow.document.body.style.margin = '0';
    gameWindow.document.body.style.height = '100vh';
    const gameIframe = gameWindow.document.createElement('iframe');
    gameIframe.style.border = 'none';
    gameIframe.style.width = '100%';
    gameIframe.style.height = '100%';
    gameIframe.style.margin = '0';
    gameIframe.src = targetUrl;
    gameWindow.document.body.appendChild(gameIframe);
  }
  // 仅修改当前点击按钮的样式
  activeBtn.style.background = '#000000';
  activeBtn.style.color = '#ffffff';
}
  1. 修改HTML内的按钮事件传参,把this.id改为直接传入按钮DOM对象this:
<div class="gameslist">
  <h1>Action Games</h1>
  <button id="https://theadvancedsociety-tam.tbt.mx/tam-run3/" onClick="reply_click(this)">Run 3</button><br>
  <button id="https://bigfoot9999.github.io/Slope-Game/" onClick="reply_click(this)">Slope Game</button><br>
  <h1>Puzzle & Strategy Games</h1>
  <h1>Skill Games</h1>
  <h1>Retro</h1>
  <h1>Shooter Games</h1>
  <h1>Other</h1>
</div>

优化版本(配合数组自动渲染列表)

基于前面提到的数组结构,实现自动渲染全部分类和游戏按钮,后续加游戏只需要改数组,不需要写HTML:

// 带分类的游戏列表数组
const gameList = [
  {
    category: "Action Games",
    games: [
      { name: "Run 3", url: "https://theadvancedsociety-tam.tbt.mx/tam-run3/" },
      { name: "Slope Game", url: "https://bigfoot9999.github.io/Slope-Game/" }
    ]
  },
  { category: "Puzzle & Strategy Games", games: [] },
  { category: "Skill Games", games: [] },
  { category: "Retro", games: [] },
  { category: "Shooter Games", games: [] },
  { category: "Other", games: [] }
]

let gameWindow = null;

// 页面加载完成后自动渲染所有游戏列表
window.addEventListener('load', () => {
  const listContainer = document.querySelector('.gameslist');
  gameList.forEach(categoryItem => {
    // 渲染分类标题
    const title = document.createElement('h1');
    title.textContent = categoryItem.category;
    listContainer.appendChild(title);
    // 渲染分类下的所有游戏按钮
    categoryItem.games.forEach(gameItem => {
      const btn = document.createElement('button');
      btn.textContent = gameItem.name;
      btn.dataset.url = gameItem.url;
      // 绑定按钮点击事件
      btn.addEventListener('click', function() {
        const targetUrl = this.dataset.url;
        if (gameWindow && !gameWindow.closed) {
          gameWindow.focus();
          gameWindow.document.querySelector('iframe').src = targetUrl;
        } else {
          gameWindow = window.open();
          gameWindow.document.body.style.margin = '0';
          gameWindow.document.body.style.height = '100vh';
          const gameIframe = gameWindow.document.createElement('iframe');
          gameIframe.style.border = 'none';
          gameIframe.style.width = '100%';
          gameIframe.style.height = '100%';
          gameIframe.src = targetUrl;
          gameWindow.document.body.appendChild(gameIframe);
        }
        this.style.background = '#000000';
        this.style.color = '#ffffff';
      })
      listContainer.appendChild(btn);
      listContainer.appendChild(document.createElement('br'));
    })
  })
})

对应HTML只需要保留列表容器即可:

<div class="gameslist"></div>

内容的提问来源于stack exchange,提问作者Bigfoot9999

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 21:03:20