【问题标题】:How to reduce dom manipulation while appending css using javaScript如何在使用 javaScript 附加 css 时减少 dom 操作
【发布时间】:2020-12-08 20:01:31
【问题描述】:

我有一些动态创建的 html 整个 css 属性都在一个对象中。所以他们需要使用 Javascript 给出。所以我使用下面的方法将样式附加到动态创建的 dom 元素。我相信每次我为附加样式进行 dom 操作时成本很高。在下面的代码本身中,有 10 行正在执行 css dom 操作。

function createNavbar() {
  let nav;
  nav = '<div class="navbar" id="nav"></div>';
  this.body.insertAdjacentHTML("beforeend", nav);
  let navBar = document.getElementById("nav");
  navBar.style.display = "block"; // style appending begins
  navBar.style.background = this.navColors.notice.bg;
  navBar.style.color = this.navColors.notice.textColor;
  navBar.style.borderWidth = "1px";
  navBar.style.borderStyle = "solid";
  navBar.style.borderColor = this.navColors.notice.borderColor;
  navBar.style.top = this.navPositionValue[this.position].top;
  navBar.style.right = this.navPositionValue[this.position].right;
  navBar.style.bottom = this.navPositionValue[this.position].bottom;
  navBar.style.left = this.navPositionValue[this.position].left; // style appending ends
}

this SO Question 找到了更好的方法,所以我用下面一行代码替换了 10 行代码(使用了 cssText 属性)

navBar.style.cssText = `display: block; color: ${this.navColors.notice.textColor}; background: ${this.navColors.notice.bg}; border: 1px solid ${this.navColors.notice.borderColor}; top: ${this.navPositionValue[this.position].top}; right: ${this.navPositionValue[this.position].right}; bottom: ${this.navPositionValue[this.position].bottom}; left: ${this.navPositionValue[this.position].left};`

通过使用这种方法,我希望 Dom 操作减少到 1 而不是 10,但是该行很长且难以阅读。我想知道是否有比这更好的方法在 js 中附加长行或许多 css

【问题讨论】:

  • 由于您使用的是template literals,因此您只需添加换行符(输入)即可获得更易读的代码。或者只是创建一个类并将该类添加到元素中
  • @Reyno 哦!那太棒了!我去做。我使用的方法是优化的吗?
  • 使用 10 条指令来更改尽可能多的样式属性不会导致 10 次单独的 CSS 重绘,因为您在进行所有更改时不会屈服于中间的 JavaScript 事件循环。
  • @theFrontEndDev 是的,这非常好,但它们与第一个选项并没有太大区别。我还创建了一个答案,向您展示如何删除颜色和位置的大变量。它有助于提高可读性。
  • 不需要优化。浏览器只会更新你的 CSS 一次。请看下面我的回答

标签: javascript css append


【解决方案1】:

只需添加一个具有通用样式的类,然后将该类添加到 dom。 这不是最简单的方法吗?

【讨论】:

  • css 是动态的吧?我们如何将它们添加到一个类中。
  • 同意你的观点,但前提是所有这些动态样式都无条件地一次性应用。如果某些样式的添加是有条件的,那么你的方法就不适合了。
  • @theFrontEndDev, navBar.classList.add("your_class");
  • 事实上,您可以将样式添加到现有样式表中的类(使用 CSS 对象模型操作)
【解决方案2】:

由于浏览器的工作方式,您上面的代码只会导致页面一次更新。您不必担心优化它。

基本上,您的所有更改将在您的函数结束后立即应用,这意味着即使您在一个函数中多次更改element.style,它仍然只是一个操作。 p>

如需详细了解其工作原理和方式,我推荐this talk by Jake Archibald 了解事件循环的工作原理。

【讨论】:

  • “浏览器很聪明”在这种情况下可能有点夸大其词和不必要的复杂原因,但结论是正确的。
  • @K1ngjulien_ 感谢您的更新。我认为它类似于 append 方法。我相信我在某处读到过不断追加到 DOM 的成本很高,他们解释了称为文档片段的概念以减少这种情况。我也看到了类似的情况。无论如何,第二个看起来比 10 行代码更简洁。换行很少,我想会很好
  • @theFrontEndDev 看起来您只是将一个元素附加到 dom,所以我不会担心任何性能问题。
  • @theFrontEndDev 我也将使用 document.createElement() 创建新的 dom 节点并将它们附加到您需要的位置,因此您不必查询刚刚使用 insertAdjacentHTML 插入的节点
【解决方案3】:

您可以在template literals 内添加换行符以提高可读性。

另一种选择是destructure 一些对象,这样我们就没有必须重复的很长的变量名。

const navBar = document.querySelector(".navBar");

const navColors = {
  notice: {
    textColor: "red",
    bg: "green",
    borderColor: "blue",
  }
};

const navPositionValue = {
  top: "5px",
  right: "10px",
  bottom: "15px",
  left: "20px",
};

// destructering so we dont have to repeat "navColors.notice" or "navPositionValue" for each value
const {textColor, bg, borderColor} = navColors.notice;
const {ttop, right, bottom, left} = navPositionValue;

navBar.style.cssText = `
  display: block;
  color: ${textColor};
  background: ${bg};
  border: 1px solid ${borderColor};
  top: ${ttop};
  right: ${right};
  bottom: ${bottom};
  left: ${left};
`;
.navBar {
  padding: 20px;
}
<div class="navBar">
  I'm a navBar
</div>

【讨论】:

  • 这太棒了!谢谢你:)
【解决方案4】:

您可以使用模板文字

而且你可以marge css边框

function createNavbar() {
  let nav = `
        <div class="navbar" id="nav" style = "
          display: block;
          background: ${this.navColors.notice.bg};
          color: ${this.navColors.notice.textColor};
          border: 1px solid ${this.navColors.notice.borderColor};
          top: ${this.navPositionValue[this.position].top};
          right: ${this.navPositionValue[this.position].right};
          bottom: ${this.navPositionValue[this.position].bottom};
          left: ${this.navPositionValue[this.position].left};
        ">
        </div>
  `
  document.body.insertAdjacentHTML("beforeend", nav);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-27
    • 2020-03-17
    • 2014-09-19
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多