如何在 Javascript 中使用 HTML 模板文字添加事件侦听器?

How to add event listener with HTML template literals in Javascript?

我从 URL 中获取了一些数据,之后我使用 forEach 循环为接收到的每一项数据生成了一个 HTML 模板。在为响应数据中的所有元素创建 HTML 模板后,我将其分配给 document.body.innerHTML。所以它显示了我的 HTML 模板的所有元素。

响应有 30 个对象,每个对象都有一个 link (clone_url) 和其他信息。我已经使用我的 HTML 模板为这 30 个对象生成了 HTML 元素,每个元素都有一个名称、个人资料头像和用于复制我提到的特定 link 的按钮。我想在用户单击复制按钮时将 link 复制到剪贴板。

因此,我想给按钮添加事件监听器。那就是我一直在努力的地方,因为我不知道我该怎么做。因为我必须访问每个组件并且我还想访问相关的响应对象以获得 link.

const url = "https://api.github.com/users/shrutikapoor08/repos";

fetch(url)
  .then((response) => response.json())
  .then((users) => {
    console.log(users);
    let htmlText = "";
    users.forEach((i) => {
      htmlText += `
        <div class="repo-container">
        <p class="repo-title">${i.name}</p>
        <div class="repo-owner">
          <img
            src="${i.owner.avatar_url}"
            alt="avatar"
            class="avatar"
          />
          <a href="${i.owner.html_url}" class="repo-owner-username">${i.owner.login}</a>
        </div>
        <div class="link-container">
          <button class="repo-link-btn">Copy</button>
          <p class="tooltip">Link Coppied</p>
        </div>
      </div>
        `;
    });
    document.body.innerHTML = htmlText;
  });
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Roboto", sans-serif;
}

.repo-container {
  background-color: rgb(255, 253, 251);
  border: 1px solid rgb(226, 226, 226);
  padding: 15px;
  width: 250px;
  margin: 10px;
}

.repo-title {
  font-weight: bold;
  margin-bottom: 10px;
}

.repo-owner {
  display: flex;
  align-items: center;
}

.avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  margin-right: 20px;
}

.repo-owner-username {
  font-size: 0.8rem;
  text-decoration: none;
}

.tooltip {
  background-color: rgba(0, 0, 0, 0.7);
  width: fit-content;
  padding: 4px 10px;
  border-radius: 10px;
  font-size: 0.75rem;
  color: white;
  opacity: 0;
  transition: transform 0.3s ease, opacity 0.3s ease;
  pointer-events: none;
}

.tooltip.active {
  opacity: 1;
  transform: translateY(-10px);
}

.link-container {
  display: flex;
}

.repo-link-btn {
  margin: 10px 0px;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./style.css" />
    <title>Document</title>
  </head>
  <body>
    <script src="./app.js"></script>
  </body>
</html>

这是我要为每个按钮添加的代码。

document.querySelector(".repo-link-btn").addEventListener("click", async () => {
  const text = "";
  await navigator.clipboard.writeText(text);
  document.querySelector(".tooltip").classList.add("active");
  setTimeout(() => {
    document.querySelector(".tooltip").classList.remove("active");
  }, 500);
});

const text 应等于响应数据对象 URL。我也必须访问该数据。解决此问题的最佳做法是什么?

如果您想使用纯 JavaScript,您需要创建循环并向所有项目添加事件侦听器,如下所示:

[...document.querySelectorAll(".repo-link-btn")].forEach(function (item) {..}

要查找 clone_url 值,您可以设置自定义属性,例如 data-cloneUrl="${i.clone_url}",然后在点击时获取它:e.target.getAttribute("data-cloneUrl");

请注意,此代码基于您的 html 和纯 JavaScript。 jQuery.

有更简单的方法

        const url = "https://api.github.com/users/shrutikapoor08/repos";

        fetch(url)
            .then((response) => response.json())
            .then((users) => {
                console.log(users);
                let htmlText = "";
                users.forEach((i) => {
                    htmlText += `
        <div class="repo-container">
        <p class="repo-title">${i.name}</p>
        <div class="repo-owner">
          <img
            src="${i.owner.avatar_url}"
            alt="avatar"
            class="avatar"
          />
          <a href="${i.owner.html_url}" class="repo-owner-username">${i.owner.login}</a>
        </div>
        <div class="link-container">
          <button class="repo-link-btn" data-cloneUrl="${i.clone_url}">Copy</button>
          <p class="tooltip">Link Coppied</p>
        </div>
      </div>
        `;
                });
                document.body.innerHTML = htmlText;

                [...document.querySelectorAll(".repo-link-btn")].forEach(function (item) {
                    item.addEventListener("click", async (e) => {
                        const text = e.target.getAttribute("data-cloneUrl");
                        await navigator.clipboard.writeText(text);
                        document.querySelector(".tooltip").classList.add("active");
                        setTimeout(() => {
                            document.querySelector(".tooltip").classList.remove("active");
                        }, 500);
                    });
                })
            });
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap");

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: "Roboto", sans-serif;
        }

        .repo-container {
            background-color: rgb(255, 253, 251);
            border: 1px solid rgb(226, 226, 226);
            padding: 15px;
            width: 250px;
            margin: 10px;
        }

        .repo-title {
            font-weight: bold;
            margin-bottom: 10px;
        }

        .repo-owner {
            display: flex;
            align-items: center;
        }

        .avatar {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            margin-right: 20px;
        }

        .repo-owner-username {
            font-size: 0.8rem;
            text-decoration: none;
        }

        .tooltip {
            background-color: rgba(0, 0, 0, 0.7);
            width: fit-content;
            padding: 4px 10px;
            border-radius: 10px;
            font-size: 0.75rem;
            color: white;
            opacity: 0;
            transition: transform 0.3s ease, opacity 0.3s ease;
            pointer-events: none;
        }

            .tooltip.active {
                opacity: 1;
                transform: translateY(-10px);
            }

        .link-container {
            display: flex;
        }

        .repo-link-btn {
            margin: 10px 0px;
        }

请注意该代码段工作正常但堆栈溢出代码段说 The Clipboard API has been blocked because of a permissions policy applied to the current document。因此,请检查您计算机中的代码段。