使用JS复制文本到剪贴板

3
我是JS初学者,遇到了以下问题:我希望只要有人点击手风琴内的URL图标,相应的链接就会被复制到剪贴板中。不幸的是(总是),只有第一个链接被复制到剪贴板中,即使单击其他两个URL图标,也只有第一个链接被复制。尽管在剪贴板中应该是链接2(来自值字段),当我单击URL图标2时(当然也适用于编号3)。我希望我已经足够清楚地描述了这个问题。
错误出在哪里?我需要更改JS代码以使其正常工作吗?非常感谢您提前的帮助!

```
<!DOCTYPE html>
<html>
<head>
  <title>My example Website</title>
<style>
body {
  font-size: 21px;
  font-family: Tahoma, Geneva, sans-serif;
  max-width: 550px;
  margin: 0 auto;
  background-color: black;
}
input {
  display: none;
}
label {
  display: block;    
  padding: 8px 22px;
  margin: 0 0 1px 0;
  cursor: pointer;
  background: #181818;
  border: 1px solid white;
  border-radius: 5px;
  color: #FFF;
  position: relative;
}
label:hover {
  background: white;
  border: 1px solid white;
  color:black;
}
label::after {
  content: '+';
  font-size: 22px;
  font-weight: bold;
  position: absolute;
  right: 10px;
  top: 2px;
}
input:checked + label::after {
  content: '-';
  right: 14px;
  top: 3px;
}
.content {
  background: #DBEECD;
  background: -webkit-linear-gradient(bottom right, #DBEECD, #EBD1CD);
  background: -moz-linear-gradient(bottom right, #DBEECD, #EBD1CD);
  background: linear-gradient(to top left, #DBEECD, #EBD1CD);
  padding: 10px 25px 10px 25px;
  border: 1px solid #A7A7A7;
  margin: 0 0 1px 0;
  border-radius: 1px;
}
input + label + .content {
  display: none;
}
input:checked + label + .content {
  display: block;
}
.whitepaper {
cursor: pointer;
text-align: center;
background-color: white;
border: 2px solid black;
border-radius: 3px;
float: left;
margin: 5px 5px 5px 0;
height: 40px;
width: 30px;
}
.blackframe {
text-align: center;
background-color: black;
cursor: pointer;
font-family: Tahoma, Geneva, sans-serif;
font-size:12px;
font-weight:bold;
margin: 12px 0 12px 0;
color: white;
width: 30px;
}
.whitepaper:hover {
cursor: pointer;
text-align: center;
background-color: black;
border: 2px solid white;
border-radius: 3px;
float: left;
margin: 5px 5px 5px 0;
height: 40px;
width: 30px;
}
 /* Tooltip container */
.tooltip {
  position: relative;
  display: inline-block;
}

/* Tooltip text */
.tooltip .tooltiptext {
  visibility: hidden;
  width: 120px;
  background-color: #555;
  color: #fff;
  text-align: center;
  padding: 5px 0;
  border-radius: 6px;

  /* Position the tooltip text */
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  margin-left: -60px;

  /* Fade in tooltip */
  opacity: 0;
  transition: opacity 0.3s;
}

/* Tooltip arrow */
.tooltip .tooltiptext::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
  visibility: visible;
  opacity: 1;
} 
</style>
</head>
<body>

<input type="checkbox" id="title1" name="contentbox" />
<label for="title1">Content 1</label>

<div class="content">

<div class="tooltip"><div class="whitepaper" onclick="myFunction()"><div class="blackframe"><span class="tooltiptext">Copy link 1 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title1" id="myInput"></div>

</div>

<input type="checkbox" id="title2" name="contentbox" />
<label for="title2">Content 2</label>

<div class="content">

<div class="tooltip"><div class="whitepaper" onclick="myFunction()"><div class="blackframe"><span class="tooltiptext">Copy link 2 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title2" id="myInput"></div>

</div>

<input type="checkbox" id="title3" name="contentbox" />
<label for="title3">Content 3</label>

<div class="content">

<div class="tooltip"><div class="whitepaper" onclick="myFunction()"><div class="blackframe"><span class="tooltiptext">Copy link 3 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title3" id="myInput"></div>

</div>

<script>
function myFunction() {
  /* Get the text field */
  var copyText = document.getElementById("myInput");

  /* Select the text field */
  copyText.select();
  copyText.setSelectionRange(0, 99999); /* For mobile devices */

   /* Copy the text inside the text field */
  navigator.clipboard.writeText(copyText.value);

  /* Alert the copied text */
  alert("Copied: " + copyText.value);
} 
</script>

</body>
</html>
```


好的,输入值(我不知道为什么要使用它们,在这里似乎是不必要的,但也许有原因)都是相同的。 - Apollo79
由于应用于当前文档的权限策略,剪贴板API已被阻止。请参见链接(https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-permissions-in-cross-origin-iframes)了解更多详细信息。@KiBLS - Jarne
@Apollo79 是的,那是我的笔误。对此我感到抱歉,但现在问题已经解决了。祝你晚上愉快 :) - KiBLS
3个回答

6

请按照以下方式替换函数myFunction:

function myFunction(event) {
    var target = event.target;
    var copyText = target.nextElementSibling;

    navigator.clipboard.writeText(copyText.value);

    alert("Copied: " + copyText.value);
}

然后更新所有的onclick属性,像这样:

onclick="myFunction(event)"

非常感谢!现在它按照预期工作了。祝你晚上愉快! :) - KiBLS
我刚刚注意到最初的问题已经解决了,但是出现了一个新问题。当我现在点击字母“URL”时,什么也不会发生。我必须点击上面或下面的白色边框,才能将文本加载到剪贴板中。有没有办法包括这些字母,使得当我点击字母“URL”时,文本也像我点击白色边框一样被复制到剪贴板中?我已经尝试在所有<div>元素上插入onclick(并且也尝试同时在所有元素上插入它们),但是不幸的是没有成功。你有什么想法吗? :) - KiBLS
好的,下面的帖子解决了问题,而且没有引起更多的问题。但无论如何还是感谢你的帮助! - KiBLS

2

2023年3月更新

似乎CodePen在某个时刻出现了问题,因为event.target返回的是第一个子元素而不是点击的目标元素。解决这个问题的方法是使用event.currentTarget来获取实际点击的元素。下面是新的解决方案,与旧方案相似但有一些调整。

function myFunction(event) {
  /* Get the text field */
  var copyText = event.currentTarget.firstElementChild.nextElementSibling.value
    
   /* Copy the text inside the text field */
  navigator.clipboard.writeText(copyText);

  /* Alert the copied text */
  alert("Copied: " + copyText);
} 

=========================================

我发现你的代码有几个问题

  1. 你没有更改输入框上的ID号,所以它们都会警报到相同的URL,这使得很难确定点击的是哪一个。
  2. 你正在对出现多次的ID进行查询选择。这意味着它不会在点击的元素上触发。

我的方法包括利用点击的元素通过将其传递给您的单击处理程序。

    <div class="tooltip">
        <div class="whitepaper" onclick="myFunction(event)">
            <div class="blackframe"><span class="tooltiptext">Copy link 3 to clipboard</span>URL</div>
        </div><input type="text" value="https://mywebsite.com/#title3" id="myInput">
    </div>

这让我可以将event传递给函数调用,从而让我们访问当前目标节点。
function myFunction(event) {
  /* Get the text field */
    var copyText = event.target.parentNode.nextSibling.nextSibling.value

   /* Copy the text inside the text field */
  navigator.clipboard.writeText(copyText);

  /* Alert the copied text */
  alert("Copied: " + copyText);
} 

在上述情况下,我不得不进行一些奇怪的遍历,因为您的输入超出了所点击元素的范围。我删除了与移动设备相关的代码,因为这与此问题无关(可以随意将其放回去)。
这是我的示例codepen

我今天早上注意到,使用您的代码时,我遇到了与上面解决方案完全相反的问题。使用您的代码,只有当我单击字母/字符“URL”时,链接才会被复制到剪贴板中。但是,如果我单击URL字母上方或下方的白色边框,则什么也不会发生。您有解决方法吗?我已经尝试创建另一个包围它的div元素,并使用onclick函数,还尝试将onclick元素放置在其他位置,但都没有成功。 :( - KiBLS
没问题。我通过将函数调用移动到父节点而不是文本节点来解决了这个问题。这也简化了遍历,因为我们只需要从最后一个子节点中获取值。https://codepen.io/LTFoReal/pen/KKQbMev?editors=1010 - LTFoReal
1
谢谢,但我用了稍微不同的方法解决了这个问题。只要我重新调整了一下CSS,你的第一个代码就很好用了。请在这里阅读我的第二篇帖子,其中介绍了我的解决方案以及新的CSS和你的代码。https://dev59.com/63UOtIcB2Jgan1zn2u0B 所以再次感谢你的帮助,祝你有愉快的一天! :) - KiBLS
你的 CodePen 示例都给了我 "copied: undefined"。 - Devin
1
@Devin,是的,问题似乎在于“target”向下冒泡而不是返回应该返回的内容,所以我用“currentTarget”替换了它,并加入了一些兄弟遍历。这是更新后的解决方案-https://codepen.io/LTFoReal/pen/KKQbMev - LTFoReal

0

以下是如何将文本复制到剪贴板的方法

示例:https://codepen.io/gmkhussain/pen/gOjaRzY

    function copyFunc(elemId) {

        let that = document.querySelector(elemId);

        navigator.clipboard.writeText(that?.innerText).then(res => {
          console.log("Copeid to clipboard: " + that.innerText );
          
          that.classList.add("copied")
          setTimeout(()=> that.classList.remove("copied"), 2000)
          
        });
    }

    <span class='box'>
       <span id="c1">Something One</span>
       <button class="btn" onclick="copyFunc('#c1')">Copy</button>
    </span>
         
     <span class='box'>
       <span id="c2">Amoos John Wick</span>
       <button class="btn" onclick="copyFunc('#c2')">Copy</button>
    </span>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接