剪贴板副本在jquery ajax成功方法中不起作用

时间:2016-12-28 11:25:21

标签: javascript jquery

我想将卡号复制到剪贴板中,以便将其粘贴到记事本中。如果在浏览器的开发人员工具栏中试过,我从互联网上获得的代码效果很好。但是,如果我将该代码添加到我的Javascript文件并运行该项目,那么它不起作用。以下是代码:

$.ajax({
  type: "POST",
  url: '@Url.Action("CopyToClipboard", "MyAccountSurface")',
  data: {
    controlId: controlId
  },
  dataType: 'json',
  success: function(data) {
    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val(data.CardNumber).select();
    document.execCommand("copy");
    $temp.remove();
    alert('copied successfully');
  }
});

7 个答案:

答案 0 :(得分:2)

如果您想在单击Ajax时复制到剪贴板中

您要单击的元素有几个事件:鼠标单击。然后按此顺序触发它们。这意味着您可以在第一个请求中发送ajax请求,并在最后一个结果中处理结果,在这种情况下,您将不会遇到安全问题。

让我分享工作示例:

  $link.on("mousedown", function() {
    var url = $(this).data("url");
    var $temp = $("<input id='copy_container' style='position:fixed;left:-200px;'>");

    $.ajax({
      url: url,
      dataType: "json",
      success: function (data) {
        $("body").append($temp);
        $temp.val(data.text);
      }
    })
  })

  $link.on("click", function() {
    setTimeout(function() {
      var $input = $("input#copy_container");
      if ($input.length && $input.val().length > 0) {
        $input.select();
        document.execCommand("copy");
        $input.remove();
      }
    }, 100)
  })

您需要100毫秒的超时时间来等待ajax响应。可以根据需要进行改进。

固定和否定的立场-我想您知道我们为什么需要它。

答案 1 :(得分:1)

嗯,你在复制什么? document.execCommand("copy");首先需要选择(突出显示)某些内容。

我认为在您的示例中,select遵循.val()。但为了实现这一点,你需要选择一个元素,而不是它的价值。

$temp.val(data.CardNumber);
$temp.select();

copied = document.execCommand("copy");
$temp.remove();

if(copied){
    alert('copied successfully');
}else{
    alert('something went wrong');
}

答案 2 :(得分:1)

<强>更新

执行document.execCommand时必须进行用户互动。 因此,在您的情况下,无法从AJAX Response复制文本。 It is the security measure that browsers agreed upon.

参考W3C API

  

仅通过脚本API触发的复制和剪切命令   如果调度事件,则会影响实际剪贴板的内容   来自用户信任和触发的事件,或者是   实现配置为允许此操作。

用户互动的解决方法

已添加步骤:

  • 使用相对位置放置远离网页的文本框。
  • 添加处于禁用状态的按钮。一旦数据可用,重新启用按钮。
  • 点击按钮,您可以执行document.execCommand,因为您直接与浏览器进行互动(Hence no security issue as mentioned in API

$(document).ready(function() {
  $.ajax({
    url: 'https://jsonplaceholder.typicode.com' + '/posts/1',
    method: 'GET' 
  }).then(function(data) {
    console.log(data);
    $('#toBeCopied').val(data.title);
    $("#copyIt").attr('disabled', null);
  });

  
});
function copyToClipboard(){
    var $temp = $("<input />");
    $("body").append($temp);
    $temp.val($("#toBeCopied").val()).select();
    var result = false;
    try {
        result = document.execCommand("copy");
    } catch (err) {
        console.log("Copy error: " + err);
    }
    $temp.remove();
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" value="dummy" id="toBeCopied" style="display:none; position: relative; left: -1000px;">
<b>Below button will be enabled once the data is available from AJAX</b>
<button id="copyIt" onclick="copyToClipboard()" disabled>Copy To Clipboard</button>

答案 3 :(得分:1)

var response;

// recursively using setTimeout to wait for response 
var recCopy = function (){
    if(response){
        copy(response); 
        return;
    }     
    else {
        setTimeout(recCopy,2000); // for e.g. 2ms
    }
}

function copy(value) {
    var tempInput = document.createElement("input");
    tempInput.style = "position: absolute; left: -1000px; top: -1000px";
    tempInput.value = value;
    document.body.appendChild(tempInput);
    tempInput.select();
    try {
            var successful = document.execCommand('copy',false,null);
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copying text command was ' + msg);
        } catch (err) {
            alert('Oops, unable to copy to clipboard');
        }
    document.body.removeChild(tempInput);
}

$('.copyToClipboard').on('mousedown',function (e){
        $.ajax({
          url: "https://www.example.com/xyz",
          data: {
             formData :formData
          },
          type : 'post',
          success: function (data) {     
            response = data;  // on success, update the response
          } 
        }) 
});

$('.copyToClipboard').on('click',function (e){
    recCopy();
});

ajax调用和复制响应需要单独处理(例如,这里已处理了click和mousedown事件)。
setTimeout可以递归地用于检查响应。收到回复后,可以执行复制到剪贴板。

答案 4 :(得分:0)

由于这不是用户互动,因此不起作用。

我们可以实现的解决方法是在用户想要复制数据和区域的区域中尽快从ajax调用获取数据。将数据放在某个textarea或输入框中。

并且,在点击事件中,我们可以复制剪贴板中的数据。

//按钮的mouseenter事件

$("#jq-copy-txt").on('mouseenter', function() {
    $.ajax({
      url: 'url',
      method: 'GET'
    }).then(function(data) {
       let copyFrom = document.getElementById("jq-cpy-txt-area"); 
        document.body.appendChild(copyFrom);
        copyFrom .textContent = data.title;
    });
});

//点击用户点击的事件

$("#jq-copy-txt").on('click', function() {

   var fn = function() {
      let copyFrom = document.getElementsByTagName("textarea")[0];
      copyFrom.select();
      document.execCommand("copy");
    };
    setTimeout(fn, 1000);});

答案 5 :(得分:0)

@Anton所说的是好的,但是这都是不好的做法,因为您依赖服务器在给定的时间给您响应,这很不好,您可以在所有后端复杂的大型网站中看到它们只是将其放在HTML对象中,以便用户可以通过ctrl + c或通过单击按钮进行复制,这与Antons的方式稍有不同

$('#btn').on('click', function(e){

    var url = 'Your-link.com';
    var $temp = $("<input id='copy_container' 
        style='position:fixed;left:-200px;'>");
    $.ajax({
      type: "POST",
      url: url,
      success: function(res) {
        $("body").append($temp);
        $temp.val(res);
      },
      error: function() {
         //handle error and do something
      }
    });
    setTimeout(function() {
        var $input = $("input#copy_container");
        if ($input.length && $input.val().length > 0) {
            $input.select();
            document.execCommand("copy");
            $input.remove();
        }
    }, 500)
});   

这样,您不需要重用事件侦听器,但是就像我之前所说的那样,它远非完美。 最好将其放在显示给用户的HTML元素中。

答案 6 :(得分:0)

这就是我的做法。您可以将值从 ajax 调用返回成功设置到剪贴板(第一个按钮),或者在需要时将文本从 textarea 复制到剪贴板(第二个按钮)。

<div>
        <div>
            <label>Content</label>
        </div>
        <div>
            <button type="button" onclick="fnGenerate()">Retrieve and Copy To Clipboard</button>
        </div>
        <div>
            <button type="button" onclick="fnCopy()">Copy To Clipboard</button>
        </div>
        <div>
            <div>
                <textarea cols="50" rows="8" id="Content"></textarea>
            </div>
        </div>
    </div>

对于js部分

function fnGenerate() {
        $.ajax({                
            type: 'POST',
            dataType: 'json',
            ............
            ............
            url: 'someUrl',                  
            success: function (data, textStatus, xhr) {
                $('#Content').val(data);
                $('#Content').select();
                document.execCommand('copy');
            },
            error: function (xhr) {
                //Do Something to handle error
                var error = xhr.responseText;
            }
        });
    }

    function fnCopy() {
        $("#Content").select();
        document.execCommand('copy');
    }