I'm trying to write a little bookmarklet that can extract some text from the active page and load that into the clipboard.
The extraction is easy enough, but I'm really stuck doing the clipboard-copying part. Currently, I'm just alert
ing the text and hitting Ctrl+C to copy the text from the message-box, which isn't ideal.
I've read How to Copy to Clipboard in JavaScript and other questions that suggest I use zeroclipboard, but I have no idea how one would make that work from a bookmarklet, considering I have to load external flash and javascript resources to be able to use the library.
I have no issues with messing up the page's DOM to accomplish this or having to enable some permissions on my browser (Google Chrome), considering this is just a private bookmarklet.
Any pointers would be appreciated.
A couple disclaimers:
- I'm not trying to spam you
- I gain nothing if you choose to use this
I made a bookmarklet generator a while back to make it easier for me to create bookmarklets.
It's jQuery enabled, but that doesn't mean you have to use jQuery.
You can check out the source to see how to import another script/library into a page via a bookmarklet.
In particular, the lines that import 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);
}
I hope that helps.
There is a nice little bookmarket in Github Gist that does the core of what you want -- copying to the clipboard. It does not use any external libraries, which I think of as an advantage.
As written, it copies some static text, but toward the bottom it talks about adapting it to other uses, such as copying the page title.
Since you've stated that 'The extraction is easy enough ...', you should be easily be able to adapt that gist to what you want to do.
I tried the plain vanilla version of the bookmarklet, because I have some static text that I often need to transfer to my clipboard. It works very well in Chrome 61 with no modifications. But make sure you read the comments; some people have suggestions on getting it to work in other browsers and scenarios.
Here is the code that I tested, already minified and ready to turn into a bookmarklet:
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 has the pre-minified code as well.
Here's how I solved it, using the technique @zzzzBov mentioned in his answer, to import zeroclipboard into the page via a bookmarklet.
When the bookmarket runs, a hand cursor appears on hovering over anywhere on the body. Clicking will copy (for example) the document's title to the clipboard.
(Links to zeroclipboard resources have been replaced with placeholders, and multi-line comments have been used since Chrome appears to be removing all line-breaks from bookmarklets (or something))
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);
An answer that's a bit unusual: open a blank page from which the user will copy the text:
<a href="javascript:window.open('data:text/html, <html contenteditable>sup<script>document.execCommand(\'selectAll\')</script></html>')">
Copy the text “sup”
</a>
Just replace sup
by the text you want the user to copy.
With recent versions of Firefox, interacting with the clipboard via a bookmarklet in general won't work due to missing permissions (see this information for more details). There may be a way, however, to have the bookmarklet display a button, and perform the clipboard interaction in the context of a button-click event handler.
A possibly more straightforward solution is to use a user-script manager, and define your bookmarklet in the form of a user-script that you can activate via a keyboard combination. See, for example this user script, reproduced here for completeness:
// 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;
}
}
来源:https://stackoverflow.com/questions/5046972/copy-text-to-clipboard-from-bookmarklet