从bookmarklet将文本复制到剪贴板

时间:2011-02-18 21:50:05

标签: javascript google-chrome clipboard bookmarklet

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

提取很容易,但我真的很难做剪贴板复制部分。目前,我只是alert文本并点击 Ctrl + C 来复制消息框中的文本,这是不理想的。 / p>

我已阅读How to Copy to Clipboard in JavaScript以及其他建议我使用zeroclipboard的问题,但我不知道如何通过 bookmarklet 来完成这项工作,考虑到我有加载外部 flash和javascript资源以便能够使用该库。

我没有弄乱页面的DOM来完成此操作或者必须在我的浏览器(Google Chrome)上启用某些权限,因为这只是一个私人书签。

任何指针都将不胜感激。

7 个答案:

答案 0 :(得分:8)

Github Gist中有一个不错的小书市,可以the core of what you want - 复制到剪贴板。它不使用任何外部库,我认为这是一个优势。

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

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

我尝试了书签的普通版本,因为我有一些静态文本,我经常需要将其传输到剪贴板。它在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");

Gist也有预先缩小的代码。

答案 1 :(得分:6)

以下是我使用answer中提到的@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);

答案 2 :(得分:4)

一对免责声明:

  1. 我不是想给你发垃圾邮件
  2. 如果您选择使用此
  3. ,我什么也得不到

    我做了一段时间bookmarklet generator,让我更容易创建bookmarklet。

    启用了jQuery,但这并不意味着 使用jQuery。

    您可以check out the source查看如何通过书签将其他脚本/库导入页面。

    特别是导入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);
      }
    

    我希望有所帮助。

答案 3 :(得分:4)

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

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

只需将sup替换为您希望用户复制的文字。

JS Bin example

答案 4 :(得分:3)

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

可能更直接的解决方案是使用用户脚本管理器,并以用户脚本的形式定义您的书签,您可以通过键盘组合激活该脚本。例如,请参阅this user script,为了完整性,请转载此处:

// 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;
    }
}

答案 5 :(得分:0)

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

javascript: navigator.clipboard.writeText('some text from somewhere');null;

注意事项:小书签中的任何警报或提示都将导致文档失去焦点,并且剪贴板API将变得不可用。在这种情况下,您需要先将焦点移回到文档中,然后再进行任何剪贴板操作:

const oldFocus = document.activeElement; 
// do popup stuff
oldFocus.focus(); 
// do clipboard stuff

答案 6 :(得分:0)

HTTP 和 HTTPS 上下文的解决方案

@Joachim Lous 的 Clipboard API 解决方案对我来说是正确的。但是,这在使用 http 而不是 https 的 localhost 上不起作用。为了解决这个问题,我使用了一个“copyToClipboard”函数(改编自 this SO answer),它作为一个多合一的包装函数,通过使用一个聪明的“视口外隐藏文本区域”来考虑 http 上下文" 把戏。

可读版本:

javascript:

function copyToClipboard(textToCopy) {
    // navigator clipboard api needs a secure context (https)
    if (navigator.clipboard && window.isSecureContext) {
        // navigator clipboard api method
        return navigator.clipboard.writeText(textToCopy);
    } else {
        // use the 'out of viewport hidden text area' trick
        let textArea = document.createElement("textarea");
        textArea.value = textToCopy;
        // make the textarea out of viewport
        textArea.style.position = "fixed";
        textArea.style.left = "-999999px";
        textArea.style.top = "-999999px";
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();
        return new Promise((res, rej) => {
            // here the magic happens
            document.execCommand('copy') ? res() : rej();
            textArea.remove();
        });
    }
};
var element = document.querySelector(".myClass");
var text = element.textContent || element.value;
copyToClipboard(text);

只需将“.myClass”替换为您的选择器即可。

书签的缩小版:

javascript:void function(){var a=document.querySelector(".myClass"),b=a.textContent||a.value;(function(a){if(navigator.clipboard&&window.isSecureContext)return navigator.clipboard.writeText(a);else{let b=document.createElement("textarea");return b.value=a,b.style.position="fixed",b.style.left="-999999px",b.style.top="-999999px",document.body.appendChild(b),b.focus(),b.select(),new Promise((a,c)=>{document.execCommand("copy")?a():c(),b.remove()})}})(b)}();