Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Hey am a new web developer and I am writing a html, css and javascript. I have created a "copy" button to copy the text inside the <p> element and a alert that the text is copied.

buttons.forEach((copystatus) => {
  copystatus.addEventListener('click', (e) => {
    const copylatest = e.target.closest(".latestatus").querySelector("p").innerText;
    const copyText = document.createElement('textarea');
    copyText.style.width = "0";
    copyText.style.height = "0";
    copyText.style.outline = "none";
    copyText.style.border = "none";
    copyText.value = copylatest;
    document.body.appendChild(copyText);
    copyText.select();
    document.execCommand('copy');
    document.body.removeChild(copyText);
    copyalert.style.visibility = "visible"
    e.target.closest(".latestatus").querySelector("p").appendChild(copyalert);
    setTimeout(function() {
      copyalert.style.visibility = "hidden"
    }, 700);

  })
})
.randomStatusCopyAlert {
  position: relative;
  background-color: #18b495;
  color: #ffffff;
  padding: 10px 10px;
  border-radius: 5px;
  z-index: 2;
  visibility: hidden;
  height: 45px;
  float: right;
  bottom: 2px;
  left: 4%;
}

.randomStatusCopyAlert:before {
  content: "";
  position: absolute;
  height: 10px;
  width: 10px;
  background-color: #18b495;
  left: -5px;
  z-index: 1;
  transform: rotate(45deg);
  top: 39%;
}
<div class="mainStatus">
  <h2 class="statusHeading">Latest English Status</h2>
  <div class="allStatus">
    <div class="block">
      <div class="latestatus">
        <p>Life is good when you have books</p>
        <div class="flex"><button class="copystatus btn">Copy</button> <span class="randomStatusCopyAlert show">Copied!</span></div>
      </div>
      <div class="latestatus">
        <p>Google is a open source library by Larry Page and Sergey Brin!</p>
        <div class="flex"><button class="copystatus btn">Copy</button> <span class="randomStatusCopyAlert">Copied!</span></div>
      </div>
    </div>
    <div class="block">
      <div class="latestatus">
        <p>Cats are better than dogs.</p>
        <div class="flex"><button class="copystatus btn">Copy</button> <span class="randomStatusCopyAlert">Copied!</span></div>
      </div>
      <div class="latestatus">
        <p>Ferrets are better than rats</p>
        <div class="flex"><button class="copystatus btn">Copy</button> <span class="randomStatusCopyAlert">Copied!</span></div>
      </div>
    </div>
  </div>
</div>
question from:https://stackoverflow.com/questions/65640687/why-javascript-is-creating-its-own-elements

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
82 views
Welcome To Ask or Share your Answers For Others

1 Answer

I tried to replicate your code into a simpler structure just for demonstration purpose

Here is the HTML

<div class="statuses-container">
  <h2 class="statuses-heading">Latest English Status</h2>
  <div class="statuses">
    <div class="status">
      <p class="status-text">Life is good when you have books</p>
      <div class="status-copy-btn-container">
        <button class="status-copy-btn btn">Copy</button>
      </div>
    </div>
    <div class="status">
      <p class="status-text">Google is an open source library by Larry Page and Sergey Brin!</p>
      <div class="status-copy-btn-container">
        <button class="status-copy-btn btn">Copy</button>
      </div>
    </div>
    <div class="status">
      <p class="status-text">Cats are better than dogs.</p>
      <div class="status-copy-btn-container">
        <button class="status-copy-btn btn">Copy</button>
      </div>
    </div>
  </div>
</div>

Feel free to change the class names as you wish, I've changed them because I find it easier to read like this. Some of the divs were removed, because I think they were not really necessary in achieving this result.

Please notice that I've removed the span which indicated that the text was copied to clipboard. It is not necessary, because maybe at some point you will decide to change the message, and you will have to change it everywhere. Now, that label saying that the text was copied will be inserted using JS.

Here is the CSS:

status-copy-alert {
 position: relative;
 background-color: #18b495;
 color: #ffffff;
 padding: 10px 10px;
 border-radius: 5px;
 left: 8px;
}
.status-copy-alert:before{
 content:"";
 position: absolute;
 height: 10px;
 width: 10px;
 background-color: #18b495;
 left: -5px;
 transform: rotate(45deg);
 top: 39%;
}

Some of the properties here were removed as well, because they were not necessary. Since we are adding the span dynamically using the JS, there is no need for the span to be hidden in the beginning.

Here is the JS:

var buttons = document.getElementsByClassName('status-copy-btn');

for (let button of buttons) {
  button.addEventListener('click', function() {
     let statusElement = this.closest('.status');
     let textToCopy = statusElement.getElementsByClassName('status-text')[0].innerHTML;
    
    copyTextToClipboard(textToCopy);
    addCopyStatusAlert(this.parentNode);
  });
}

function copyTextToClipboard(text) {
  const copyText = document.createElement('textarea');
  copyText.style.position="absolute";
  copyText.style.display="none";
  copyText.value = text;

  document.body.appendChild(copyText);
  copyText.select();
  document.execCommand('copy');
  document.body.removeChild(copyText);
}

function addCopyStatusAlert(element) {
  if (!element.getElementsByClassName('status-copy-alert').length) {
    let copyAlertElement = document.createElement('span');
    copyAlertElement.classList.add('status-copy-alert')
    let copyMessage = document.createTextNode('Copied!');
    copyAlertElement.appendChild(copyMessage);

    element.appendChild(copyAlertElement);

    setTimeout(function() {
      element.removeChild(copyAlertElement);
    }, 700);
  }
}

I've taken all of the buttons and added a click listener on them. When it gets clicked, we take the entire status element and get the p element inside it. We pass the text of the p element to copyTextToClipboard function. Here is only the logic needed for copying the text to clipboard and nothing else.

The addCopyStatusAlert function is used just to append a newly created span as a sibling to the button. And after a short timeout, it gets completely deleted from the DOM.

Here is the link to the pen i've created on CodePen for this. Feel free to experiment with it there.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...