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

点击切换游戏信息需多次点击的问题及jQuery搜索适配求助

问题:点击游戏名称切换详情需多次点击生效

我通过fetch获取游戏JSON数据,动态创建DOM结构实现点击游戏名称显示/隐藏详情,但现在需要多次点击才生效,同时还遇到搜索功能适配的问题,以下是相关代码和解决方案:

一、初始代码与问题分析

1. 动态创建DOM的JS代码

fetch("thething.json")
.then(res => res.json())
.then(data =>{
games = data.map(game => {
const newDiv = document.createElement("div");
newDiv.className = "game-info";
newDiv.innerHTML = `
<p onclick="toggler();">${game.Name}</p>
<div class="info">
<img src="${game.Thumbnail}">
<p>${game.Description}</p>
</div>
`;
document.body.appendChild(newDiv);
return {name: game.Name, element: newDiv}
})
})

2. JSON数据结构

[
  {
    "Name": "gamename1",
    "Thumbnail": "https://imglocation",
    "Description": "This game is indeed a game"
  },
  {
    "Name": "gamename2",
    "Thumbnail": "https://imglocation2",
    "Description": "This game2 is indeed a game2"
  }
]

3. 切换函数代码

function toggler(){
    $('div.game-info').click(function(e){
        $(this).children('.info').toggle();
    });
}

问题根源

每次点击游戏名称的<p>标签时,都会执行toggler()函数,而这个函数又会给所有.game-info元素重复绑定点击事件。第一次点击只是完成事件绑定,第二次点击才会触发切换逻辑,所以需要多次点击才生效。另外直接绑定全局.game-info事件时,容易出现触发所有游戏详情的问题。

二、点击切换问题的解决方案

方案1:原生JS直接绑定单元素事件

修改动态创建DOM的逻辑,给每个游戏名称标签单独绑定点击事件,精准定位当前项的详情:

fetch("thething.json")
.then(res => res.json())
.then(data =>{
games = data.map(game => {
const newDiv = document.createElement("div");
newDiv.className = "game-info";

// 创建名称标签并绑定事件
const nameP = document.createElement("p");
nameP.textContent = game.Name;
nameP.addEventListener('click', () => {
    infoDiv.classList.toggle('hidden');
});

// 创建详情区域
const infoDiv = document.createElement("div");
infoDiv.className = "info";
infoDiv.innerHTML = `
<img src="${game.Thumbnail}">
<p>${game.Description}</p>
`;

// 组装元素并插入页面
newDiv.appendChild(nameP);
newDiv.appendChild(infoDiv);
document.body.appendChild(newDiv);
return {name: game.Name, element: newDiv}
})
})

需要搭配CSS隐藏类:

.info.hidden {
    display: none;
}

方案2:jQuery事件委托(更简洁)

移除动态DOM里的onclick属性,改用全局事件委托,避免重复绑定:

// 修改动态创建时的innerHTML部分,去掉onclick
newDiv.innerHTML = `
<p class="toggle-name">${game.Name}</p>
<div class="info">
<img src="${game.Thumbnail}">
<p>${game.Description}</p>
</div>
`;

// 在全局范围内绑定事件委托(放在fetch外部)
$(document).on('click', '.toggle-name', function(){
    $(this).siblings('.info').toggle();
});

这种方式只会绑定一次全局事件,点击时直接定位到当前项的详情区域,无需多次点击。

三、搜索功能适配问题与解决方案

原原生JS搜索代码

searchInput.addEventListener("input", e=>{
    const value = e.target.value.toLowerCase()
    games.forEach(game =>{
        const isVisible = game.Name.toLowerCase().includes(value)
        game.element.classList.toggle("hide", !isVisible)
    });
})

该代码依赖map返回的{name: game.Name, element: newDiv}数组,通过数组项控制对应DOM的显示隐藏。

适配jQuery的解决方案

方案1:沿用原games数组逻辑

既保留之前的数组结构,又用jQuery实现搜索:

const searchInput = document.querySelector("[data-search]")
$(searchInput).on("keyup", function(){
    const value = $(this).val().toLowerCase();
    games.forEach(game => {
        const isVisible = game.name.toLowerCase().includes(value);
        $(game.element).toggle(isVisible);
    });
});

方案2:直接通过DOM筛选(自行实现的版本)

const searchInput = document.querySelector("[data-search]")
$(searchInput).on("keyup", function(){
    let value = $(this).val().toLowerCase();
    $(".game-info").filter(function(){
        const gameName = $(this).find('.toggle-name').text().toLowerCase();
        $(this).toggle(gameName.indexOf(value) > -1);
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 19:53:19