简体   繁体   English

文档execCommand副本不能与AJAX一起使用

[英]document execCommand copy not working with AJAX

I can't copy the generated link directly (without ctrl+C) I am usign document.execCommand('copy') but it seems it has no effect. 我不能直接复制生成的链接(没有ctrl + C)我是usign document.execCommand('copy')但它似乎没有效果。 If code has no AJAX then its working pefectly . 如果代码没有AJAX那么它的工作就完美了 Here's the 这是

HTML : HTML

<div class="permalink-control"> </div>

JQUERY : JQUERY

    $(".permalink-control")
          .append(
            '<div class="input-group">' +
            '    <span class="input-group-btn"><button type="button" class="btn btn-default" title="Get Permalink"><span class="glyphicon glyphicon-link"></span></button></span>' +
            '    <input type="text" class="form-control">' +
            '</div>'
          );
        $(".permalink-control input")
          .hide()
          .focus(function () {
            // Workaround for broken selection: https://stackoverflow.com/questions/5797539
            var $this = $(this);
            $this.select()
              .mouseup(function () {
                $this.unbind("mouseup");
                return false;
              });
          });
        $(".permalink-control button")
          .click(function () {
            var $this = $(this);
            $.ajax({
              url: "https://api-ssl.bitly.com/shorten",
              dataType: "jsonp",
              data: {
                longUrl: window.location.href,
                access_token: "your access token",
                format: "json"
              },
              success: function (response) {
                var longUrl = Object.keys(response.results)[0];
                var shortUrl = response.results[longUrl].shortUrl;
                if (shortUrl.indexOf(":") === 4) {
                  shortUrl = "https" + shortUrl.substring(4);
                }
                $this.parents(".permalink-control")
                  .find("input")
                  .show()
                  .val(shortUrl)
                  .focus();
              },
              async:false
            });
          });

UPDATE: 更新:

How do I copy to the clipboard in JavaScript? 如何使用JavaScript复制到剪贴板?

is not answer to my question as My code also copies without using ctrl+C if AJAX is not there. 没有回答我的问题,因为如果没有AJAX,我的代码也会在没有使用ctrl + C的情况下进行复制。 However when I am using AJAX document.execCommand('copy') is not working. 但是,当我使用AJAX document.execCommand('copy')不起作用时。

The reason for this is clearly stated in W3 specs : W3规范中明确说明了这一点的原因:

Copy and cut commands triggered through a scripting API will only affect the contents of the real clipboard if the event is dispatched from an event that is trusted and triggered by the user, or if the implementation is configured to allow this. 如果从用户信任和触发的事件调度事件,或者实现配置为允许此操作,则通过脚本API触发的复制和剪切命令将仅影响实际剪贴板的内容。

But, having said that we can try to fool around the browser by copying text when a user does some interaction . 但是,说过我们可以尝试通过when a user does some interaction复制文本来欺骗浏览器。

In this case since you are looking for a click event I assume you're user is interacting with mouse 在这种情况下,因为您正在寻找click事件,我假设您的用户正在与mouse交互

So, what if I attach a $(window).blur() or $(document).click() event after the ajax call is resolved? 那么,如果我在解析ajax调用后附加$(window).blur()$(document).click()事件怎么办?

That's right, Since, the user has to blur at some point to use the copy selection, user will initiate a blur() or click() (depending on your need) and we can copy text to our clipboard. 这是正确的,因为用户必须在某些时候blur使用副本选择,用户将启动blur() or click() (depending on your need) ,我们可以将文本复制到剪贴板。

Here's the HACKY DEMO 这是HACKY DEMO

 $(document).ready(function(){ var shortUrl; $(".permalink-control") .append( '<div class="input-group">' + ' <span class="input-group-btn"><button type="button" class="btn btn-default" title="Get Permalink"><span class="glyphicon glyphicon-link"></span></button></span>' + ' <input type="text" class="form-control">' + '</div>' ); $(".permalink-control input") .hide() .focus(function () { // Workaround for broken selection: http://stackoverflow.com/questions/5797539 var $this = $(this); $this.select(); document.execCommand('copy'); $this.mouseup(function () { $this.unbind("mouseup"); return false; }); }); $(".permalink-control button") .click(function () { var shortUrl =""; var $this = $(this); $.ajax({ url: "https://api-ssl.bitly.com/shorten", dataType: "jsonp", data: { longUrl: window.location.href, access_token: "48ecf90304d70f30729abe82dfea1dd8a11c4584", format: "json" }, success: function (response) { var longUrl = Object.keys(response.results)[0]; shortUrl = response.results[longUrl].shortUrl; if (shortUrl.indexOf(":") === 4) { shortUrl = "https" + shortUrl.substring(4); } $this.parents(".permalink-control") .find("input") .show() .val(shortUrl) .focus(); } }).done(function(){ $(window).blur(function(){ document.execCommand('copy'); $(window).off('blur');// make sure we don't copy anything else from the document when window is foucussed out }); }) }); }) 
 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="permalink-control"></div> <div class"log"></div> 

PS: This has been tested in chrome. PS:这已经过镀铬测试。

I had the same problem. 我有同样的问题。 I solved it rather primitively: inside the handler of a click event, you can run an interval that will check the variable where ajax will insert the value after the server responds. 我原来解决了这个问题:在click事件的处理程序中,你可以运行一个间隔来检查ajax在服务器响应后插入值的变量。 After the answer is received, we stop the interval and start the work with the clipboard. 收到答案后,我们停止间隔并开始使用剪贴板。 No problem, because the user himself starts the interval after the click, without any callbacks. 没问题,因为用户自己在点击后开始间隔,没有任何回调。

Simple jQuery example: 简单的jQuery示例:

var ajaxResponse;

function copyText(copiedText){
  $('<textarea class="copied-text">' + copiedText + '</textarea>').appendTo('body');

  if ( navigator.userAgent.match(/ipad|iphone/i) ) {
    var range = document.createRange(),
        textArea = $('.copied-text')[0];
    range.selectNodeContents(textArea);
    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    textArea.setSelectionRange(0, 999999);
  } else {
    $('.copied-text').select();
  }

  document.execCommand('copy');
  $('.copied-text').remove();
};

function myAjaxFunc(){
  $.ajax({
    type: 'POST',
    url: yourUrl,
    data: yourData,
    success: function(data){
      ajaxResponse = data;
    }
  });
};

$('.your-button').on('click', function(){
  myAjaxFunc();
  var ajaxCheckTimer = setInterval(function(){
    if ( ajaxResponse ) {
      copyText(ajaxResponse);
      clearInterval(ajaxCheckTimer);
    };
  }, 100);
});

In this example, when clicking on a button, we send some data to the server and start the interval with checking the value of the ajaxResponse variable. 在此示例中,当单击按钮时,我们将一些数据发送到服务器并通过检查ajaxResponse变量的值来启动间隔。

After the response from the server is received, the response of the server is written to this variable, after which the condition in the interval becomes true and the text copy function is called, and the server response variable is specified as the parameter: copyText(ajaxResponse); 收到服务器的响应后,服务器的响应将写入此变量,之后间隔中的条件变为true,并调用文本复制函数,并将服务器响应变量指定为参数: copyText(ajaxResponse); . The interval stops. 间隔停止。

The copyText function creates an textarea on the page with the value of the ajaxResponse variable, copies this value from the field to the clipboard, and deletes the field from the page. copyText函数在页面上使用ajaxResponse变量的值创建textarea,将该值从字段复制到剪贴板,并从页面中删除该字段。


UPDATE 01.07.19 更新01.07.19

For correct copying to the clipboard on iOS, add the attribute contenteditable with the value true to the text field: 为了正确地复制到iOS上的剪贴板,添加属性contenteditable与价值true文本字段:

$('<textarea class="copied-text" contenteditable="true">' + copiedText + '</textarea>').appendTo('body');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM