JS新手求助:如何用fetch加载静态JSON文件替代数组?
Hey there! Let's break down what's going wrong with your code and fix it step by step — I know that stuck feeling when something just won't click, so let's get you sorted out.
First, let's address the critical bugs in your code
The biggest issue is how you're passing the hairdresser object to the page2 function via the onclick handler. When you use JSON.stringify(hairdresser), it creates a string with double quotes, which clashes with the double quotes in your HTML's onclick attribute. This breaks the JavaScript code that runs when the link is clicked.
There's also a small syntax error in your page2 function: you're closing a <p> tag without ever opening one, which creates invalid HTML.
Next, verify your fetch path
Double-check that the path to your data.json file is correct. If your HTML file is in the same folder as the JSON file, use ./data.json or just data.json — the placeholder /path/to/data.json needs to be replaced with the actual relative path to your file.
Here's the fully fixed code
Updated JavaScript:
// Loop through all properties to display info on page 2 let page2 = (hairdresser) => { let singleView = "<div>"; for (const prop in hairdresser) { if (hairdresser.hasOwnProperty(prop)) { // Fix: Add opening <p> tag to match the closing one singleView += `<p>${hairdresser[prop]}</p>`; } } singleView += "</div>"; document.body.innerHTML = singleView; }; // handleData function for page 1 let handleData = (hairdressers) => { let out = "<table>"; // Add table headers for better readability out += "<tr><th>Time</th><th>Name</th><th>Price</th><th>Time Estimate</th><th>Rating</th><th>Address</th></tr>"; hairdressers.forEach((hairdresser) => { out += "<tr>"; const printableProps = ["time", "name", "price", "timeEst", "rating", "adress"]; printableProps.forEach(prop => { if (hairdresser.hasOwnProperty(prop)) { if (prop === "name") { // Fix: Use a data attribute instead of inline onclick to avoid quote conflicts out += `<td><a href="#" class="hairdresser-link" data-hairdresser='${JSON.stringify(hairdresser)}'>${hairdresser[prop]}</a></td>`; } else { out += `<td>${hairdresser[prop]}</td>`; } } }); out += "</tr>"; }); out += "</table>"; document.body.innerHTML = out; // Add click event listeners to all name links AFTER rendering the table document.querySelectorAll(".hairdresser-link").forEach(link => { link.addEventListener("click", (e) => { e.preventDefault(); // Stop the default link navigation behavior const hairdresser = JSON.parse(link.dataset.hairdresser); page2(hairdresser); }); }); }; // Fix: Use the correct relative path to your data.json file fetch("./data.json") .then(res => { // Add error handling to catch fetch failures if (!res.ok) { throw new Error(`Failed to load data: HTTP status ${res.status}`); } return res.json(); }) .then(handleData) .catch(err => console.error("Error:", err));
Key changes explained:
- Replaced inline onclick with event listeners: Instead of injecting stringified JSON into an onclick attribute (which causes quote clashes), we store the JSON in a
data-hairdresserattribute (using single quotes to avoid conflicts). After rendering the table, we add click listeners to parse the JSON and callpage2. - Fixed invalid HTML in page2: Added the missing opening
<p>tag to make the output valid. - Added table headers: Makes the table easier to read and navigate.
- Added fetch error handling: Now you'll see clear errors in the browser console if the JSON file can't be loaded (e.g., wrong path), which simplifies debugging.
- Cleaned up code formatting: Added consistent indentation and line breaks to make the code easier to read and debug.
How to test this:
- Ensure your
data.jsonfile is in the same directory as your HTML file (or update the fetch path to match its location). - Open your HTML file in a browser, then open the developer tools (F12) to check the console for any errors. If the fetch fails, you'll get a message explaining why.
That should get your code working smoothly! Let me know if you hit any more snags.
内容的提问来源于stack exchange,提问作者user9705452

