从bookmarklet将文本复制到剪贴板

Ani*_*Ani 13 javascript clipboard google-chrome bookmarklet

我正在尝试编写一个小书签,可以从活动页面中提取一些文本并将其加载到剪贴板中.

提取很容易,但我真的很难做剪贴板复制部分.目前,我正在alert阅读文本并点击Ctrl+ C来复制消息框中的文本,这并不理想.

我已经阅读了如何在JavaScript中复制到剪贴板以及其他建议我使用zeroclipboard的问题,但我不知道如何从书签中完成这项工作,考虑到我必须加载外部 flash和javascript资源才能使用图书馆.

我没有弄乱页面的DOM来实现这一点,或者必须在我的浏览器(谷歌浏览器)上启用一些权限,考虑到这只是一个私人书签.

任何指针将不胜感激.

Joa*_*ous 12

由于新的Clipboard API,这在支持它的浏览器中很容易:

javascript: navigator.clipboard.writeText('some text from somewhere');null;
Run Code Online (Sandbox Code Playgroud)

警告:书签中的任何警报或提示都会导致文档失去焦点,并且剪贴板 API 将不可用。在这种情况下,您需要将焦点移回文档,然后才能进行任何后续剪贴板操作:

const oldFocus = document.activeElement; 
/* do popup stuff */
oldFocus.focus(); 
/* do clipboard stuff */
Run Code Online (Sandbox Code Playgroud)

  • “来自某处的一些文本”比示例中使用的通常的“bla blah bal”要严重得多。 (2认同)
  • `;null;` 中的 `null;` 的目的是什么? (2认同)
  • 另外,由于这是一个小书签,所以所有内容都被“压缩”(连接)到一行,因此在小书签中使用“//”是一个问题。我认为 `/* comment */` 应该可以正常工作。 (2认同)
  • @netawater - 我很确定 JoachimLous 只是意味着如果您的书签代码打开任何警报或“弹出窗口”,您应该小心(例如:`window.alert(“sometext”);`,`alert(“sometext”) ;`, `window.confirm("sometext");`, `confirm("sometext");`, `window.prompt("sometext","defaultText");` 或 `prompt("sometext","defaultText ");`), ***在***写入剪贴板的代码之前。如果您不使用警报或提示,或者如果您在写入剪贴板的代码***之后***使用它们,则您不必(不应该)担心恢复焦点,您可以忽略`...focus();` 的东西。 (2认同)

Gun*_*ark 9

在Github Gist中有一个很好的小书市,它可以实现您想要的核心 - 复制到剪贴板.它不使用任何外部库,我认为这是一个优势.

如上所述,它复制了一些静态文本,但是在底部它会讨论如何使其适应其他用途,例如复制页面标题.

既然你已经说过'提取很容易......',那么你应该能够轻松地将这个要点与你想做的事情相匹配.

我尝试了书签的普通版本,因为我有一些静态文本,我经常需要将其传输到剪贴板.它在Chrome 61中运行良好,无需修改.但请务必阅读评论; 有些人建议让它在其他浏览器和场景中工作.

这是我测试的代码,已经缩小并准备变成书签:

javascript:!function(a){var b=document.createElement("textarea"),c=document.getSelection();b.textContent=a,document.body.appendChild(b),c.removeAllRanges(),b.select(),document.execCommand("copy"),c.removeAllRanges(),document.body.removeChild(b)}("Text To Copy");
Run Code Online (Sandbox Code Playgroud)

Gist也有预先缩小的代码.

  • 显然,这**在 Firefox 中不起作用**:`document.execCommand('cut'/'copy') 被拒绝,因为它不是从短期运行的用户生成的事件处理程序中调用的。` (2认同)

Mar*_*ark 9

对于最新版本的 Firefox,由于缺少权限,通常无法通过书签与剪贴板进行交互(有关更多详细信息,请参阅此信息)。然而,可能有一种方法可以让书签显示一个按钮,并在按钮单击事件处理程序的上下文中执行剪贴板交互。

一个可能更直接的解决方案是使用用户脚本管理器,并以可以通过键盘组合激活的用户脚本的形式定义书签。参见,例如这个用户脚本,为了完整起见,复制在这里:

// Add the following as a user-script (via an extension like https://github.com/violentmonkey/violentmonkey) in order to copy the
// current webpage and selected text to the clipboard in a format suitable for pasting into an org-mode document.
// To execute the action, you need to press Alt-C on a webpage, though this can be modified by changing the keycode
// used in the onkeyup function.

// ==UserScript==
// @name Copy Org-mode Link
// @namespace Violentmonkey Scripts
// @match *://*/*
// @grant clipboardWrite
// ==/UserScript==

function main() {
    function copyTextToClipboard(text) { var textArea = document.createElement("textarea"); textArea.style.position = 'fixed'; textArea.style.top = 0; textArea.style.left = 0; textArea.style.width = '2em'; textArea.style.height = '2em'; textArea.style.padding = 0; textArea.style.border = 'none'; textArea.style.outline = 'none'; textArea.style.boxShadow = 'none'; textArea.style.background = 'transparent'; textArea.value = text; document.body.appendChild(textArea); textArea.select(); try { var successful = document.execCommand('copy'); var msg = successful ? 'successful' : 'unsuccessful'; console.log('Copying text command was ' + msg); } catch (err) { console.log('Oops, unable to copy'); } document.body.removeChild(textArea); }; var url = encodeURIComponent(location.href); url = url.replace(/%253A/g, ':').replace(/%252F/g, '/'); var title = document.title; title = title.replace(/\[/g, '{'); title = title.replace(/\]/g, '}'); var sel_text = window.getSelection(); copyTextToClipboard('[['+url+']['+title+']]'+'\n\n'+sel_text);
}

// listen for Alt-C key-combination, and then execute
document.onkeyup=function(e){
    var e = e || window.event; // for IE to cover IEs window object
    if(e.altKey && e.which == 67) {
         main();
         return false;
    }
}
Run Code Online (Sandbox Code Playgroud)


Ani*_*Ani 6

以下是我使用他的答案中提到的@zzzzBov技术解决它,通过书签将zeroclipboard导入页面.

当书市场运行时,在主体上的任何位置悬停时会出现一个手形光标.单击将(例如)文档的标题复制到剪贴板.

(zeroclipboard资源的链接已被占位符替换,并且已使用多行注释,因为Chrome似乎正在删除来自bookmarklet(或其他内容)的所有换行符)

javascript:

var s = document.createElement('script');
s.setAttribute('src', 'http://example.com/ZeroClipboard.js');

s.onload = s.onreadystatechange = 
  function()
  { 
     ZeroClipboard.setMoviePath( 'http://example.com/ZeroClipboard.swf');
     var clip = new ZeroClipboard.Client();   

     /* glue to the body: sample only, in reality  we should
        probably create a new visible element and glue to that. */
     clip.glue(document.body);   

     clip.setHandCursor( true );

     /* copy to clipboard on mouse-up */
     clip.addEventListener('onMouseUp', 
      function (client) 
      {      
         /* example */
         var toCopy = document.title;        
         clip.setText(toCopy);    

         alert(toCopy + ' copied.');
         clip.hide();
      });  
   };

document.body.appendChild(s);
Run Code Online (Sandbox Code Playgroud)


Chr*_*ois 5

一个有点不寻常的答案:打开一个空白页面,用户将从中复制文本:

<a href="javascript:window.open('data:text/html, <html contenteditable>sup<script>document.execCommand(\'selectAll\')</script></html>')">
  Copy the text “sup”
</a>
Run Code Online (Sandbox Code Playgroud)

只需替换sup为您希望用户复制的文本即可。

JS Bin 示例

  • 好用,谢谢!注意:有些引号需要转义:`execCommand(\'selectAll\')` (4认同)

zzz*_*Bov 3

一些免责声明:

  1. 我不是想向你发送垃圾邮件
  2. 如果你选择使用这个我什么也得不到

我不久前制作了一个小书签生成器,以便我更轻松地创建小书签。

它支持 jQuery,但这并不意味着您必须使用 jQuery。

您可以查看源代码,了解如何通过书签将另一个脚本/库导入页面。

特别是导入 jQuery 的行:

if (!window.zbooks)
  {
    //if zbooks hasn't been set, initialize it

    //s used for the Script element
    var s = document.createElement('script');
    //r used for the Ready state
    var r = false;
    //set the script to the latest version of jQuery
    s.setAttribute('src', 'http://code.jquery.com/jquery-latest.min.js');
    //set the load/readystate events
    s.onload = s.onreadystatechange = function()
    {
/**
 * LOAD/READYSTATE LOGIC
 * execute if the script hasn't been ready yet and:
 * - the ready state isn't set
 * - the ready state is complete
 *   - note: readyState == 'loaded' executes before the script gets called so
 *     we skip this event because it wouldn't have loaded the init event yet.
 */
      if ( !r && (!this.readyState || this.readyState == 'complete' ) )
      {
        //set the ready flag to true to keep the event from initializing again
        r = true;
        //prevent jQuery conflicts by placing jQuery in the zbooks object
        window.zbooks = {'jQuery':jQuery.noConflict()};
        //make a new zbook
        window.zbooks[n] = new zbooks(c);
      }
    };
    //append the jQuery script to the body
    b.appendChild(s);
  }
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助。