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

如何通过JavaScript点击事件获取JSON中对应产品的详细信息

基于Fetch实现产品详情点击获取功能

我已经掌握了用Fetch从JSON文件获取数据的基础方法,能展示包含产品图片、名称和「Show Detail」按钮的产品卡片,但不清楚如何通过点击图片或按钮,获取对应产品的id、name、image、url、brand、jenis、deskripsi等详细信息,希望学习对应的Fetch实现方案。

现有JSON数据结构

{
  "products": [
    {
      "id": "11",
      "name": "panda",
      "brand": "blue",
      "jenis": "cool panda",
      "deskripsi": "cute panda",
      "image": "a8205ca774a533e0053e6fe969443510.jpg",
      "url": "http://localhost:5000/images/a8205ca774a533e0053e6fe969443510.jpg",
      "createdAt": "2024-11-28 03:34:22",
      "updatedAt": "2024-11-29 06:37:36"
    },
    {
      "id": "13",
      "name": "fox",
      "brand": "crowd",
      "jenis": "fox samurai",
      "deskripsi": "strongest samurai",
      "image": "c87dcede772ef2d0fbdd5ceb65237937.jpg",
      "url": "http://localhost:5000/images/c87dcede772ef2d0fbdd5ceb65237937.jpg",
      "createdAt": "2024-11-28 14:12:39",
      "updatedAt": "2024-11-29 06:39:41"
    },
    {
      "id": "14",
      "name": "panda",
      "brand": "digital",
      "jenis": "samurai",
      "deskripsi": "its panda samurai",
      "image": "167748215ed489e0f363d5be562026dd.jpg",
      "url": "http://localhost:5000/images/167748215ed489e0f363d5be562026dd.jpg",
      "createdAt": "2024-11-29 03:39:16",
      "updatedAt": "2024-11-29 06:38:10"
    }
  ]
}

现有JavaScript代码

const data        = "../php/data.json";
const jenisList   = document.querySelector('.content');
var urlParams     = new URLSearchParams(window.location.search);
var jenis         = urlParams.get("jenis");
const modalDetail = document.querySelectorAll('.btn-primary');

const getProducts = () => {
  fetch(data)
    .then(response => {
      return response.json();
    }).then(responseJson => {
      if (jenis == null) {
        showProduct(responseJson.products);
      } else {
        jenisProduct(responseJson.products);
      }
    }).catch(error => {
      console.log(error);
    });
}

const showProduct = product => {
  jenisList.innerHTML = '';
  product.forEach(agen => {
    jenisList.innerHTML +=
      `<div class="product-list">
            <div class="flex-div">
            <a href="" class="foto-product"><img src="${agen.url}" class="product-img"></a>
                <div class="product-info">
                    <p>${agen.name}</p>
                </div>
                <a href="#" class="btn-primary" data-toggle="modal" 
                data-target="#movieDetailModal" data-imdbid="${agen.id}">Show Detail</a>
            </div>
        </div>`
  });
}

const jenisProduct = product => {
  jenisList.innerHTML = '';
  product.forEach(agen => {
    if (agen.jenis === jenis) {
      jenisList.innerHTML +=
        `<div class="product-list">
            <div class="flex-div">
            <a href="" class="foto-product"><img src="${agen.url}" class="product-img"></a>
                <div class="product-info">
                    <p>${agen.name}</p>
                </div>
                <a href="${agen.id}" class="btn btn-primary modal-detail-button" data-toggle="modal" 
                data-target="#movieDetailModal" data-imdbid="${agen.id}">Show Detail</a> 
            </div>
        </div>`
    }
  });
}

document.addEventListener('DOMContentLoaded', getProducts);

解决方案实现步骤

1. 存储全局产品数据

避免重复请求JSON文件,先把获取到的产品数据存在全局变量中,后续点击时直接从变量中查找:

// 新增全局变量存储所有产品数据
let allProducts = [];

在getProducts函数中更新数据存储:

const getProducts = () => {
  fetch(data)
    .then(response => response.json())
    .then(responseJson => {
      // 把产品数据存入全局变量
      allProducts = responseJson.products;
      if (jenis == null) {
        showProduct(allProducts);
      } else {
        jenisProduct(allProducts);
      }
    }).catch(error => console.log(error));
}

2. 添加事件委托处理点击

因为产品卡片是动态生成的,不能直接给单个图片/按钮绑定事件,需要给父容器jenisList添加事件委托:

// 新增点击事件委托,处理图片和按钮的点击
jenisList.addEventListener('click', function(e) {
  e.preventDefault(); // 阻止a标签默认跳转行为
  
  // 判断点击的是图片容器还是详情按钮
  let target = e.target;
  let productId = null;
  
  // 点击图片时,找到对应的产品id
  if (target.classList.contains('product-img')) {
    productId = target.closest('.product-list').querySelector('.btn-primary').dataset.imdbid;
  } 
  // 点击详情按钮时,直接获取id
  else if (target.classList.contains('btn-primary')) {
    productId = target.dataset.imdbid;
  }
  
  // 如果拿到了产品id,获取详情并展示
  if (productId) {
    getProductDetail(productId);
  }
});

3. 获取并展示产品详情

实现getProductDetail函数,从全局变量中找到对应产品,然后填充到模态框(假设你已经有#movieDetailModal模态框,里面有对应元素展示详情):

const getProductDetail = (productId) => {
  // 根据id找到对应产品
  const product = allProducts.find(item => item.id === productId);
  
  if (product) {
    // 假设模态框内有如下元素,根据实际结构调整
    document.querySelector('#modal-product-name').textContent = product.name;
    document.querySelector('#modal-product-brand').textContent = product.brand;
    document.querySelector('#modal-product-jenis').textContent = product.jenis;
    document.querySelector('#modal-product-deskripsi').textContent = product.deskripsi;
    document.querySelector('#modal-product-image').src = product.url;
    
    // 如果用Bootstrap模态框,手动触发显示(可选)
    $('#movieDetailModal').modal('show');
  }
}

4. 优化现有生成卡片的代码

统一两个生成卡片函数的按钮和图片标签,避免不一致:
比如在showProduct和jenisProduct中,把图片的a标签href设为#,防止跳转:

<a href="#" class="foto-product"><img src="${agen.url}" class="product-img"></a>

完整修改后的代码

const data        = "../php/data.json";
const jenisList   = document.querySelector('.content');
var urlParams     = new URLSearchParams(window.location.search);
var jenis         = urlParams.get("jenis");
let allProducts = []; // 全局存储产品数据

const getProducts = () => {
  fetch(data)
    .then(response => response.json())
    .then(responseJson => {
      allProducts = responseJson.products;
      if (jenis == null) {
        showProduct(allProducts);
      } else {
        jenisProduct(allProducts);
      }
    }).catch(error => console.log(error));
}

const showProduct = product => {
  jenisList.innerHTML = '';
  product.forEach(agen => {
    jenisList.innerHTML +=
      `<div class="product-list">
            <div class="flex-div">
            <a href="#" class="foto-product"><img src="${agen.url}" class="product-img"></a>
                <div class="product-info">
                    <p>${agen.name}</p>
                </div>
                <a href="#" class="btn-primary" data-toggle="modal" 
                data-target="#movieDetailModal" data-imdbid="${agen.id}">Show Detail</a>
            </div>
        </div>`
  });
}

const jenisProduct = product => {
  jenisList.innerHTML = '';
  product.forEach(agen => {
    if (agen.jenis === jenis) {
      jenisList.innerHTML +=
        `<div class="product-list">
            <div class="flex-div">
            <a href="#" class="foto-product"><img src="${agen.url}" class="product-img"></a>
                <div class="product-info">
                    <p>${agen.name}</p>
                </div>
                <a href="#" class="btn btn-primary modal-detail-button" data-toggle="modal" 
                data-target="#movieDetailModal" data-imdbid="${agen.id}">Show Detail</a> 
            </div>
        </div>`
    }
  });
}

// 处理产品卡片的点击事件
jenisList.addEventListener('click', function(e) {
  e.preventDefault();
  
  let productId = null;
  const target = e.target;
  
  // 判断点击的是图片还是按钮
  if (target.classList.contains('product-img')) {
    productId = target.closest('.product-list').querySelector('.btn-primary').dataset.imdbid;
  } else if (target.classList.contains('btn-primary')) {
    productId = target.dataset.imdbid;
  }
  
  if (productId) {
    getProductDetail(productId);
  }
});

// 获取并填充产品详情到模态框
const getProductDetail = (productId) => {
  const product = allProducts.find(item => item.id === productId);
  
  if (product) {
    // 替换为你模态框中实际的元素选择器
    document.querySelector('#modal-product-name').textContent = product.name;
    document.querySelector('#modal-product-brand').textContent = `品牌:${product.brand}`;
    document.querySelector('#modal-product-jenis').textContent = `类型:${product.jenis}`;
    document.querySelector('#modal-product-deskripsi').textContent = `描述:${product.deskripsi}`;
    document.querySelector('#modal-product-image').src = product.url;
    
    // 显示模态框(如果用Bootstrap)
    $('#movieDetailModal').modal('show');
  }
}

document.addEventListener('DOMContentLoaded', getProducts);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:42:31