2

I'm trying to apply a copy to clipboard option on my color selecctor, which shows up the color selected on a h3 tag.The idea is to make a background color generator in which each time a color is selected, it would appear on screen, allowing us to select all the information of the colors and then being able to copy said color information to our clipboard by clicking on the botton. I don't kown why the button doesn't work.

I'm still learging how properly use these methods, but I couldn't make it work yet. Any advice would be greatly appreciated.

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 + ";";
}


/*Not working yet!*/
function copyElement(){
    if(setGradient){
        /*Getting the textfield*/ 
    var copyText = css.textContent;
        /*Selecting the text field */
    copyText.select();
    copyText.setSelectionRange(0,99999);
    /*Copying text*/
    document.execCommand("copy");
    alert("Copied!");
    }
}


color1.addEventListener("input",setGradient);
color2.addEventListener("input",setGradient);
color3.addEventListener("input",setGradient);

button.addEventListener("click",copyElement);
<!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>
        <input type="button" class="button" name="button" value="Copy to clipboard">
        <script type="text/javascript" src="script.js"></script>
</body>
</html>
Mad-Kid
  • 23
  • 3

2 Answers2

1

You have several errors:

  • You were selecting a <button> but you used <input> in yout HTML
  • 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:

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");
// I change the html to match this selector
var button = document.querySelector("button");

function setGradient() {
    body.style.background = 
    "linear-gradient(to right, " 
    + color1.value 
    + ", " 
    + color2.value 
    + ", " 
    + color3.value
    + ")"; // missing `+`

    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);
<!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>

Try it online

I got the method to access the clipboard from: How do I copy to the clipboard in JavaScript?

aloisdg
  • 22,270
  • 6
  • 85
  • 105
  • Thank you so much for your help! I still got a lot to learn. Now I can implement this function anywhere, yet I'll make a new version for practice when I feel comfortable using "document" methods – Mad-Kid Feb 12 '20 at 13:47
0

First of all, document.querySelector(".button") is correct (notice to dot character). After that, select method works for your input elements, not h3 or its textContent.

F.NiX
  • 1,457
  • 3
  • 12
  • 20