简体   繁体   中英

Why javascript is creating it's own elements?

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>

My main intention is to make visible the respective <span class="randomStatusCopyAlert">Copied!</span> when respective <button class="copystatus btn">Copy</button> is clicked. Although the code is working correctly but the javascript creats itself span and display it. See I will share some pics so that if I make ". randomStatusCopyAlert" myself visible. [![See Now the the span is place correctly][1]][1]

Now the span is placed correctly. When it is done by the above javascript [![the span change its position and goes into

elements when I used html code inspection tool][2]][2]

The span position is changed. [1]: https://i.stack.imgur.com/aNevS.png [2]: https://i.stack.imgur.com/b0az4.png

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM