如何使用JavaScript实现闪卡数据展示并解决切换与渲染异常问题
问题修复方案
核心错误根源
1. 索引值错误增减
你在prev/next按钮的回调中,对索引idx执行了两次自增/自减操作,每次切换会直接跳2个索引位,很快就超出数组边界,同时导致正反面内容对应不同卡片,出现渲染异常、浏览器抛错。
2. 事件监听器重复绑定
每次调用getCardInfo都会给按钮新增事件监听器,未清理旧绑定,导致单次点击触发多次回调,索引逻辑完全混乱。
3. 无索引边界校验
没有限制索引的最小值为0、最大值为卡片总数-1,索引越界后访问不存在的数组成员直接报错。
4. 索引状态无法同步
你将索引作为值参数传入scrollThroughCards,修改的是局部变量副本,索引状态无法在多次点击中正确保持。
修复后前端代码
const flashCard = document.querySelector(".flashcard"); const flipBtn = document.querySelector(".flip-btn"); const prevBtn = document.querySelector(".prev-btn"); const nextBtn = document.querySelector(".next-btn"); let frontOfCard = document.querySelector(".front-content"); let backOfCard = document.querySelector(".back-content"); // 把索引提为全局状态,避免值传递问题 let currentCardIdx = 0; let cardList = []; // 提前绑定一次flip事件,避免重复绑定 const flash = () => { flashCard.style.transform = flashCard.style.transform != "rotateX(180deg)" ? "rotateX(180deg)" : "none"; }; flipBtn.addEventListener("click", flash); // 卡片渲染公共方法,避免重复写逻辑 const renderCurrentCard = () => { frontOfCard.innerHTML = cardList[currentCardIdx].Answer; backOfCard.innerHTML = cardList[currentCardIdx].Question; flashCard.style.transform = "none"; // 切换卡片后自动回到正面 flashCard.style.display = "block"; }; const displayCards = () => { getCardInfo(); flipBtn.innerHTML = "Flip"; flipBtn.removeEventListener("click", displayCards); } // 初始化绑定View Cards的点击事件 flipBtn.addEventListener("click", displayCards); const getCardInfo = async () => { const itemBody = { method: "PUT", headers: { Accept: "application/json", "Content-Type": "application/json" } } const data = await fetch(window.location.href, itemBody); cardList = await data.json(); currentCardIdx = 0; renderCurrentCard(); } // 切换按钮只绑定一次,不用每次拉取数据都重复绑定 prevBtn.addEventListener("click", (e) => { e.preventDefault(); if (currentCardIdx <= 0) return; // 边界限制:到第一张卡后不再后退 currentCardIdx--; flashCard.style.display = "none"; setTimeout(renderCurrentCard, 1000); }) nextBtn.addEventListener("click", (e) => { e.preventDefault(); if (currentCardIdx >= cardList.length - 1) return; // 边界限制:到最后一张卡后不再前进 currentCardIdx++; flashCard.style.display = "none"; setTimeout(renderCurrentCard, 1000); })
补充说明
后端代码逻辑无问题,不需要修改。如果仍存在正反面内容颠倒的情况,交换renderCurrentCard方法里Answer和Question的赋值位置即可。
内容的提问来源于stack exchange,提问作者Zoko
相关产品推荐
相关产品推荐

