剪贴板副本在jquery ajax成功方法中不起作用
我想将卡号复制到剪贴板中,以便将其粘贴到记事本中。 如果在浏览器的开发人员工具栏中尝试过,我从互联网上获得的代码效果很好。 但是,如果我将该代码添加到我的Javascript文件并运行该项目,那么它将无法正常工作。 以下是代码:
$.ajax({ type: "POST", url: '@Url.Action("CopyToClipboard", "MyAccountSurface")', data: { controlId: controlId }, dataType: 'json', success: function(data) { var $temp = $(""); $("body").append($temp); $temp.val(data.CardNumber).select(); document.execCommand("copy"); $temp.remove(); alert('copied successfully'); } });
如果要在使用Ajax单击时复制到剪贴板
您要单击的元素几乎没有事件: mousedown和click 。 它们按此顺序触发。 这意味着您可以在第一个请求中发送ajax请求,并在最后一个中使用结果,在这种情况下,您将不会遇到安全问题。
让我分享工作实例:
$link.on("mousedown", function() { var url = $(this).data("url"); var $temp = $(""); $.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) })
你需要100ms的超时来等待ajax响应。 它可以像你想要的那样改进。
固定和消极的位置 – 我想你知道我们为什么需要它。
那么,你在复制什么? 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'); }
更新:
执行document.execCommand
必须进行用户交互。 因此,在您的情况下,无法从AJAX响应中复制文本。 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 = $(""); $("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(); }
Below button will be enabled once the data is available from AJAX
var response; // recursively using setTimeout to wait for response var recCopy = function (){ if(response){ copy(response); return; } else { setTimeout(recCopy,2000); // for eg 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可以递归地用于检查响应。 收到响应后,可以执行复制到剪贴板。
由于这不是用户交互,因此无法正常工作。
我们可以实现的解决方法是在用户想要复制数据并将数据放在某个文本区域或输入框中的区域中立即从ajax调用获取数据。
并且,在click事件中,我们可以复制剪贴板中的数据。
//按钮的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);});