【发布时间】:2020-11-22 01:54:20
【问题描述】:
我有以下代码,它从名为 banner 的 Firestore 集合中获取 snapshot。每个对象都有以下结构
{
index: // each object has index
image: // url of source image
link: // link to be redirected when clicked the image
}
这是我从我的集合中动态添加元素到 HTML 的 HTML 代码,在这种情况下我有 5 图像
<div id="homepage-background" class="background">
<img class="bg" src="https://firebasestorage.googleapis.com/v0/b....">
<img class="bg" src="https://firebasestorage.googleapis.com/v0/b....">
<img class="bg" src="https://firebasestorage.googleapis.com/v0/b....">
<img class="bg" src="https://firebasestorage.googleapis.com/v0/b....">
<img class="bg" src="https://firebasestorage.googleapis.com/v0/b....">
</div>
这里是函数
let homepageBackground = document.getElementById("homepage-background");
firebase
.firestore()
.collection("banner")
.orderBy("index")
.get()
.then((snapshot) => {
let array = snapshot.docs;
for (let i = 0; i < array.length; i++) {
console.log(array[i].data());
console.log("i before " + i);
let imgBackground = document.createElement("img");
imgBackground.setAttribute("class", "bg");
imgBackground.setAttribute("src", array[i].image);
imgBackground.setAttribute("data-index", i);
console.log("i after " + i);
imgBackground.addEventListener("click", function () {
const alertText = imgBackground.getAttribute("data-index");
alert(alertText);
});
homepageBackground.appendChild(imgBackground);
}
})
.catch((error) => {
console.log(error);
});
问题是我点击的每张图片都会提醒5,这是我收藏中最后一个元素的索引。我希望当我单击第一张图片时收到1 的警报,单击第二张图片,收到2 的警报,依此类推,直到第五张图片获得5 的警报。不知何故,集合中每个文档的index 属性都无法正确显示,因为无论我点击什么图片,我都会收到5 的警报,这是最后一个元素的索引。我认为问题出在 addEventListener() 函数上,该函数可能只分配给最后一个 HTML 元素,因为它总是显示 5。
我不太确定为什么它不起作用以及我应该如何解决。
编辑
我在imgBackground.setAttribute("data-index", i);之前和之后添加了2个控制台日志
页面加载后显示如下
i before 0
i after 0
i before 1
i after 1
i before 2
i after 2
i before 3
i after 3
i before 4
i after 4
我的假设是所有图像都已经呈现到 HTML,因为它们正确显示在屏幕上。但只有在循环i 被设置为最后一个索引之后。我不得不提到我还有一个脚本文件负责在页面中滑动图像。它只是一个setInterval(),每 5 秒运行一次,并从该div 向每个img 添加show 类。以下是脚本。
document.addEventListener(
"load",
function () {
let slider = document.querySelector(".slider");
let buttons = document.querySelectorAll(".btn");
let slides = document.querySelectorAll(".img");
let backgrounds = document.querySelectorAll(".bg");
let options = document.querySelectorAll(".option");
let element = document.getElementById("homepage-background");
let numberOfChildren = element.getElementsByTagName("img").length;
let index = 1;
let op_index = 0;
let size = slides[index].clientWidth;
update();
function update() {
slider.style.transform = "translateX(" + -size * index + "px)";
backgrounds.forEach((img) => img.classList.remove("show"));
backgrounds[op_index].classList.add("show");
options.forEach((op) => op.classList.remove("colored"));
options[op_index].classList.add("colored");
}
function slide() {
slider.style.transition = "transform .5s ease-in-out";
update();
}
function btnCheck() {
if (this.id === "prev") {
index--;
if (op_index === 0) {
op_index = numberOfChildren - 1;
} else {
op_index--;
}
} else {
index++;
if (op_index === numberOfChildren - 1) {
op_index = 0;
} else {
op_index++;
}
}
slide();
}
slider.addEventListener("transitionend", () => {
if (index >= numberOfChildren - 1) {
return;
}
if (index <= 0) {
return;
}
if (slides[index].id === "fist") {
slider.style.transition = "none";
index = slides.length - 2;
slider.style.transform = "translateX(" + -size * index + "px)";
} else if (slides[index].id === "last") {
slider.style.transition = "none";
index = 1;
slider.style.transform = "translateX(" + -size * index + "px)";
}
});
buttons.forEach((btn) => btn.addEventListener("click", btnCheck));
options.forEach((option) => option.addEventListener("click", optionFunc));
setInterval(btnCheck, 5000);
},
5000
);
【问题讨论】:
-
我可能只是在循环内的元素上设置一个
data-属性,然后编写click函数来提醒事件目标的数据值。 -
您希望这段代码有何不同之处?由于我们无法查看您的数据或知道您点击的是哪个元素,因此无法查看发生了什么。
-
@Marc 我的理解是我应该在循环内创建类似
let currentImage = array[i].data();的东西并使用它而不是array[i].data();? -
@DougStevenson 我编辑了帖子并提供了有关该问题的更多详细信息。
-
只是为了确认,src 在循环中被正确旋转,但索引只是被记录为 array.length - 1 基本上对吗?或者 src 也只是指向 array[4].image?
标签: javascript html firebase google-cloud-firestore