[英]copying & selecting a span programmatically in Javascript (with clipboard.js)
The real free software (GPLv3) application (motivating this question) that I am coding is the MELT monitor on github (FWIW, I am at commit 56a83d358d3966eddb55... on February 11 th , 2016). 我正在编码的真正的自由软件(GPLv3)应用程序(激发这个问题)是github上的MELT监视器 (FWIW,我在2016年2月11 日的提交56a83d358d3966eddb55 ... )。 It is on Linux/x86_64/Debian, Firefox/44, JQuery-2.2.0, JqueryUI 1.11.4, clipboard.js 1.5.8....
它在Linux / x86_64 / Debian,Firefox / 44,JQuery-2.2.0,JqueryUI 1.11.4,clipboard.js 1.5.8 ....
A more open (but without code) related question was downvoted on Programmers. 一个更开放(但没有代码)的相关问题被低估了程序员。 So I made a JsFiddle example for this very question, but that JsFiddle example is probably very wrong.
所以我为这个问题做了一个JsFiddle示例 ,但是JsFiddle示例可能非常错误。
I have a (dynamically generated) HTML document with some
<span>
-s ofclass='momitemref_cl'
like<span class='momitemref_cl'>this</span>
etc... (the inside content of such spans is always a single word likethis
, actually some variable name or identifier in some DSL of mine).我有一个(动态生成的)HTML文档,其中一些
<span>
-s ofclass='momitemref_cl'
如<span class='momitemref_cl'>this</span>
等......(此类跨度的内部内容始终是像this
单词,实际上是某些DSL中的变量名称或标识符)。 My goal is to have a dynamically generated menu for each such spans to enable some operations on them, in particular: hilight every occurrence of that word, and copy & select the word to the browser's and desktop's clipboard.我的目标是为每个这样的跨度创建一个动态生成的菜单 ,以便对它们进行一些操作 ,特别是:每次出现该单词时都会出现hilight ,然后将该单词复制并选择到浏览器和桌面的剪贴板。
There are many questions here about copying to the clipboard in Javascript , such as this one. 这里有很多关于在Javascript中复制到剪贴板的问题,例如这个问题。 Several of them mention Zeno Rocha's clipboard.js which I am trying to use.
其中有几个提到我试图使用的Zeno Rocha的clipboard.js 。
To explain some of the JsFiddle: I am creating the JQueryUI menu with 解释一些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;
}
In the above code, I don't know what to put in //// what should go here?
在上面的代码中,我不知道该放
//// what should go here?
; ; perhaps it might be something similar to:
也许它可能类似于:
uitem.select();
document.execCommand('Copy');
but AFAIU this don't work as expected, and I feel that clipboard operations need the user event (eg a mouse click or down) trigerring them. 但AFAIU这不能按预期工作,我觉得剪贴板操作需要用户事件(例如鼠标点击或向下)来触发它们。
The clipboard is initialized with 剪贴板初始化为
$clipboardh = new Clipboard(".momitemref_cl", {
text: function (trig) {
console.log("clipboard text trig=", trig);
/// some code is missing here probably
};
});
I guess (but I am not sure) that the /// some code is missing here probably
should return the text value of the relevant span. 我想(但我不确定)
/// some code is missing here probably
应该返回相关跨度的文本值。
So I don't know how to copy the span's content to the clipboard ( //// what should go here?
....) and how to put into the clipboard its text ( /// some code is missing here probably
....) 所以我不知道如何将span的内容复制到剪贴板(
//// what should go here?
....)以及如何将其文本放入剪贴板( /// some code is missing here probably
。 ...)
The full MVCE code is this JsFiddle 完整的MVCE代码就是这个JsFiddle
In other words, how to use clipboard.js
from a JQueryUI menu item to copy a span
's content to the browser's clipboard ?? 换句话说, 如何使用JQueryUI菜单项中的
clipboard.js
将span
的内容复制到浏览器的剪贴板?
Perhaps the entire approach is wrong, and perhaps I should use contextmenu
(but then, how to customize it only for span
-s of class='momitemref_cl'
?) 也许整个方法都是错误的,也许我应该使用
contextmenu
(但是,如何仅针对class='momitemref_cl'
span
-s来定制它?)
To make things even more complex, I actually have in MELT monitor (but not in this JsFiddle ...) two CSS classes mom_itemref_cl
& mom_itemval_cl
that I want to behave likewise. 为了使事情变得更复杂,我实际上已经在MELT监视器中 (但不是在这个JsFiddle中 )两个CSS类
mom_itemref_cl
和mom_itemval_cl
,我想表现得同样如此。
PS. PS。 I messed the JsFiddle when copying code here.
我在这里复制代码时搞砸了JsFiddle。 I updated it, https://jsfiddle.net/bstarynk/g2notLd7/132/
我更新了它, https://jsfiddle.net/bstarynk/g2notLd7/132/
NB. NB。 I could be satisfied with an answer working only on recent Firefox & Chrome.
我对仅在最近的Firefox和Chrome上工作的答案感到满意。
Clipboard.js needs to be attached to the element that triggers the copy event. 需要将Clipboard.js附加到触发复制事件的元素。 In your case, this is the
<li>Copy</li>
element inside the mommenu_cl
menu, which you create dynamically when a momitemref_cl
is right clicked. 在您的情况下,这是
mommenu_cl
菜单中的<li>Copy</li>
元素,您可以在右键单击momitemref_cl
时动态创建该momitemref_cl
。 You can attach clipboard.js to the Copy li
dynamically when you create the menu itself. 创建菜单本身时,可以动态地将clipboard.js附加到Copy
li
。 You will also have to destroy the clipboard when you destroy the menu. 在销毁菜单时,您还必须销毁剪贴板。
First, let's fix the typo in your updated fiddle, on line 87: 首先,让我们在第87行修正你更新的小提琴中的拼写错误:
curmenu[0].stle.left = Math.round(ev.pageY) + 5;
Then, remove the clipboard from your DOM's ready handler, we'll move this to the make_menu
function: 然后,从DOM的就绪处理程序中删除剪贴板,我们将其移至
make_menu
函数:
$(document).ready(function() {
$maindiv = $('#maindiv_id');
// no clipboard initialization here
console.log("our document ready function");
...
});
Next, at the top of your script, were you first declare $clipboardh
, initialize it to false
. 接下来,在脚本的顶部,您首先声明
$clipboardh
,将其初始化为false
。 Later, you will be checking to make sure you only attach the clipboard in case it is not currently attached. 稍后,您将检查以确保您只附加剪贴板,以防它当前未连接。
/// javascript code
var $clipboardh = false;
In your make_menu
function, give your <li>Copy</li>
element a class="copy"
attribute so you can easily attach clipboard.js to it, and a data-clipboard-text
attribute set to the value you want clipboard.js to copy when the element is clicked. 在
make_menu
函数中,为<li>Copy</li>
元素提供class="copy"
属性,以便您可以轻松地将clipboard.js附加到它,并将data-clipboard-text
属性设置为您想要剪贴板的值。单击元素时要复制的js。
Because the name
variable contains the text value you want to copy, your menu will look something like: 由于
name
变量包含要复制的文本值,因此菜单将如下所示:
$maindiv.after("<ul class='mommenu_cl' id='" + menuid + "'>" +
"<li class='copy' data-clipboard-text='" + name + "'>Copy</li>" +
"</ul>");
Next, just after this code in your make_menu
function, attach clipboard.js, only if it was not already attached: 接下来,在
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);
});
}
Finally, you will want to make sure you destroy the clipboard when you destroy the menu, by adding this to the bottom of your destroy_menu
function: 最后,您需要确保在销毁菜单时销毁剪贴板,方法是将其添加到
destroy_menu
函数的底部:
$clipboardh.destroy();
$clipboardh = false;
Copying from the clipboard from anything other than IE needs to happen on an editable element. 从IE以外的任何其他内容复制需要在可编辑元素上进行。 The most common way to handle this is to create a hidden textarea, put the content in the text area and then
处理此问题的最常用方法是创建隐藏的文本区域,然后将内容放入文本区域
textArea.select();
document.execCommand('Copy');
For IE, you can just use 对于IE,你可以使用
if(window.clipboardData){
window.clipboardData.setData('Text',
uitem.innerText);
}
I wrote a pretty extensive article explaining how this all works and I have a project on GitHub with the resulting code. 我写了一篇非常广泛的文章,解释了这一切是如何工作的,我在GitHub上有一个带有结果代码的项目。
http://blog.dmbcllc.com/cross-browser-javascript-copy-and-paste/ http://blog.dmbcllc.com/cross-browser-javascript-copy-and-paste/
It took me months to sort out all of the conflicting advice available by searching Google because HOW you do this keeps changes as the browsers "mature". 我花了几个月的时间来通过搜索Google来解决所有可用的冲突建议,因为你这样做会随着浏览器“成熟”而不断变化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.