【问题标题】:How to copy text, which is in a for-each loop, to clipboard when button is clicked?单击按钮时如何将for-each循环中的文本复制到剪贴板?
【发布时间】:2018-11-11 22:03:18
【问题描述】:

我有一个 for-each 循环,它从数据库中打印出一些文本并显示一个按钮。所以基本上我有多个文本“区域”,每个区域都有自己的按钮。我想要这样,每当用户点击一个按钮时,它匹配的特定文本就会被复制到剪贴板。

在发帖之前,我尝试对此进行多次搜索。但是,从其他解决方案中,我读到它们或多或少地显示了在输入标签中复制文本的解决方案。但是,在我的情况下,用户没有输入任何需要复制的内容 - 文本已经在屏幕上并且无法更改。

我无法复制与按钮匹配的特定文本,因为该文本没有特定的 id 或类名,因为它只是在循环时打印文本,因此它们都具有相同的类名。那么我如何使用该按钮指定特定文本,因为按钮可以按任何顺序按下?

HTML:

<c:forEach items="${items}" var="item">
<h2>${item.itemDescription}</h2>
<input class="big-button" type="button" value="Add item copied to clipboard" id="btn" onclick="status(this)">
</c:forEach>

JavaScript:

function status(clickedBtn) 
  {
    clickedBtn.value = "Copied to clipboard";
    clickedBtn.disabled = true;
    clickedBtn.style.color = 'white';
    clickedBtn.style.background = 'gray';
  }

【问题讨论】:

  • 我已经使用这个答案将文本放到剪贴板上:stackoverflow.com/a/33928558/74757。您可以使用选择器从 &lt;h2&gt; 项目中获取文本并传递它。
  • 您也可以使用循环中项目的索引来生成一个 id,这样您就可以更轻松地引用您的元素。
  • @Cᴏʀʏ,非常感谢您提供链接。所以,我检查了一下,似乎他们能够做到new Date() 将日期复制到剪贴板。但是,就我而言,我必须复制循环中的字符串——${item.itemDescription}。那么,我怎么能调用它,因为那是在我的 HTML 中,而不是在 JS 中。
  • @Cᴏʀʏ 哦,好吧,这是有道理的。抱歉,我还是 HTML 和 JS 的新手。我怎么能引用某个索引,因为我理论上不知道有多少元素,因为我从数据库中获取信息并插入到我的 HTML 中。
  • 你用的是什么模板框架?

标签: javascript html


【解决方案1】:

我会更改您的 HTML 以生成某种 ID,该 ID 可用于在您的文本中引用元素。

<c:forEach items="${items}" var="item" varStatus="loop">
    <h2 id="item-desc-${loop.index}">${item.itemDescription}</h2>
    <input class="big-button" data-desc-ref="item-desc-${loop.index}" type="button" value="Add item copied to clipboard" id="btn" onclick="status(this)">
</c:forEach>

在上面我添加了代码以在每个 &lt;h2&gt; 元素上生成一个唯一的 ID(例如 id="item-desc-0")。在按钮上,我添加了一个data- 属性来引用&lt;h2&gt; 的ID,以便我们稍后检索它。

现在我们更改您的status 函数以通过数据属性中指定的ID 查找元素,并获取其innerText(开始和结束标记之间的内容)。

然后,您可以将该文本传递给将其复制到剪贴板的函数,在我的评论中参考上面。

  function status(clickedBtn) 
  {
    var text = document.getElementById(clickedBtn.dataset.descRef).innerText;
    copyToClipboard(text);

    clickedBtn.value = "Copied to clipboard";
    clickedBtn.disabled = true;
    clickedBtn.style.color = 'white';
    clickedBtn.style.background = 'gray';
  }

这是一个工作示例。我必须放入将由您的循环生成的示例 HTML。

function copyToClipboard(text) {
  if (window.clipboardData && window.clipboardData.setData) {
    // IE specific code path to prevent textarea being shown while dialog is visible.
    return clipboardData.setData("Text", text);

  } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
    var textarea = document.createElement("textarea");
    textarea.textContent = text;
    textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in MS Edge.
    document.body.appendChild(textarea);
    textarea.select();
    try {
      return document.execCommand("copy"); // Security exception may be thrown by some browsers.
    } catch (ex) {
      console.warn("Copy to clipboard failed.", ex);
      return false;
    } finally {
      document.body.removeChild(textarea);
    }
  }
}

function status(clickedBtn) {
  var text = document.getElementById(clickedBtn.dataset.descRef).innerText;

  copyToClipboard(text);

  clickedBtn.value = "Copied to clipboard";
  clickedBtn.disabled = true;
  clickedBtn.style.color = 'white';
  clickedBtn.style.background = 'gray';
}
<h2 id="item-desc-0">Testing 0</h2>
<input class="big-button" data-desc-ref="item-desc-0" type="button" value="Add item copied to clipboard" id="btn" onclick="status(this)">

<h2 id="item-desc-1">Testing 1</h2>
<input class="big-button" data-desc-ref="item-desc-1" type="button" value="Add item copied to clipboard" id="btn" onclick="status(this)">

<h2 id="item-desc-2">Testing 2</h2>
<input class="big-button" data-desc-ref="item-desc-2" type="button" value="Add item copied to clipboard" id="btn" onclick="status(this)">

【讨论】:

  • @Cory,非常感谢!我试过了,不幸的是,它不起作用。什么时候为 for-each 循环设置索引号?
  • 我提供了一些修改过的 JSTL 代码,它们呈现的 HTML 有点不同。你记得更新你的 JSTL 吗?
  • @Cory,你应该得到最金色的星星!!!这行得通!哇,你太不可思议了!!!太感谢了!! :)
  • 不客气!请研究并理解它,如果其中任何部分没有意义,请回复。充分了解它的工作原理是有益的,这样您就可以从中学习。
【解决方案2】:

如果h2 元素恰好位于previousbutton 上,则可以这样使用。

function status(clickedBtn) 
    {
      clickedBtn.value = "Copied to clipboard";
      clickedBtn.disabled = true;
      clickedBtn.style.color = 'white';
      clickedBtn.style.background = 'gray';

      //New Code
      copyToCliboard(clickedBtn.previousSibling);
    }
    function copyToCliboard(el) {
      if (document.body.createTextRange) {
          var range = document.body.createTextRange();
          range.moveToElementText(el);
          range.select();
      } else {
          var selection = window.getSelection();
          var range = document.createRange();
          range.selectNodeContents(el);
          selection.removeAllRanges();
          selection.addRange(range);
      }
      document.execCommand("copy");
      window.getSelection().removeAllRanges();
  }
h2{
display:inline;
}
<html>
  <head>
 </head>
  <body>
   <div><h2>Text1</h2><button onclick="status(this)">Copy</button></div>
   <div><h2>Text2</h2><button onclick="status(this)">Copy</button></div>
  </body>
</html>

【讨论】:

    【解决方案3】:

    Cory 提供了一个非常有用的指向剪贴板方面的链接,我想我会提供有关如何定位点击的元素的信息。

    要实现这一点,请将event 传递给您的onclick 属性,并使用event.target 来引用被点击的元素。这是一个基本示例:

    function copy(e) {
    	alert(e.target.value)
    }
    <button onclick="copy(event)" value="copy this">copy this</button>
    <button onclick="copy(event)" value="copy that">copy that</button>

    为了满足您的特定要求,如果您将item.itemDescription 放入value 属性中,那么它将复制您想要的文本。

    【讨论】:

    • 非常感谢!所以既然我的value 属性中已经有了一些东西,还有其他方法可以解决这个问题吗?
    • @daisygal 当然,您可以使用parent selector 然后从那里找到h2 值。
    猜你喜欢
    • 2019-07-27
    • 2014-04-30
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    相关资源
    最近更新 更多