[英]Event listener not attaching to all element but attach to last one only in for loop in javascript
我正在尝试在缩略图容器上添加一个事件侦听器,它并没有附加到所有元素,而是始终附加到最后一个元素。
我试图将 for 循环的内容放在匿名函数中,但它也不起作用。
const getThumbnail = async (skipIndex) => {
if (typeof skipIndex === "number") {
const { files } = await fetchData(`/getNumber/${skipIndex}`, null, true);
const { length } = files;
if (length !== 0 && files)
{
APP.skipIndex += length;
for (let index = 0; index < length; index++) {
const element = files[index];
const { length } = element;
const [videoName] = element.filename.split("_");
const { _id } = element;
if (!length <= 0) {
const { mimetype } = element.metadata;
const data = await fetchData(`/getThumbnail/${_id}`, null, false);
const thumbnailDataString = getBase64(mimetype, data);
addVideoThumbnail(thumbnailDataString, videoName, index, _id);
}
else
{
const defaultUrl = "../img/default.png";
addVideoThumbnail(defaultUrl, videoName, index, _id);
}
const tCon = elementById(_id);
addEvent(tCon);
}
}
else {
APP.skipIndex = false;
}
}
else {
console.log("else first");
}
};
const addEvent = (tCon) => {
console.log("add event");
const [thumbnail, name, deleteSpan] = tCon.children;
const { id } = tCon;
deleteSpan.addEventListener("click", async () => {
const postData = {
method: "DELETE",
};
const res = await fetchData(`/deleteFile/${id}`, postData, true);
res.result ? showAlert("success", false) : showAlert("failure", false);
});
const opacityChange = (status) => {
status ? thumbnail.classList.add("opacity-50") : thumbnail.classList.remove("opacity-50");
};
const sameFunc = (opacity, visible) => {
opacityChange(opacity);
changeClass(name, visible);
changeClass(deleteSpan, visible);
};
deleteSpan.addEventListener("mouseover", () => opacityChange(true));
name.addEventListener("mouseover", () => opacityChange(true));
tCon.addEventListener("mouseover", () => sameFunc(true, false));
tCon.addEventListener("mouseout", () => sameFunc(false, true));
tCon.addEventListener("click", () => watchVideo(id));
tCon.addEventListener("touchmove", () => sameFunc(true, false));
tCon.addEventListener("touchend", () => sameFunc(false, true));
};
我认为这是一个关闭问题。
对不起,如果这很奇怪,我是初学者。
是的,这很可能是一个关闭问题。 您在 addEvent(tCon) 调用中提供的 tCon 作为参考发送,因此随着循环的进行和 tCon 的值的变化,它也会反映在参考上。
考虑像这样更改您的 addEvent 函数:
const addEvent = (element_id) => {
const tCon = elementById(element_id);
然后像这样调用addEvent
:
addEvent(_id.slice());
_id.slice()
创建_id
的副本并将该副本发送到 addEvent 函数。 这个_id
的副本现在应该作为值发送到addEvent
函数。
之后,在addEvent
函数中,我们使用_id
的副本通过 id 将元素获取到tCon
变量中。
我无法 100% 验证这是否有效,因此请尝试一下,看看会发生什么。
编辑:
而不是addEvent(_id.slice())
,您可以使用IIFE :
((id) => {
addEvent(id);
})(_id);
因此,经过一天的了解,了解了很多。 我发现使用 0 毫秒的setTimeout可以解决我的问题。
如何:- 当您将毫秒设置为 0 时,这意味着您想最后触发它。 所以当我的 for 循环结束时。 所有 setTimeout 都一一触发,并将 _id 传递给 addEvent 函数。
所以当前代码是这样的: -
const getThumbnail = async (skipIndex) => {
if (typeof skipIndex === "number") {
APP.hitted = true;
const { files } = await fetchData(`/getNumber/${skipIndex}`, null, true);
const { length } = files;
if (length !== 0 && files) {
files.forEach(async (element, index) => {
const originalIndex = index + APP.skipIndex;
const { length, _id } = element;
const [videoName] = element.filename.split("_");
if (!length <= 0) {
const { mimetype } = element.metadata;
const data = await fetchData(`/getThumbnail/${_id}`, null, false);
const thumbnailDataString = getBase64(mimetype, data);
addVideoThumbnail(thumbnailDataString, videoName, originalIndex, _id);
} // else this will fire
else {
const defaultUrl = "../img/default.png";
addVideoThumbnail(defaultUrl, videoName, originalIndex, _id);
}
setTimeout(() => addEvent(_id.slice()), 0);
});
APP.skipIndex += length;
} // else this will fire
else APP.skipIndex = false;
}
setTimeout(() => {
APP.hitted = false;
}, 1000);
};
const addEvent = (id) => {
const tCon = elementById(id);
const [thumbnail, name, deleteSpan] = tCon.children;
deleteSpan.addEventListener("click", async () => {
const postData = {
method: "DELETE",
};
const res = await fetchData(`/deleteFile/${id}`, postData, true);
if (res.result) {
tCon.remove();
showAlert("success", false);
} // else this will fire
else showAlert("failure", false);
});
// to add or remove opacity-50 class from thumbnail
const opacityChange = (status) => {
status
? thumbnail.classList.add("opacity-50")
: thumbnail.classList.remove("opacity-50");
};
const sameFunc = (opacity, visible) => {
opacityChange(opacity);
changeClass(name, visible);
changeClass(deleteSpan, visible);
};
deleteSpan.addEventListener("mouseover", () => opacityChange(true));
name.addEventListener("mouseover", () => opacityChange(true));
tCon.addEventListener("mouseover", () => sameFunc(true, false));
tCon.addEventListener("mouseout", () => sameFunc(false, true));
thumbnail.addEventListener("click", () => watchVideo(id));
tCon.addEventListener("touchmove", () => sameFunc(true, false));
tCon.addEventListener("touchend", () => sameFunc(false, true));
};
您还可以通过单击此处查看此文件或项目的源代码以详细了解它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.