电影文件命名工具代码运行正常却报undefined TypeError求解决
Hey there! Let's troubleshoot those frustrating TypeError bugs you're hitting with your movie file naming tool—we can break this down and get it sorted out.
First, Let's Understand the Errors
Original Error:
Cannot read property 'token' of undefined
This means when you try to accessdata[i].token, thedata[i]value doesn’t exist. Either yournamingobject is missing entries for some separator+case combinations, or the array for a given combination has fewer than 20 items (so when you loop to index 19, there’s nothing there).Updated Error:
Cannot set property 'innerText' of undefined
Now you’re fixing the data check, but this new error tells us that one of your button elements isn’t being found. Either your selector for grabbing buttons is wrong, there aren’t exactly 20 buttons on the page, or your loop is running beyond the number of existing buttons.
Step-by-Step Solutions
1. Validate Your naming Object Structure
First, double-check that every combination of separator and case option has an array with exactly 20 items, each with a token and example property. You can test this quickly in the browser console:
// Replace with your actual separator/case values console.log(naming['space']['default'].length); // Should log 20 console.log(naming['dot']['uppercase'][19]); // Should log an object with token/example
If any combination is missing items or has the wrong structure, fill in the gaps or correct the object keys to match your select’s value attributes (e.g., make sure your select’s option value for "space" matches the key in naming exactly—no typos or case mismatches!).
2. Fix Button Selection & Loop Boundaries
Instead of hardcoding a loop to 20, dynamically match the number of buttons and available data to avoid out-of-bounds errors. Here’s a revised version of your update function with built-in safeguards:
function updateButtons() { // Get current select values const separatorSelect = document.getElementById('separator-select'); const caseSelect = document.getElementById('case-select'); const currentSeparator = separatorSelect.value; const currentCase = caseSelect.value; // Safely fetch the corresponding data (fallback to empty array if missing) const tokenData = naming[currentSeparator]?.[currentCase] || []; // Get all token buttons (adjust the selector to match your actual button class/id) const buttons = document.querySelectorAll('.token-button'); // Only loop up to the smaller of the two lengths (data count vs button count) const maxItems = Math.min(tokenData.length, buttons.length); for (let i = 0; i < maxItems; i++) { const item = tokenData[i]; const button = buttons[i]; // Only update if both the data item and button exist if (item && button) { button.innerText = `${item.token}: ${item.example}`; } } // Optional: Clear any extra buttons that don't have matching data for (let i = maxItems; i < buttons.length; i++) { buttons[i].innerText = ''; // Or hide them: buttons[i].style.display = 'none'; } } // Don't forget to call this on initial load and when selects change document.addEventListener('DOMContentLoaded', updateButtons); separatorSelect.addEventListener('change', updateButtons); caseSelect.addEventListener('change', updateButtons);
3. Verify Select Option Values
Make sure the value attributes of your <option> elements exactly match the keys in your naming object. For example:
<select id="separator-select"> <option value="space">Space</option> <option value="dot">Dot</option> <option value="underline">Underline</option> <option value="dash">Dash</option> </select>
If your naming object uses 'hyphen' instead of 'dash', that mismatch would cause naming[currentSeparator] to be undefined, leading to the first error.
Why This Works
- The optional chain operator (
?.) and empty fallback (|| []) ensure we never try to access properties on an undefined value. - Using
Math.min()prevents us from looping beyond the length of either the data array or the button list. - The double check for
itemandbuttonin the loop eliminates both types of TypeErrors you were seeing.
内容的提问来源于stack exchange,提问作者Eugene

