语境

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

一个更开放(但没有代码)的 related question 在 Programmers 上被否决了。所以我为这个问题做了一个 JsFiddle example ,但那个 JsFiddle 例子可能非常错误。



这里有很多关于在Javascript中复制到剪贴板的问题,例如this一个。他们中的一些人提到了我正在尝试使用的 Zeno Rocha 的 clipboard.js

带解释的代码

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

// 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 应该返回相关跨度的文本值。

问题

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

完整的 MVCE 代码是 this JsFiddle

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

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

为了让事情变得更复杂,我实际上在 MELT monitor(但不是在 this JsFiddle ...)中有两个 CSS 类 mom_itemref_clmom_itemval_cl,我想这样做。

附注。我在这里复制代码时弄乱了 JsFiddle。我更新了,
https://jsfiddle.net/bstarynk/g2notLd7/132/

注意。我对仅适用于最近的 Firefox 和 Chrome 的答案感到满意。

最佳答案

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

首先,让我们更正更新后的 fiddle 中的错字,在第 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 属性设置为您希望在单击该元素时复制 clipboard.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;

You can find a working fiddle here.

关于javascript - 在 Javascript 中以编程方式复制和选择跨度(使用 clipboard.js),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35340862/

10-12 13:48