繁体   English   中英

事件侦听器未附加到所有元素,但仅在 JavaScript 的 for 循环中附加到最后一个元素

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM