从Ace编辑器复制文本到剪贴板

3
我正在尝试使用纯JS方法(此处)将Ace Editor框内的文本复制到本地剪贴板。但是,当我点击复制按钮时,会抛出错误:

"TypeError: copyTextarea.select不是一个函数"

并且文本不会复制到我的剪贴板。是否有一种方法可以以某种方式实现这一点(无论是纯JS还是jQuery)?我的代码如下(简化但应该足够):

$('#clipboard').on('click', function() {
  var copyTextarea = document.querySelector('#result-box');
  copyTextarea.select();
  document.execCommand('copy');
});
<button id="clipboard">Copy</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result-box" style="height: 100px; width: 100%; border-radius: 4px; border: 1px solid #DDD;">&lt;!DOCTYPE html&gt; 
  &lt;html&gt; 
  &lt;/html&gt;</div>
<script src="https://cdn.rawgit.com/ajaxorg/ace-builds/master/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
  var editor = ace.edit("result-box");
  editor.getSession().setMode("ace/mode/html");
  editor.setReadOnly(true);
  editor.setShowPrintMargin(false);
  editor.getSession().setUseWrapMode(true);
</script>

P.S.:如果有人知道如何修复关于Ace的某些工作人员等方面的另一个错误,请在下面评论。先感谢您!


请尝试查看 https://apidoc.c9.io/c9v3/#!/api/clipboard - GibboK
@GibboK,不,只要文本区域可见,您可以毫无问题地使用该命令。http://jsfiddle.net/ourcodeworld/wrL0j3xu/1/ - Carlos Delgado
2个回答

7

在编辑器上调用 focusselectAll,在大多数现代浏览器上都可以正常工作。

$('#clipboard').on('click', function() {
  var sel = editor.selection.toJSON(); // save selection
  editor.selectAll();
  editor.focus();
  document.execCommand('copy');
  editor.selection.fromJSON(sel); // restore selection
});
<button id="clipboard">Copy</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result-box" style="height: 100px; width: 100%; border-radius: 4px; border: 1px solid #DDD;">&lt;!DOCTYPE html&gt; 
  &lt;html&gt; 
  &lt;/html&gt;</div>
<script src="https://cdn.rawgit.com/ajaxorg/ace-builds/master/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
  var editor = ace.edit("result-box");
  editor.getSession().setMode("ace/mode/html");
  editor.setReadOnly(true);
  editor.setShowPrintMargin(false);
  editor.getSession().setUseWrapMode(true);
</script>


是的,但之后我该如何取消选择所有内容呢?我希望它看起来无缝,并且不向用户显示任何内部操作(我知道这听起来有点糟糕,但这是我被要求做的)。 - Angelos Chalaris
更新了答案以在复制后恢复选择。 - a user

3

select方法应该作为本地方法在textarea中可用,而你正在使用div (这是ace所需的工作方式)。

从编辑器中检索值,将该值设置为textarea,然后使用您的方法复制内容。

您可以使用getValue来检索Ace的文本:

<button id="clipboard">Copy</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result-box" style="height: 100px; width: 100%; border-radius: 4px; border: 1px solid #DDD;">&lt;!DOCTYPE html&gt; 
  &lt;html&gt; 
  &lt;/html&gt;</div>
<textarea id="clipboard-content"></textarea>
<script src="https://cdn.rawgit.com/ajaxorg/ace-builds/master/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
      var editor = ace.edit("result-box");
      editor.getSession().setMode("ace/mode/html");
      editor.setReadOnly(true);
      editor.setShowPrintMargin(false);
      editor.getSession().setUseWrapMode(true);

      $('#clipboard').on('click', function() {
          var copyTextarea = document.querySelector('#clipboard-content');
          copyTextarea.value = editor.getValue();
          copyTextarea.select();
          document.execCommand('copy');
          // Reset textarea
          copyTextarea.value = "";
      });
</script>

请注意,如果您隐藏了文本区域,那么您使用的复制文本的方法将无法工作。

我建议您改用插件,阅读以下文章以查看可能的解决方案,包括纯JavaScript和使用JS回退的Flash。


非常感谢,这对我来说已经足够好了。动态添加textarea并在复制后删除可以解决问题,而不会使页面与之前看起来有任何区别。 - Angelos Chalaris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接