首页 > 解决方案 > 更有效/更合适的方式来编写这个 DOM 操作?

问题描述

我是 Vanilla JavaScript 的初学者,刚刚编写了代码来更改下面的 HTML。它有效,但我想知道是否有更有效/更合适的方式来做到这一点。预先感谢您的帮助。

之前的HTML

<section id="anchor-a">
<p>lorem ipsum....</p>
</section>
<section id="anchor-b">
<p>lorem ipsum....</p>
</section>

之后的HTML

<section>
<div id="anchor-a" class="anchor"></div>
<p>lorem ipsum....</p>
</section>
<section>
<div id="anchor-b" class="anchor"></div>
<p>lorem ipsum....</p>
</section>

我的 JavaScript 代码

const anchor = document.querySelectorAll('[id^="anchor-"]');
anchor.forEach((element) => {
  let newDiv = document.createElement('div');
  newDiv.classList.add('anchor');
  newDiv.setAttribute('id', element.getAttribute("id"));
  ;
  element.insertBefore(newDiv, element.firstChild);
  element.removeAttribute('id');
});

标签: javascripthtml

解决方案


更简洁的版本是 to insertAdjacentHTML,它可能更容易阅读:

const anchor = document.querySelectorAll('[id^="anchor-"]');
anchor.forEach((section) => {
  section.insertAdjacentHTML('afterbegin', `<div id="${section.id}">`);
  section.removeAttribute('id');
});
// next line is not needed, just cleans up the console output for demonstration
document.currentScript.remove();
console.log(document.body.innerHTML);
<section id="anchor-a">
<p>lorem ipsum....</p>
</section>
<section id="anchor-b">
<p>lorem ipsum....</p>
</section>

另请注意,querySelectorAll返回 a NodeList,并且只有较新的浏览器才有NodeList.prototype.forEach函数。对于较旧的浏览器和 IE,要么包含一个 polyfill,要么使用Array.prototype.forEach.call

Array.prototype.forEach.call(
  document.querySelectorAll('[id^="anchor-"]'),
  (section) => {
    section.insertAdjacentHTML('afterbegin', `<div id="${section.id}">`);
    section.removeAttribute('id');
  }
);
// next line is not needed, just cleans up the console output for demonstration
document.currentScript.remove();
console.log(document.body.innerHTML);
<section id="anchor-a">
<p>lorem ipsum....</p>
</section>
<section id="anchor-b">
<p>lorem ipsum....</p>
</section>

(当然,如果使用 ES6+ 语法,如果您想支持古老的浏览器,请记住除了 polyfills 之外还要转译为 ES5 )


推荐阅读