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

Vanilla JS重复请求API致功能仅生效一次的问题咨询与优化

Hey there! Let's fix both of your issues with a revised Vanilla JS implementation that's more efficient and robust:

Revised Code

// Cache the API data once globally
let cachedDesigns = null;

// Initialize the app by fetching data first
function initApp() {
  const xhr = new XMLHttpRequest();
  xhr.open("GET", 'http://www.pat-cooney.com/gd.json', true);
  xhr.onload = function() {
    if (this.status === 200) {
      cachedDesigns = JSON.parse(this.responseText);
      // Load initial content once data is ready
      loadDesigns(0);
      // Set up event listeners after content is rendered
      setupGalleryListeners();
    }
  };
  xhr.send();
}

// Load content using cached data (no repeated API calls)
function loadDesigns(index) {
  if (!cachedDesigns) return; // Exit if data isn't loaded yet

  let contentImages = `<img src="${cachedDesigns[index].images[0]}">`;
  let galleryNavOutput = "";

  // Generate navigation images with data attributes instead of duplicate IDs
  for (let i = 0; i < 3; i++) {
    galleryNavOutput += `<img class="gallery-nav-item" data-index="${i}" src="${cachedDesigns[i].thumbnail}">`;
  }

  // Update the DOM with new content
  document.getElementById("inner").innerHTML = contentImages;
  document.getElementById("center").innerHTML = galleryNavOutput;
}

// Use event delegation to handle navigation clicks (works even when elements re-render)
function setupGalleryListeners() {
  const galleryContainer = document.getElementById("center");
  galleryContainer.addEventListener("click", function(e) {
    const target = e.target;
    // Check if we clicked on a navigation image
    if (target.classList.contains("gallery-nav-item")) {
      const index = parseInt(target.dataset.index);
      // Add small delay for UX feel
      setTimeout(() => loadDesigns(index), 300);
    }
  });
}

// Start the app
initApp();

1. Why & How We Fixed Repeated API Requests

Your original code called the API every time loadDesigns ran—this is inefficient, especially for a small static JSON file. Here's what changed:

  • We moved the AJAX request to an initApp function that runs once when the page loads
  • We store the fetched designs data in a global cachedDesigns variable
  • The loadDesigns function now uses this cached data instead of making new requests every time you click a navigation item

This way, we only hit the API once, and reuse the data for all subsequent content switches.

2. Fixing the One-Time Click Issue (ID Conflicts & Event Binding)

The main problem here was duplicate IDs and lost event listeners:

  • Duplicate IDs: Your original code generated elements with IDs like one, two, three every time loadDesigns ran. HTML requires IDs to be unique on a page, so this caused DOM inconsistencies. We replaced these with a shared class (gallery-nav-item) and a data-index attribute to track which item corresponds to which content.
  • Lost Event Listeners: You bound click events to the first set of navigation images, but when you re-rendered the navigation, the new elements didn't have those listeners. We fixed this with event delegation: we bind the click event to the parent container (#center) instead of individual images. Since events bubble up, the parent can catch clicks on any child navigation image—even new ones that get rendered later.

We also simplified the timeout logic to avoid nested delays that could cause timing issues.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:39:02