0

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

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

因此,我想向按钮添加事件侦听器。那就是我一直在努力的地方,因为我不知道该怎么做。因为我必须访问每个组件,并且我想访问相关的响应对象来获取链接。

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。我也必须访问这些数据。解决这个问题的好习惯是什么?

4

1 回答 1

1

如果您想使用纯 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。因此,请检查您计算机中的代码段。

于 2021-08-08T08:45:00.170 回答