Code Monkey home page Code Monkey logo

clipboard.js's Introduction

clipboard.js

Build Status Killing Flash

Modern copy to clipboard. No Flash. Just 3kb gzipped.

Demo

Why

Copying text to the clipboard shouldn't be hard. It shouldn't require dozens of steps to configure or hundreds of KBs to load. But most of all, it shouldn't depend on Flash or any bloated framework.

That's why clipboard.js exists.

Install

You can get it on npm.

npm install clipboard --save

Or if you're not into package management, just download a ZIP file.

Setup

First, include the script located on the dist folder or load it from a third-party CDN provider.

<script src="dist/clipboard.min.js"></script>

Now, you need to instantiate it by passing a DOM selector, HTML element, or list of HTML elements.

new ClipboardJS('.btn');

Internally, we need to fetch all elements that matches with your selector and attach event listeners for each one. But guess what? If you have hundreds of matches, this operation can consume a lot of memory.

For this reason we use event delegation which replaces multiple event listeners with just a single listener. After all, #perfmatters.

Usage

We're living a declarative renaissance, that's why we decided to take advantage of HTML5 data attributes for better usability.

Copy text from another element

A pretty common use case is to copy content from another element. You can do that by adding a data-clipboard-target attribute in your trigger element.

The value you include on this attribute needs to match another's element selector.

example-2

<!-- Target -->
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git" />

<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo">
  <img src="assets/clippy.svg" alt="Copy to clipboard" />
</button>

Cut text from another element

Additionally, you can define a data-clipboard-action attribute to specify if you want to either copy or cut content.

If you omit this attribute, copy will be used by default.

example-3

<!-- Target -->
<textarea id="bar">Mussum ipsum cacilds...</textarea>

<!-- Trigger -->
<button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">
  Cut to clipboard
</button>

As you may expect, the cut action only works on <input> or <textarea> elements.

Copy text from attribute

Truth is, you don't even need another element to copy its content from. You can just include a data-clipboard-text attribute in your trigger element.

example-1

<!-- Trigger -->
<button
  class="btn"
  data-clipboard-text="Just because you can doesn't mean you should — clipboard.js"
>
  Copy to clipboard
</button>

Events

There are cases where you'd like to show some user feedback or capture what has been selected after a copy/cut operation.

That's why we fire custom events such as success and error for you to listen and implement your custom logic.

var clipboard = new ClipboardJS('.btn');

clipboard.on('success', function (e) {
  console.info('Action:', e.action);
  console.info('Text:', e.text);
  console.info('Trigger:', e.trigger);

  e.clearSelection();
});

clipboard.on('error', function (e) {
  console.error('Action:', e.action);
  console.error('Trigger:', e.trigger);
});

For a live demonstration, go to this site and open your console.

Tooltips

Each application has different design needs, that's why clipboard.js does not include any CSS or built-in tooltip solution.

The tooltips you see on the demo site were built using GitHub's Primer. You may want to check that out if you're looking for a similar look and feel.

Advanced Options

If you don't want to modify your HTML, there's a pretty handy imperative API for you to use. All you need to do is declare a function, do your thing, and return a value.

For instance, if you want to dynamically set a target, you'll need to return a Node.

new ClipboardJS('.btn', {
  target: function (trigger) {
    return trigger.nextElementSibling;
  },
});

If you want to dynamically set a text, you'll return a String.

new ClipboardJS('.btn', {
  text: function (trigger) {
    return trigger.getAttribute('aria-label');
  },
});

For use in Bootstrap Modals or with any other library that changes the focus you'll want to set the focused element as the container value.

new ClipboardJS('.btn', {
  container: document.getElementById('modal'),
});

Also, if you are working with single page apps, you may want to manage the lifecycle of the DOM more precisely. Here's how you clean up the events and objects that we create.

var clipboard = new ClipboardJS('.btn');
clipboard.destroy();

Browser Support

This library relies on both Selection and execCommand APIs. The first one is supported by all browsers while the second one is supported in the following browsers.

Chrome logo Edge logo Firefox logo Internet Explorer logo Opera logo Safari logo
42+ ✔ 12+ ✔ 41+ ✔ 9+ ✔ 29+ ✔ 10+ ✔

The good news is that clipboard.js gracefully degrades if you need to support older browsers. All you have to do is show a tooltip saying Copied! when success event is called and Press Ctrl+C to copy when error event is called because the text is already selected.

You can also check if clipboard.js is supported or not by running ClipboardJS.isSupported(), that way you can hide copy/cut buttons from the UI.

Bonus

A browser extension that adds a "copy to clipboard" button to every code block on GitHub, MDN, Gist, StackOverflow, StackExchange, npm, and even Medium.

Install for Chrome and Firefox.

License

MIT License © Zeno Rocha

clipboard.js's People

Contributors

arve0 avatar calvincorreli avatar coliff avatar dependabot[bot] avatar eduardolundgren avatar grabus avatar helderberto avatar heldr avatar jaydson avatar johnsenpeder avatar jory avatar leuisken avatar mauriciosoares avatar obetomuniz avatar orafaelfragoso avatar patrickhlauke avatar pawlufelice avatar plesiecki avatar r3nanp avatar realityking avatar sebastianekstrom avatar shabailiu avatar spazzmarticus avatar vccortez avatar vitormalencar avatar whitj00 avatar whyounes avatar xhmikosr avatar yannickoo avatar zenorocha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clipboard.js's Issues

programmed to work with hidden input?

Really like this - excellent work!
If i leave the input as it works as expected.
I'd like to use it with a hidden input, but when I add type="hidden" the text no longer gets copied.
Tried it with display:none but had the same results.
I can style the input so the input cannot be seen but I'd rather be able to use a hidden input, if possible.

Idea: pass in the elements

With single page apps, you may want to manage the lifecycle of the DOM more precisely.

What I would like would be for a way to provide a single element or list of elements that are used instead of having the library use the selector to find elements on the document. Otherwise, it feels like jQuery spaghetti by adding extra classes to HTML (FYI: I'm using React refs to find elements).

Not working on Firefox 41

Documentation says Firefox 41 is supported, but it's not.
screenshot from 2015-09-23 01 02 58
Am I missing something?

On Firefox 42 it works just fine.

Copy image support

Hi,

Does actual browser api let's you copy images? Could be usefull.

thank you

Why is dist directory in source control?

Generally, build artifacts should not be checked in to source control. This includes the dist directory in your repo. Out of curiosity, why did you decide to check this in? You can use the "releases" feature of Github to upload .zip files for people that don't want to use the npm package.

Emit mouse events too

It's quite common for people to show user feedback after a copy to clipboard action. [1] Although we provide a success event on which they can show a Copied! tooltip, we do not expose mouse events such as mouseover, mouseleave, so they can show a Copy to Clipboard tooltip. Our own site shows that this is a good use reason to implement that. [2]

[1] http://stackoverflow.com/questions/27488279/how-to-show-tooltip-after-copying-using-zero-clipboard
[2] https://github.com/zenorocha/clipboard.js/blob/gh-pages/assets/scripts/main.js#L1-L8

Module parse failed

I am using webpack and babel to package this library, but get the following error:

ERROR in ./~/clipboard/src/clipboard.js
Module parse failed: 
/node_modules/clipboard/src/clipboard.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import ClipboardAction from './clipboard-action';
| import Delegate from 'delegate-events';
| import Emitter from 'tiny-emitter';

I see you have configured the browser version to point to a different file than in Node.js so I am manually pointing to clipboard/dist/clipboard.js to work around this.

If I copy clipboard.js and clipboard-action.js into my project, they seem to work so I think it has something to do with the way package.json is set up.

Init copy

Hi,

thank you for the great plugin. Is there any way to auto/init copy some text?
Without the need to click on an element?

Faulty behaviour when browser access is not permitted.

Hello,

This is a bit of an edge-case and might not have a proper solution. But since the project supports IE9+
and I'd qualify this as a "case where you'd like to show some user feedback".

I thought I'd be worth mentioning here.

Steps to reproduce:

  1. Visit http://zenorocha.github.io/clipboard.js/
  2. Click one of the triggers in the examples
  3. Click on deny access, when prompted for clipboard permissions by the browser. (see screenshot)
  4. UI responds as if the copy to clipboard succeeded. (see screenshot)

AFAIK the root cause of the problem is that document.execCommand returns true even if it does not have permissions.

  • OS: Windows 7 (Home Premium)
  • Browser Version: IE 9 (see screenshot)

permission
copied
version

Thanks for a great library with superb documentation.
Cheers.

Consider rename the data attributes actions

Hello Zeno, nice project :)

This issue is for you to consider renaming the configuration data-attributes for something like data-clipboard-action instead of data-action.

The reason,

In my project (for example) I already use a lot the attribute data-action, this is too generic and most likely to be used by other developers as well, this may conflict with your library.

What you think?

clipboard.js (naturally) does not work with stopPropagation() on parents

So I tried to get to work clipboard.js with a button inside a modal.
Problem is, there's something like $( "body" ).one( function () { modal.close(); } );. Not exactly that code, but take it like that to keep this simple.
Of course the click event registered on the modal stops the event propagation to not get closed which means clipboard.js by design won't work inside that modal.

So my question: Is there a way around it?
Could there be a config option provided by the constructor which creates an additional "parent" for event delegation?
Sounds weird, I know, but that's the only kind-of-reasonable solution my mind came up with.

Cut and Paste

Would it be possible to add "cut" and "paste" functionality also?

G63

New Here but so much to learn

Add feature detection method

it would be nice if there's a method that can tell us wither clipboard.js will work on current browser or not, as I don't want the copy button to show up to the end user when he cannot actually use this feature.

IE8 Support

ClipboardAction uses addEventListener and removeEventListener methods, which are not supported in IE8.

clipboard.js already contains component-events module that can be used to resolve this issue.

How to return from two var?

new Clipboard('.btn-copy', {
                    target: function(trigger) {
                        var a = document.querySelector(".data-order");
                        var b = document.querySelector("#t");
                        return (a,b);
                    }
                });

I wanna make somehing like above, but return wrong result, can u help?

Cannot be used in Node 0.12 (browserify based apps)

/tmp $ npm install clipboard
clipboard@1.2.0 node_modules/clipboard
├── tiny-emitter@1.0.0
└── delegate-events@1.1.1 (component-event@0.1.4, closest@0.0.1)

/tmp $ node
> var C = require('clipboard')
/tmp/node_modules/clipboard/src/clipboard.js:1
(function (exports, require, module, __filename, __dirname) { import Clipboard
                                                              ^^^^^^
SyntaxError: Unexpected reserved word
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at repl:1:9
    at REPLServer.defaultEval (repl.js:132:27)
    at bound (domain.js:254:14)

Obviously import is not implemented in Node 0.12 as it is not ES6. However I usually build my JS web apps as a Node project + browserify. Unfortunately the usage of import makes this unfeasible.

Why export a global?

Being a npm library it would really make sense that the exported object/class would not be global, but instead the user should call var clipboard = require('clipboard') as usual.

Please don't pollute the brower's window namespace if a JS loader is detected.

API

As per conversation w/ @zenorocha on Hangouts, I'm creating this issue for the record.

I'm suggesting some breaking changes to the public API so we can remove all the logic from the constructors of clipboard and clipboard-action.

The resulting API would be:

var clipboard = new Clipboard('.btn'); // config options

clipboard.setup(); // initializing logic (event delegation, construction of clipboard-action, etc.) this could maybe return a promise that either resolves or fails if the setup succeed or not.

clipboard.on('[event]', callbackFn);

clipboard.destroy(); // unbind all the events and maybe kill the elements in the DOM

The main reason of those changes are to avoid side effects on the constructors to make it easier to test and more flexible for the users.

Option to include HTML

Would be nice if we could also copy to the clipboard a full HTML block and not just the text that block has.

An example is that I wanted to allow users to copy the email signature code to be pasted in Outlook.

Readme confusion

It reads: "For a live demonstration, open this site on Safari.". However, Safari appears to be the only browser NOT supported by this plugin. WAT?

Add disting steps

Hi,

Can you please add how your are transpiling ES6 code to ES5 code in dist folder? Which tool you are using (babel/traceur) and what all are the compiler options?

data-clipboard-target should be data-clipboard-source

"data-clipboard-target" is confusingly misnamed as it actually indicates the source, the clipboard itself is the target.

I had to read the example twice to make sure that I wasn't going mad - therefore please rename it "data-clipboard-source" to preserve everyone's sanity!

Implicit instantiation of trigger element(s)

As from my understanding, a very basic workflow of using clipboard.js would involve importing clipboard.js/clipboard.min.js, and then instantiating the clipboard element(s) using; new Clipboard("{selector}");. Perhaps, this workflow can be further simplified through the implicit instantiation of those element(s).

Thus instead of;

<!DOCTYPE html>
<html>
  <head>
    <script src="jquery-1.11.3.js"></script>
    <script src="clipboard.js"></script>
    <script>
      $("document").ready(function(){
        new Clipboard(".btn");
      });
    </script>
    <title>Test Page</title>
  </head>
  <body>
    <input id="foo" value="asdf">
    <button class="btn" data-clipboard-target="#foo">Click me!</button>
  </body>
</html>

, we have,

<!DOCTYPE html>
<html>
  <head>
    <script src="clipboard.js"></script>
    <title>Test Page</title>
  </head>
  <body>
    <input id="foo" value="asdf">
    <button class="btn" data-clipboard-target="#foo">Click me!</button>
  </body>
</html>

.

Support for paste

Thanks for writing clipboard.js, really awesome!

Besides support for copy and cut, it would be great be able to paste text too.

Text not copied to clipboard in disabled textarea

I am using clipboard.js to copy text from a disabled textarea (the text is programmatically generated and I don't want the user to edit it before copying):

<button class="copyBtn" data-clipboard-target="#myTextArea">Copy</button>
<textarea id="myTextArea" rows="10" disabled>My text here</textarea>

With the disabled property the text is not copied to the clipboard, despite the clipboard success event indicating that it is:

var clipboard = new Clipboard('.copyBtn');

        clipboard.on('success', function(e) {
            console.info('Action:', e.action);
            console.info('Text:', e.text);
            console.info('Trigger:', e.trigger);

            e.clearSelection();
        });

        clipboard.on('error', function(e) {
            console.error('Action:', e.action);
            console.error('Trigger:', e.trigger);
        });
Action: copy 
Text: My text here
Trigger: <button data-clipboard-target="#myTextArea" class="copyBtn">​

Removing the disabled property on the textarea, clipboard functions as expected and text is copied.

It doesn't work in Safari.

why not just use document.execCommand('copy')? chrome firfox IE edge ....oh, i didn't test opera
just like
$('.pre-btn-copy').click(function () {
var execCommandReady = document.execCommand('copy', false, '');
if (execCommandReady) {
var text = document.getElementById('us-detail-c');
text.select();
document.execCommand('Copy');
console.log('ok')
} else {
console.log('doesn't work');
}
});

localization

Hi, thanks for the awesome project!

From the docs:

That means you can show a tooltip saying Copied! when success event is called and Press Ctrl+C to copy when error event is called because the text is already selected.

I'm not pro on JS and just wonder is there any API for me change the text so I can achieve the localization?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.