JavaScript execCommand('copy') 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45117731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:55:12  来源:igfitidea点击:

JavaScript execCommand('copy') not working

javascriptexeccommand

提问by Rajesh k

I am unable to use the execCommand('copy'), trying to copy value which is selected in multi-select option. iam getting value in "temp" but the value which is getting in temp not copying or getting in clipboard.

我无法使用 execCommand('copy'),试图复制在多选选项中选择的值。我在“temp”中获取值,但在 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>

回答by Zomry

I understand that your intention is the following: you want to copy the values of the selected options to the clipboard as soon as you select it.

我了解您的意图如下:您希望在选择后立即将所选选项的值复制到剪贴板。

When you use document.execCommand('copy'), you copy whatever is selected on the page (such as content in a paragraph or in an input field itself).

使用 时document.execCommand('copy'),您复制页面上选择的任何内容(例如段落中的内容或输入字段本身中的内容)。

The catch is however that selecting options in <select>is not considered to be selected text. Worse yet, if you would like to trigger selecting text via javascript, there are some restrictions: you can only call .select()on an <input>or a <textarea>element.

然而,问题是在中选择选项<select>不被认为是选定的文本。更糟糕的是,如果你想通过 javascript 触发选择文本,有一些限制:你只能在一个或一个元素上调用.select()<input><textarea>

Here is what I would do: copy the selected options to a separate (not visible) input-field, select it and copy the content from that.

这是我要做的:将选定的选项复制到一个单独的(不可见的)输入字段,选择它并从中复制内容。

Here is a fiddle that can serve as a demo: https://jsfiddle.net/Zomry/metcfvcq/13/

这是一个可以作为演示的小提琴:https: //jsfiddle.net/Zomry/metcfvcq/13/

I wil break it down here:

我将在这里分解它:

First, add this element to the page. This is the input-field where we will copy the content from to the clipboard. Note that I have added tabindex -1 so you cannot reach it via tab key. I also included aria-hidden so screenreaders know it should ignore this.

首先,将此元素添加到页面。这是我们将内容复制到剪贴板的输入字段。请注意,我添加了 tabindex -1,因此您无法通过 Tab 键访问它。我还包括了 aria-hidden 以便屏幕阅读器知道它应该忽略这一点。

<input class='copyfrom' tabindex='-1' aria-hidden='true'>

Then make the input field invisible by putting it off screen (did not work if I tried display: none; or other tricks)

然后通过将其移出屏幕使输入字段不可见(如果我尝试 display: none; 或其他技巧,则不起作用)

<style>
    .copyfrom {
        position: absolute;
        left: -9999px;
    }
</style>

Then copy the value to the input field, select it and copy it.

然后将值复制到输入字段,选择它并复制它。

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: https://stackoverflow.com/questions/5866169/how-to-get-all-selected-values-of-a-multiple-select-box
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;
}

回答by Sielu

I had other case of "copy" command not working. ExecCommand returned true, but the value was not copied. In my case the problem was the function which executed the command (a Promise, to be exact). Maybe a small sample (using the function from Zomry's answer):

我还有其他“复制”命令不起作用的情况。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'*/
  );
}

If I interpret correctly, command has to be invoked in the same script execution iteration that was invoked by a human. Since Promise's callback is in other iteration, browser denies it (although it says it doesn't). I do not know if this is true, but the code works for me, which is fine ;)

如果我解释正确,则必须在人类调用的同一脚本执行迭代中调用命令。由于 Promise 的回调在其他迭代中,浏览器拒绝它(尽管它说它没有)。我不知道这是否属实,但代码对我有用,这很好;)

回答by Alireza Noori

ok, my approach is a little bit easier:

好的,我的方法稍微简单一点:

  1. create an extra input with type 'text'
  2. on your function call copy the value of the selected option to the extra field
  3. give extra field position absolute and left -9999 so it exists in dom but not in the visible viewport!
  4. do the rest!
  1. 创建一个类型为 'text' 的额外输入
  2. 在您的函数调用中,将所选选项的值复制到额外的字段
  3. 给额外的字段位置绝对和左 -9999 所以它存在于 dom 但不在可见视口中!
  4. 做剩下的!

here's an example:

这是一个例子:

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");
}

回答by Hina Azhar

function CopyToClipboard(element) {

功能复制到剪贴板(元素){

            var $temp = $("<input>");
            $("body").append($temp);
            $temp.val($(element).text()).select();
            document.execCommand("copy", false, $temp.val());
            $temp.remove();




        }

回答by john

Not directly related but seems like a good place to say this. When using the document.execCommand(), the element that is being used to supply the "text" must be visible on the page. So using display: none; will cause this to fail also trying to make the element height: 0; width: 0; also breaks this function. I got round this but positioning the element absolute and moving it far off the screen.

没有直接关系,但似乎是说这个的好地方。使用 document.execCommand() 时,用于提供“文本”的元素必须在页面上可见。所以使用 display: none; 将导致此失败也试图使元素高度:0; 宽度:0;也打破了这个功能。我解决了这个问题,但是将元素绝对定位并将其移离屏幕很远。

Hope this helps someone :-)

希望这对某人有所帮助:-)

回答by Mariel Quezada

thanks to @Zomry I adapted your response to Typescript on Angular 9 and here is:

感谢@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>

I was trying to hidde the input but it doesn′t work until i found this solution in your CSS positioning. I hope someone find it usefull.

我试图隐藏输入但它不起作用,直到我在你的 CSS 定位中找到这个解决方案。我希望有人觉得它有用。

回答by ledaivuong

Try this:

尝试这个:

function showpropval(val) {
    var temp = val;
    document.execCommand("copy",false,val);
}