为什么 javascript 要创建它自己的元素?

问题描述

嘿,我是一名新的 Web 开发人员,我正在编写 html、css 和 javascript。我创建了一个“复制”按钮来复制 <p> 元素内的文本,并提示文本已复制。

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>

我的主要目的是在点击相应的 <span class="randomStatuscopyAlert">copied!</span> 时使相应的 <button class="copystatus btn">copy</button> 可见。虽然代码工作正常,但 javascript 会创建自己的跨度并显示它。 看到我将分享一些图片,以便如果我让“.randomStatuscopyAlert”自己可见。 [![现在看到跨距正确放置][1]][1]

现在跨度放置正确。 当它由上面的javascript完成时 [![当我使用 html 代码检查工具时,跨度改变其位置并进入

元素][2]][2]

跨度位置已更改。 [1]:https://i.stack.imgur.com/aNevS.png [2]:https://i.stack.imgur.com/b0az4.png

解决方法

为了演示目的,我尝试将您的代码复制到更简单的结构中

这是 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>

随意更改类名,我已经更改了它们,因为我发现这样更容易阅读。一些 div 被删除了,因为我认为它们并不是实现这个结果的必要条件。

请注意,我删除了表示文本已复制到剪贴板的跨度。这是没有必要的,因为也许在某个时候您会决定更改消息,并且您将不得不在任何地方更改它。现在,将使用 JS 插入表示文本已复制的标签。

这是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%;
}

这里的一些属性也被删除了,因为它们不是必需的。由于我们是使用JS动态添加span,所以不需要在开头隐藏span。

这是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);
  }
}

我已经拿走了所有按钮并在它们上面添加了一个 click 侦听器。当它被点击时,我们获取整个状态元素并在其中获取 p 元素。我们将 p 元素的文本传递给 copyTextToClipboard 函数。这里只是将文本复制到剪贴板所需的逻辑,没有别的。

addCopyStatusAlert 函数仅用于将新创建的 span 作为同级按钮附加到按钮。在短暂的超时后,它会从 DOM 中完全删除。

这是我在 CodePen 上为此创建的笔的 link。随意在那里试验它。