You have several errors:
* You missed a `+` in your `setGradient` function
* You never call `setGradient`
* Your logic to access to the clipboard were not working
Here is a working version:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var css = document.querySelector("h3");
var color1 = document.querySelector(".color1");
var color2 = document.querySelector(".color2");
var color3 = document.querySelector(".color3");
var body = document.getElementById("gradient");
var button = document.querySelector("button");
function setGradient() {
body.style.background =
"linear-gradient(to right, "
+ color1.value
+ ", "
+ color2.value
+ ", "
+ color3.value
+ ")";
css.textContent = body.style.background + ";";
}
function copyTextToClipboard(text) {
var textArea = document.createElement("textarea");
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
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);
}
/*Not working yet!*/
function copyElement(){
setGradient();
alert(css.textContent)
if(!!css.textContent){
copyTextToClipboard(css.textContent);
alert("Copied!");
}
}
color1.addEventListener("input",setGradient);
color2.addEventListener("input",setGradient);
color3.addEventListener("input",setGradient);
button.addEventListener("click",copyElement);
<!-- language: lang-html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Gradient Background</title>
<link rel="stylesheet" href="style.css">
</head>
<body id="gradient">
<h1>Background Generator</h1>
<input class="color1" type="color" name="color1" value="#00ff00">
<input class="color2" type="color" name="color2" value="#ffff00">
<input type="color" class="color3" name="color3" value="#AF0066">
<h2>Current CSS Backgrounds</h2>
<h2>Deluxe edition </h2>
<h3></h3>
<button type="button" class="button" name="button">Copy to clipboard</button>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
<!-- end snippet -->
I got the method to access the clipboard from: https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
# Overview
There are three primary browser APIs for copying to the clipboard:
1. [Async Clipboard API][1] `[navigator.clipboard.writeText]`
- Text-focused portion available in [Chrome 66 (March 2018)][2]
- Access is asynchronous and uses [JavaScript Promises][3], can be written so security user prompts (if displayed) don't interrupt the JavaScript in page.
- Text can be copied to the clipboard directly from a variable.
- Only supported on pages served over HTTPS.
- In Chrome 66 pages in active tabs can write to the clipboard without a permissions prompt.
2. `document.execCommand('copy')`
- Most browsers support this as of ~April 2015 (see Browser Support below).
- Access is synchronous, i.e. stops JavaScript in the page until complete including displaying and user interacting with any security prompts.
- Text is read from the DOM and placed on the clipboard.
- During testing ~April 2015 only Internet Explorer was noted as displaying permissions prompts whilst writing to the clipboard.
3. Overriding the copy event
- See Clipboard API documentation on [Overriding the copy event][4].
- Allows you to modify what appears on the clipboard from any copy event, can include other formats of data other than plain text.
- Not covered here as it doesn't directly answer the question.
# General development notes
Don't expect clipboard related commands to work whilst you are testing code in the console. Generally the page is required to be active (Async Clipboard API) or requires user interaction (e.g. a user click) to allow (`document.execCommand('copy')`) to access the clipboard see below for more detail.
# Async + Fallback
Due to the level of browser support for the new Async Clipboard API you will likely want to fallback to the `document.execCommand('copy')` method to get good browser coverage.
Here is a simple example:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function fallbackCopyTextToClipboard(text) {
var textArea = document.createElement("textarea");
textArea.value = text;
textArea.style.position="fixed"; //avoid scrolling to bottom
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Fallback: Copying text command was ' + msg);
} catch (err) {
console.error('Fallback: Oops, unable to copy', err);
}
document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
if (!navigator.clipboard) {
fallbackCopyTextToClipboard(text);
return;
}
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
}
var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<!-- language: lang-html -->
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
<!-- end snippet -->
Note that this snippet is not working well in Stack Overflow's embedded preview you can try it here: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011
# Async Clipboard API
- [Chrome 66 announcement post (March 2018)][2]
- Reference [Async Clipboard API][1] draft documentation
Note that there is an ability to "request permission" and test for access to the clipboard via the permissions API in Chrome 66.
var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
# document.execCommand('copy')
The rest of this post goes into the nuances and detail of the `document.execCommand('copy')` API.
## Browser Support
The JavaScript [`document.execCommand('copy')`][5] support has grown, see the links below for browser updates:
- Internet Explorer 10+ (although [this document][6] indicates some support was there from Internet Explorer 5.5+).
- [Google Chrome 43+ (~April 2015)][7]
- [Mozilla Firefox 41+ (shipping ~September 2015)][8]
- [Opera 29+ (based on Chromium 42, ~April 2015)][9]
## Simple Example
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var copyTextareaBtn = document.querySelector('.js-textareacopybtn');
copyTextareaBtn.addEventListener('click', function(event) {
var copyTextarea = document.querySelector('.js-copytextarea');
copyTextarea.focus();
copyTextarea.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');
}
});
<!-- language: lang-html -->
<p>
<button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
<textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>
<!-- end snippet -->
## Complex Example: Copy to clipboard without displaying input
The above simple example works great if there is a `textarea` or `input` element visible on screen.
In some cases you might wish to copy text to the clipboard without displaying an `input` / `textarea` element. This is one example of a way to work around this (basically insert element, copy to clipboard, remove element):
Tested with Google Chrome 44, Firefox 42.0a1 and Internet Explorer 11.0.8600.17814.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function copyTextToClipboard(text) {
var textArea = document.createElement("textarea");
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
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 copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<!-- language: lang-html -->
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
<!-- end snippet -->
## Additional notes
### Only works if the user takes an action
All `document.execCommand('copy')` calls must take place as a direct result of a user action, e.g. click event handler. This is a measure to prevent messing with the user's clipboard when they don't expect it.
See the [Google Developers post here][7] for more info.
### Clipboard API
Note the full Clipboard API draft specification can be found here:
https://w3c.github.io/clipboard-apis/
### Is it supported?
- `document.queryCommandSupported('copy')` should return `true` if the command "is supported by the browser".
- and `document.queryCommandEnabled('copy')` return `true` if the `document.execCommand('copy')` will succeed if called now. Checking to ensure the command was called from a user-initiated thread and other requirements are met.
However as an example of browser compatibility issues, Google Chrome from ~April to ~October 2015 only returned `true` from `document.queryCommandSupported('copy')` if the command was called from a user-initiated thread.
Note compatibility detail below.
### Browser Compatibility Detail
Whilst a simple call to `document.execCommand('copy')` wrapped in a `try`/`catch` block called as a result of a user click will get you the most compatibility use the following has some provisos:
Any call to `document.execCommand`, `document.queryCommandSupported` or `document.queryCommandEnabled` should be wrapped in a `try`/`catch` block.
Different browser implementations and browser versions throw differing types of exceptions when called instead of returning `false`.
Different browser implementations are still in flux and the [Clipboard API][10] is still in draft, so remember to do your testing.
[1]: https://www.w3.org/TR/clipboard-apis/#async-clipboard-api
[2]: https://developers.google.com/web/updates/2018/03/clipboardapi
[3]: https://developers.google.com/web/fundamentals/primers/promises
[4]: https://w3c.github.io/clipboard-apis/#override-copy
[5]: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
[6]: https://msdn.microsoft.com/en-us/library/ms537834(v=vs.85).aspx
[7]: https://developers.google.com/web/updates/2015/04/cut-and-copy-commands?hl=en
[8]: https://developer.mozilla.org/en-US/Firefox/Releases/41#Interfaces.2FAPIs.2FDOM
[9]: https://dev.opera.com/blog/opera-29/#cut-and-copy-commands
[10]: https://w3c.github.io/clipboard-apis/