簡體   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