使用PHP和JavaScript将文本复制到剪贴板?

7

我希望在现有网页上加入一个按钮,用于将文本复制到Windows剪贴板。

该网页及其中的PHP已经可以很好地创建和显示像这样的文本:

网页输出:

'Abby Normal' <abnormal@rockyhorror.com>, 'Brad Majors' <bm@rockyhorror.com>, 'Frank N. Furter' <franknfurter@rockyhorror.com>

现在我想添加一个JavaScript函数和一个HTML按钮来调用该函数,将输出内容复制到Windows剪贴板。
问题:当按下按钮时没有复制任何内容。我做错了什么?提前谢谢。
<?PHP
  session_start();
  include('include/_initsess.php');
  include('include/_setdb.php');
  if(!isset($_SESSION['userlist'])) exit;
  $users = $_SESSION['userlist'];
  $emails = '';
  $qry = "SELECT FIRST,LAST,EMAIL FROM users WHERE PKEY IN ($users)";
  $result  = mysql_query($qry);     
  $numrows = mysql_num_rows($result);   
  for ($m=0; $m<$numrows; $m++) {
    $row = mysql_fetch_array($result); 
    list($fn,$ln,$em) = $row;
    $emails .= ($m==0) ? "'".$fn." ".$ln."' &lt;".$em."&gt;" : (", '".$fn." ".$ln."' &lt;".$em."&gt;");
    } // end for
?>

<html>
<head>
</head>
<body>
<span class=mono id="theList" value="<?php echo $emails; ?>">
  <?PHP echo($emails); ?>
</span>

<script>
function copyToClipboardWithJavascript() {
  /* Get the text field */
  var copyText = document.getElementById("theList");
  /* Select the text field */
  copyText.select();
  /* Copy the text inside the text field */
  document.execCommand("copy");
}
</script>

<button onclick="copyToClipboardWithJavascript()">Click here</button>

</span>
</body>
</html>

我尝试了一篇Javascript教程提出的方法:

var copyText = = document.getElementById("theList");

我使用PHP在Javascript中进行了自己的变化:

var copyText = <?PHP echo($emails); ?>;
var copyText = `<?PHP echo($emails); ?>`;
var copyText = "<?PHP echo($emails); ?>";
var copyText = '<?PHP echo($emails); ?>';

但结果是没有任何错误,也没有复制到剪贴板中。
我知道网页被立即保存和使用,因为我还对按钮中的字母“点击这里”进行了微小的更改,并在刷新后看到了差异。
<span class=mono id="theList">
<?PHP echo($emails); ?>
</span>
<button id="copyButton" onclick="myCopyFunction()">Copy email address list to clipboard.</button>
<script>
function myCopyFunction() {
  var myText = document.createElement("textarea")
  myText.value = document.getElementById("theList").innerHTML;
  myText.value = myText.value.replace(/&lt;/g,"<");
  myText.value = myText.value.replace(/&gt;/g,">");
  document.body.appendChild(myText)
  myText.focus();
  myText.select();
  document.execCommand('copy');
  document.body.removeChild(myText);
}
</script>

你确定要公开这些电子邮件地址吗? - GolezTrol
3
那些电子邮件地址代表虚构人物。请看《洛基恐怖秀》。尽管如此,您的担忧是合理的 :) - Burgan
@Flashdrive 你的担忧是有道理的,因为这是一个已经存在的域名(实际上是RHPS粉丝俱乐部的),所以可能已经存在电子邮件地址。如果这确实是该网站的代码,那么这个问题也暴露了它使用的是一个旧版本的PHP,不再得到任何补丁,并且存在一个看起来容易受到SQL注入攻击的代码片段。我会备份一下,以确保安全。;-) - GolezTrol
在那行中,echo应该是class="mono",缺少引号。 - Michael
你尝试过哪些方法来解决这个问题?你目前卡在哪里了?这是一个 PHP 问题(打印使其正常工作的标记)还是一个 JS 问题(查找正确的代码复制某些内容到剪贴板)? - Nico Haase
显示剩余2条评论
3个回答

12

这是我制作的一个可行示例:

你需要知道两件事:

  1. 与之前的答案相反,你实际上可以将变量字符串复制到剪贴板中,就像我的示例一样。
  2. 用户必须明确采取某个行动来调用复制函数。如果它是自动调用的,复制将被拒绝。这很可能是你的问题所在。

这是我的示例。简要解释一下它的工作原理:创建一个新的临时元素,类型为 input type='text',给它赋值以便复制到剪贴板,然后执行复制命令,最后移除该临时元素。

copyToClipboard(document.getElementById("content"));

document.getElementById("clickCopy").onclick = function() {
 copyToClipboard(document.getElementById("goodContent"));
}

document.getElementById("clickCopyString").onclick = function() {
 copyToClipboard("This is a variable string");
}

/**
* This will copy the innerHTML of an element to the clipboard
* @param element reference OR string
*/
function copyToClipboard(e) {
    var tempItem = document.createElement('input');

    tempItem.setAttribute('type','text');
    tempItem.setAttribute('display','none');
    
    let content = e;
    if (e instanceof HTMLElement) {
      content = e.innerHTML;
    }
    
    tempItem.setAttribute('value',content);
    document.body.appendChild(tempItem);
    
    tempItem.select();
    document.execCommand('Copy');

    tempItem.parentElement.removeChild(tempItem);
}
div {
  border: 1px solid black;
  margin: 10px;
  padding: 5px;
}
<div id="content">
This is example text which will NOT be copied to the clipboard.
</div>
<div id="goodContent">
This WILL be copied to the cliboard when you push the button below:
</div>
<button id="clickCopy">
Copy Text from 2nd
</button>

<button id="clickCopyString">
Copy STRING to Clibpoard from Variable
</button>


这个答案适用于stackoverflow的“运行代码片段”按钮。这个网站让你在这里测试它真是太酷了。但是,使用JavaScript变量的另一个答案和它都不能在我的系统上工作。我会回来用JavaScript版本。我已经能够使用这段代码将信息提取到警报窗口中: var myText = document.getElementById("theList"); myText.value = <?php echo json_encode($emails); ?>; alert(myText.value); ----或者---- var myText = document.getElementById("theList").innerHTML; alert(myText.value); - Bear. Teddy Bear.
你的意思是它完全不工作还是只是不能自动工作?别忘了这只有在用户直接触发它时才能工作,例如按一个按钮。由于浏览器安全限制,你无法自动运行它。 - Brandon Dixon
我的意思是当用户按下按钮时它不起作用。@Brandon Dixon - Bear. Teddy Bear.
我已经让它工作了。基本上你的答案是我使用的@Brandon Dixon。创建一个元素,将文本放入其中,将元素附加到文档树中,选择我的元素,复制到剪贴板,从文档树中删除元素。除此之外,我在选择我的元素之前添加了myElement.focus();调用,如https://dev59.com/fHRC5IYBdhLWcg3wJNcN中所述。 - Bear. Teddy Bear.
缺少 .focus() 调用导致了这个错误:Uncaught TypeError: myText.select 不是一个函数。 - Bear. Teddy Bear.
非常感谢!您的函数正是我需要在我的项目中添加“复制到剪贴板”功能的!非常感谢! - P.Davide

3

您不能直接从字符串复制,只能从HTML元素复制。您需要将PHP字符串放入元素的值中。

function copyToClipboardWithJavascript() {
  /* Get the text field */
  var copyText = document.getElementById("theList");
  /* Put emails into the text field */
  copyText.value = <?php echo json_encode($emails); ?>;
  /* Select the text field */
  copyText.select();
  /* Copy the text inside the text field */
  document.execCommand("copy");
}

1
“你不能直接从字符串中复制,只能从HTML元素中复制”是不正确的。我的回答中的示例表明这是可能的。 - Brandon Dixon
你的答案不是直接从字符串复制的,而是创建了一个临时元素,设置其值,然后使用复制命令。我做的事情也一样,只是元素在HTML中,不是在临时位置。 - Barmar
是的,抱歉,我相信我第一次阅读时曲解了您的陈述,认为您根本无法做到。 - Brandon Dixon

0

这个简单的解决方案可能适用于您。这是我使用的方法。使用jQuery。

function copy() {
  navigator.clipboard.writeText($('#link-to-copy').val());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<span onclick="copy();">
  Copy link
</span>

<input type="hidden" id="link-to-copy" value="<?= $link_copy ?>">

当您点击“复制链接” span 元素时,它将调用 copy() 函数,该函数将把隐藏输入框(id 为 'link-to-copy')的值写入您浏览器的剪贴板。
隐藏输入框的值可以是任何您想要的,这里我使用了一个 PHP 变量。然后,这个 PHP 值将被复制到您的剪贴板中。

请分享更多细节,以便其他人可以从您的答案中学习。就我所见,您在答案中没有使用任何PHP生成的数据。 - Nico Haase
@NicoHaase 是的,我是。看到隐藏输入框的值了吗? - Isaac Muniz
请随意通过编辑您的答案添加所有澄清内容。 - Nico Haase
@NicoHaase 好的,已添加解释。谢谢。 - Isaac Muniz

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