JavaScript execCommand('copy') 不工作
JavaScript execCommand('copy') not working
我无法使用 execCommand('copy'),试图复制在 multi-select 选项中 selected 的值。我正在 "temp" 中获取值,但临时获取的值未复制或获取到剪贴板中。
{
$propArr=array_unique($properties);
echo "<div class='table-responsive'>";
echo "<table class='bordered'>";
foreach($propArr as $keyProp =>$val){
echo "<tr>";
echo "<td>$val</td><td>";
echo "<select name='propval' id='propval' onclick='showpropval(this.value);' class='form-control' multiple>";
foreach($values as $k => $v){
if($val==$k){
foreach($v as $kv =>$fval){
echo "<option value='$fval'>$fval</option>";
}
}
}
echo "</select>";
echo"</td>";
echo "</tr>";
}
echo "</table>";
echo "</div>";
}
<script>
function showpropval(val)
{
var temp = val;
temp.execCommand("copy");
}
</script>
试试这个:
function showpropval(val) {
var temp = val;
document.execCommand("copy",false,val);
}
我了解到您的意图如下:您想在 select 后立即将 selected 选项的值复制到剪贴板。
当您使用 document.execCommand('copy')
时,您可以复制页面上 select 编辑的任何内容(例如段落中的内容或输入字段本身中的内容)。
然而,selecting <select>
中的选项不被视为 selected 文本。更糟糕的是,如果您想通过 javascript 触发 selecting 文本,则有一些限制:您只能在 <input>
或 [=16= 上调用 .select() ]元素。
我会这样做:将 selected 选项复制到一个单独的(不可见的)输入字段,select 它并从中复制内容。
这里有一个可以作为演示的fiddle:https://jsfiddle.net/Zomry/metcfvcq/13/
我会在这里分解它:
首先,将此元素添加到页面中。这是我们将从中复制内容到剪贴板的输入字段。请注意,我添加了 tabindex -1,因此您无法通过 tab 键访问它。我还包含了 aria-hidden,因此屏幕阅读器知道它应该忽略它。
<input class='copyfrom' tabindex='-1' aria-hidden='true'>
然后通过将输入字段从屏幕上移开使其不可见(如果我尝试显示:none;或其他技巧则无效)
<style>
.copyfrom {
position: absolute;
left: -9999px;
}
</style>
然后将值复制到输入字段,select它并复制它。
var input = document.querySelector("input.copyfrom"); // select the input field
function showpropval(val) {
var selectedValues = getSelectValues(this); // get selected values
input.value = test.join(','); // join them in a comma separated list
input.select(); // select offscreen inputs text
document.execCommand("copy"); // copy it
this.focus(); // focus back on original, so we don't see any glitches
}
// credits to:
function getSelectValues(select) {
var result = [];
var options = select && select.options;
var opt;
for (var i=0, iLen=options.length; i<iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
return result;
}
我遇到过其他 "copy" 命令不起作用的情况。 ExecCommand 返回 true,但未复制该值。在我的例子中,问题是执行命令的函数(准确地说是一个 Promise)。也许是一个小样本(使用 Zomry 的回答中的函数):
function copyToClipboardButtonHandler_Working() {
//copy logic executed directly here works
showpropval('this works');
}
function copyToClipboardButtonHandler_NotWorking() {
//copy logic executed directly here works
myService.doSomeLogicAndReturnPromiseWithAString().then(text =>
showpropval(text) /*this does NOT work'*/
);
}
如果我解释正确,命令必须在人类调用的同一脚本执行迭代中调用。由于 Promise 的回调在其他迭代中,浏览器拒绝它(尽管它说它没有)。我不知道这是不是真的,但代码对我有用,这很好 ;)
好的,我的方法稍微简单一点:
- 创建类型为 'text'
的额外输入
- 在您的函数调用中,将所选选项的值复制到
额外字段
- 给出额外的字段绝对位置并留下 -9999 所以它存在于
dom 但不在可见视口中!
- 做剩下的事!
这是一个例子:
function copyUserName() {
//just_for_copy is my invisible extra field
document.getElementById('just_for_copy').value = document.getElementById('user_phone').value;
var justForCopy = document.getElementById('just_for_copy');
justForCopy.select();
document.execCommand("copy");
}
function CopyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy", false, $temp.val());
$temp.remove();
}
没有直接关系,但似乎是说这个的好地方。使用 document.execCommand() 时,用于提供 "text" 的元素必须在页面上可见。所以使用 display: none;将导致此失败也尝试使元素高度:0;宽度:0;也打破了这个功能。我解决了这个问题,但将元素定位为绝对位置并将其移离屏幕。
希望这对某人有所帮助:-)
感谢@Zomry,我在 Angular 9 上调整了你对 Typescript 的回复,这里是:
copyColor(colorCode: string) {
// funcion que copia al clipboard
const colorClicked = this.findColorObject(colorCode);
const copyText = document.getElementById(`${colorClicked.id}`) as HTMLInputElement;
copyText.select();
document.execCommand('copy');
}
.input-color{
/* visibility: hidden;
height: 0px; */
position: absolute;
left: -9999px;
}
<div *ngFor="let color of ColorList" class="col-4 p-0">
<div (click)="copyColor(color.color)">
<p>{{color.name}}</p>
<input class="input-color" id="{{color.id}}" value="{{color.color}}" type="text" tabindex='-1' aria-hidden='true'/>
<p>{{color.color}}</p>
</div>
</div>
我试图隐藏输入,但直到我在您的 CSS 定位中找到这个解决方案,它才起作用。我希望有人觉得它有用。
2021 年,当与 Internet Explorer 的兼容性最终(几乎)无关紧要时,可能的最简单 解决方案是:
function copyToClipboard(value) {
navigator.clipboard.writeText(value)
}
我无法使用 execCommand('copy'),试图复制在 multi-select 选项中 selected 的值。我正在 "temp" 中获取值,但临时获取的值未复制或获取到剪贴板中。
{
$propArr=array_unique($properties);
echo "<div class='table-responsive'>";
echo "<table class='bordered'>";
foreach($propArr as $keyProp =>$val){
echo "<tr>";
echo "<td>$val</td><td>";
echo "<select name='propval' id='propval' onclick='showpropval(this.value);' class='form-control' multiple>";
foreach($values as $k => $v){
if($val==$k){
foreach($v as $kv =>$fval){
echo "<option value='$fval'>$fval</option>";
}
}
}
echo "</select>";
echo"</td>";
echo "</tr>";
}
echo "</table>";
echo "</div>";
}
<script>
function showpropval(val)
{
var temp = val;
temp.execCommand("copy");
}
</script>
试试这个:
function showpropval(val) {
var temp = val;
document.execCommand("copy",false,val);
}
我了解到您的意图如下:您想在 select 后立即将 selected 选项的值复制到剪贴板。
当您使用 document.execCommand('copy')
时,您可以复制页面上 select 编辑的任何内容(例如段落中的内容或输入字段本身中的内容)。
然而,selecting <select>
中的选项不被视为 selected 文本。更糟糕的是,如果您想通过 javascript 触发 selecting 文本,则有一些限制:您只能在 <input>
或 [=16= 上调用 .select() ]元素。
我会这样做:将 selected 选项复制到一个单独的(不可见的)输入字段,select 它并从中复制内容。
这里有一个可以作为演示的fiddle:https://jsfiddle.net/Zomry/metcfvcq/13/
我会在这里分解它:
首先,将此元素添加到页面中。这是我们将从中复制内容到剪贴板的输入字段。请注意,我添加了 tabindex -1,因此您无法通过 tab 键访问它。我还包含了 aria-hidden,因此屏幕阅读器知道它应该忽略它。
<input class='copyfrom' tabindex='-1' aria-hidden='true'>
然后通过将输入字段从屏幕上移开使其不可见(如果我尝试显示:none;或其他技巧则无效)
<style>
.copyfrom {
position: absolute;
left: -9999px;
}
</style>
然后将值复制到输入字段,select它并复制它。
var input = document.querySelector("input.copyfrom"); // select the input field
function showpropval(val) {
var selectedValues = getSelectValues(this); // get selected values
input.value = test.join(','); // join them in a comma separated list
input.select(); // select offscreen inputs text
document.execCommand("copy"); // copy it
this.focus(); // focus back on original, so we don't see any glitches
}
// credits to:
function getSelectValues(select) {
var result = [];
var options = select && select.options;
var opt;
for (var i=0, iLen=options.length; i<iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
return result;
}
我遇到过其他 "copy" 命令不起作用的情况。 ExecCommand 返回 true,但未复制该值。在我的例子中,问题是执行命令的函数(准确地说是一个 Promise)。也许是一个小样本(使用 Zomry 的回答中的函数):
function copyToClipboardButtonHandler_Working() {
//copy logic executed directly here works
showpropval('this works');
}
function copyToClipboardButtonHandler_NotWorking() {
//copy logic executed directly here works
myService.doSomeLogicAndReturnPromiseWithAString().then(text =>
showpropval(text) /*this does NOT work'*/
);
}
如果我解释正确,命令必须在人类调用的同一脚本执行迭代中调用。由于 Promise 的回调在其他迭代中,浏览器拒绝它(尽管它说它没有)。我不知道这是不是真的,但代码对我有用,这很好 ;)
好的,我的方法稍微简单一点:
- 创建类型为 'text' 的额外输入
- 在您的函数调用中,将所选选项的值复制到 额外字段
- 给出额外的字段绝对位置并留下 -9999 所以它存在于 dom 但不在可见视口中!
- 做剩下的事!
这是一个例子:
function copyUserName() {
//just_for_copy is my invisible extra field
document.getElementById('just_for_copy').value = document.getElementById('user_phone').value;
var justForCopy = document.getElementById('just_for_copy');
justForCopy.select();
document.execCommand("copy");
}
function CopyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy", false, $temp.val());
$temp.remove();
}
没有直接关系,但似乎是说这个的好地方。使用 document.execCommand() 时,用于提供 "text" 的元素必须在页面上可见。所以使用 display: none;将导致此失败也尝试使元素高度:0;宽度:0;也打破了这个功能。我解决了这个问题,但将元素定位为绝对位置并将其移离屏幕。
希望这对某人有所帮助:-)
感谢@Zomry,我在 Angular 9 上调整了你对 Typescript 的回复,这里是:
copyColor(colorCode: string) {
// funcion que copia al clipboard
const colorClicked = this.findColorObject(colorCode);
const copyText = document.getElementById(`${colorClicked.id}`) as HTMLInputElement;
copyText.select();
document.execCommand('copy');
}
.input-color{
/* visibility: hidden;
height: 0px; */
position: absolute;
left: -9999px;
}
<div *ngFor="let color of ColorList" class="col-4 p-0">
<div (click)="copyColor(color.color)">
<p>{{color.name}}</p>
<input class="input-color" id="{{color.id}}" value="{{color.color}}" type="text" tabindex='-1' aria-hidden='true'/>
<p>{{color.color}}</p>
</div>
</div>
我试图隐藏输入,但直到我在您的 CSS 定位中找到这个解决方案,它才起作用。我希望有人觉得它有用。
2021 年,当与 Internet Explorer 的兼容性最终(几乎)无关紧要时,可能的最简单 解决方案是:
function copyToClipboard(value) {
navigator.clipboard.writeText(value)
}