箭头切换卡片时hiddenCard内容无法正确更新的问题求助
我正在用JavaScript实现一个卡片导航功能:点击卡片时,把卡片内容展示在hiddenCard元素里,还能通过左右箭头按钮切换不同卡片。
目前点击卡片时hiddenCard能正常显示,但点击箭头按钮时,hiddenCard的内容没法更新,导航功能完全达不到预期效果。
我的代码实现
选择卡片和隐藏卡片元素
var cards=document.querySelectorAll(".card"); var hiddenCard=document.querySelector(".card_hidden") var currntIndex=0;
给每个卡片添加点击事件
for (var i = 0; i < cards.length; i++) { cards[i].addEventListener("click", function () { currntIndex = Array.from(cards).indexOf(this); var image = this.querySelector("img"); var title = this.querySelector(".title p"); hiddenCard.innerHTML = ` <p>${title.textContent}</p> <img src=${image.src}> <i class="fa-solid fa-arrow-left pre"></i> <i class="fa-solid fa-arrow-right next"></i> `; hiddenCard.style.display = "block"; console.log(hiddenCard); arrows(); }); }
箭头导航功能
function arrows() { document.querySelector(".pre").addEventListener("click", function () { if (currntIndex > 0) { currntIndex--; showIndex(currntIndex); } }); document.querySelector(".next").addEventListener("click", function () { if (currntIndex < cards.length - 1) { currntIndex++; showIndex(currntIndex); } }); }
更新隐藏卡片内容
function showIndex(currntIndex) { var imagIndex = cards[currntIndex].querySelector("img"); var titleIndex = cards[currntIndex].querySelector(".title p"); hiddenCard.innerHTML = ` <p>${titleIndex.textContent}</p> <img src=${imagIndex.src}> <i class="fa-solid fa-arrow-left pre"></i> <i class="fa-solid fa-arrow-right next"></i> `; }
问题分析与修复方案
问题出在哪?
兄弟你踩了个常见的JS坑:**每次调用showIndex更新内容时,你用innerHTML把整个hiddenCard的内容全部替换了,包括之前绑定了点击事件的箭头按钮!**新生成的箭头元素根本没有绑定点击事件,所以点了自然没反应。而且每次点击卡片都调用arrows(),还会给新箭头重复绑定事件,积累下来点一次箭头可能触发好几次,逻辑彻底乱套。
修复方案(二选一即可)
方案一:提前放置箭头,只更新可变内容
这个方案更高效,不用反复创建销毁元素:
- 先把hiddenCard的基础结构写好(箭头提前放进去):
<div class="card_hidden" style="display: none;"> <p class="hidden-card-title"></p> <img class="hidden-card-img" src="" alt=""> <i class="fa-solid fa-arrow-left pre"></i> <i class="fa-solid fa-arrow-right next"></i> </div>
- 修改JS代码,只更新标题和图片,不动箭头:
var cards = document.querySelectorAll(".card"); var hiddenCard = document.querySelector(".card_hidden"); // 提前获取要更新的元素 var hiddenTitle = hiddenCard.querySelector(".hidden-card-title"); var hiddenImg = hiddenCard.querySelector(".hidden-card-img"); var currntIndex = 0; // 箭头事件只绑定一次!不用每次点卡片都绑 document.querySelector(".pre").addEventListener("click", function () { if (currntIndex > 0) { currntIndex--; showCurrentCard(); } }); document.querySelector(".next").addEventListener("click", function () { if (currntIndex < cards.length - 1) { currntIndex++; showCurrentCard(); } }); // 卡片点击事件 for (var i = 0; i < cards.length; i++) { cards[i].addEventListener("click", function () { currntIndex = Array.from(cards).indexOf(this); showCurrentCard(); hiddenCard.style.display = "block"; }); } // 只更新需要变的内容,不动箭头 function showCurrentCard() { const activeCard = cards[currntIndex]; const cardImg = activeCard.querySelector("img"); const cardTitle = activeCard.querySelector(".title p"); hiddenTitle.textContent = cardTitle.textContent; hiddenImg.src = cardImg.src; }
方案二:用事件委托,兼容动态生成的箭头
如果不想改HTML结构,用事件委托就完美解决——给hiddenCard本身绑定点击事件,判断点击的是不是箭头:
var cards = document.querySelectorAll(".card"); var hiddenCard = document.querySelector(".card_hidden"); var currntIndex = 0; // 事件委托:给父元素绑定一次事件,永远生效 hiddenCard.addEventListener("click", function(e) { // 判断点击的是左箭头还是右箭头 if (e.target.classList.contains("pre")) { if (currntIndex > 0) { currntIndex--; showCurrentCard(); } } else if (e.target.classList.contains("next")) { if (currntIndex < cards.length - 1) { currntIndex++; showCurrentCard(); } } }); // 卡片点击事件不变 for (var i = 0; i < cards.length; i++) { cards[i].addEventListener("click", function () { currntIndex = Array.from(cards).indexOf(this); showCurrentCard(); hiddenCard.style.display = "block"; }); } // 这个函数不用改,继续用innerHTML生成内容 function showCurrentCard() { const activeCard = cards[currntIndex]; const cardImg = activeCard.querySelector("img"); const cardTitle = activeCard.querySelector(".title p"); hiddenCard.innerHTML = ` <p>${cardTitle.textContent}</p> <img src=${cardImg.src}> <i class="fa-solid fa-arrow-left pre"></i> <i class="fa-solid fa-arrow-right next"></i> `; }
这样改完之后,箭头点击就能正常切换卡片,内容也会正确更新啦!
备注:内容来源于stack exchange,提问作者Nada Mohamed
相关产品推荐
相关产品推荐

