繁体   English   中英

在Javascript中以编程方式复制和选择范围(使用clipboard.js)

[英]copying & selecting a span programmatically in Javascript (with clipboard.js)

上下文

我正在编码的真正的自由软件(GPLv3)应用程序(激发这个问题)是github上的MELT监视器 (FWIW,我在2016年2月11 日的提交56a83d358d3966eddb55 ... )。 它在Linux / x86_64 / Debian,Firefox / 44,JQuery-2.2.0,JqueryUI 1.11.4,clipboard.js 1.5.8 ....

一个更开放(但没有代码)的相关问题被低估了程序员。 所以我为这个问题做了一个JsFiddle示例 ,但是JsFiddle示例可能非常错误。

我有一个(动态生成的)HTML文档,其中一些<span> -s of class='momitemref_cl'<span class='momitemref_cl'>this</span>等......(此类跨度的内部内容始终是像this单词,实际上是某些DSL中的变量名称或标识符)。 我的目标是为每个这样的跨度创建一个动态生成的菜单 ,以便对它们进行一些操作 ,特别是:每次出现该单词时都会出现hilight ,然后将该单词复制并选择到浏览器和桌面的剪贴板。

这里有很多关于在Javascript中复制到剪贴板的问题,例如这个问题。 其中有几个提到我试图使用的Zeno Rocha的clipboard.js

代码说明

解释一些JsFiddle:我正在创建JQueryUI 菜单

// make a menu for the given span
function make_menu(spa) {
  console.log("make_menu spa=", spa);
  var name = $(spa).text();
  mom_menuitemcount++;
  var menuid = "menuid_" + mom_menuitemcount;
  console.log("make_menu name=", name, " menuid=", menuid);
  $maindiv.after("<ul class='mommenu_cl' id='" + menuid + "'>"
               + "<li class='ui-state-disabled'>* <i>" + name + "</i> *</li>"
    // the text inside the following <li> matters
    + "<li>Hilight</li>" + "<li>Copy</li>" + "</ul>");
  var mymenu = $('#' + menuid);
  mymenu.menu({
    select: function(ev, ui) {
      var uitem = ui.item;
      var utext = uitem.text();
      console.log("mymenu-select ev=", ev, " ui=", ui, " name=", name,
        " uitem=", uitem, " utext=", utext);
      switch (utext) {
        case "Hilight":
          $maindiv.find(".momitemref_cl").each(function(ix, el) {
            var etext = $(el).text();
            console.log("hilighting el=", el, " etext=", etext);
            if (etext == name) {
              $(el).toggleClass("momhilight_cl");
            }
          });
          break;
        case "Copy":
          //// what should go here?
          break;
      };
      setTimeout(200, destroy_menu);
    },
    position: {
      my: "left top",
      at: "bottom left",
      of: spa
    }
  });
  mom_menuitem = mymenu;
  console.log("make_menu spa=", spa, " mymenu=", mymenu);
  return mymenu;
}

在上面的代码中,我不知道该放//// what should go here? ; 也许它可能类似于:

uitem.select();
document.execCommand('Copy');

但AFAIU这不能按预期工作,我觉得剪贴板操作需要用户事件(例如鼠标点击或向下)来触发它们。

剪贴板初始化为

$clipboardh = new Clipboard(".momitemref_cl", {
  text: function (trig) {
    console.log("clipboard text trig=", trig);
    /// some code is missing here probably
  };
});

我想(但我不确定) /// some code is missing here probably应该返回相关跨度的文本值。

问题

所以我不知道如何将span的内容复制到剪贴板( //// what should go here? ....)以及如何将其文本放入剪贴板( /// some code is missing here probably 。 ...)

完整的MVCE代码就是这个JsFiddle

换句话说, 如何使用JQueryUI菜单项中的clipboard.jsspan的内容复制到浏览器的剪贴板?


也许整个方法都是错误的,也许我应该使用contextmenu (但是,如何仅针对class='momitemref_cl' span -s来定制它?)

为了使事情变得更复杂,我实际上已经在MELT监视器中 (但不是在这个JsFiddle中 )两个CSS类mom_itemref_clmom_itemval_cl ,我想表现得同样如此。


PS。 我在这里复制代码时搞砸了JsFiddle。 我更新了它, https://jsfiddle.net/bstarynk/g2notLd7/132/

NB。 我对仅在最近的Firefox和Chrome上工作的答案感到满意。

需要将Clipboard.js附加到触发复制事件的元素。 在您的情况下,这是mommenu_cl菜单中的<li>Copy</li>元素,您可以在右键单击momitemref_cl时动态创建该momitemref_cl 创建菜单本身时,可以动态地将clipboard.js附加到Copy li 在销毁菜单时,您还必须销毁剪贴板。

首先,让我们在第87行修正你更新的小提琴中的拼写错误:

curmenu[0].stle.left = Math.round(ev.pageY) + 5;

然后,从DOM的就绪处理程序中删除剪贴板,我们将其移至make_menu函数:

$(document).ready(function() {
  $maindiv = $('#maindiv_id');
  // no clipboard initialization here
  console.log("our document ready function");
  ...
});

接下来,在脚本的顶部,您首先声明$clipboardh ,将其初始化为false 稍后,您将检查以确保您只附加剪贴板,以防它当前未连接。

/// javascript code
var $clipboardh = false;

make_menu函数中,为<li>Copy</li>元素提供class="copy"属性,以便您可以轻松地将clipboard.js附加到它,并将data-clipboard-text属性设置为您想要剪贴板的值。单击元素时要复制的js。

由于name变量包含要复制的文本值,因此菜单将如下所示:

$maindiv.after("<ul class='mommenu_cl' id='" + menuid + "'>" +
        "<li class='copy' data-clipboard-text='" + name + "'>Copy</li>" + 
    "</ul>");

接下来,在make_menu函数中的此代码之后,附加clipboard.js,仅当它尚未附加时:

if ($clipboardh === false){
  console.log("creating the clipboard");
  $clipboardh = new Clipboard('.copy');

  // some optional event handlers for debugging
  $clipboardh.on('success', function(e) {
      console.info('Action:', e.action);
      console.info('Text:', e.text);
      console.info('Trigger:', e.trigger);

      e.clearSelection();
  });

  $clipboardh.on('error', function(e) {
      console.error('Action:', e.action);
      console.error('Trigger:', e.trigger);
  });
}

最后,您需要确保在销毁菜单时销毁剪贴板,方法是将其添加到destroy_menu函数的底部:

$clipboardh.destroy();
$clipboardh = false;

你可以在这里找到一个工作小提琴。

从IE以外的任何其他内容复制需要在可编辑元素上进行。 处理此问题的最常用方法是创建隐藏的文本区域,然后将内容放入文本区域

textArea.select();
document.execCommand('Copy');

对于IE,你可以使用

if(window.clipboardData){
    window.clipboardData.setData('Text',
        uitem.innerText);
}

我写了一篇非常广泛的文章,解释了这一切是如何工作的,我在GitHub上有一个带有结果代码的项目。

http://blog.dmbcllc.com/cross-browser-javascript-copy-and-paste/

我花了几个月的时间来通过搜索Google来解决所有可用的冲突建议,因为你这样做会随着浏览器“成熟”而不断变化。

暂无
暂无

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

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