仅使用DOMContentLoaded后如何DOM更改页面内容

问题描述 投票:-1回答:1

我正在使用基于cargocollective的系统,并尝试使用javascript更改现有项目标签。现在,当用户输入地址时,标签会在1或2秒钟内从一个阶段变为另一个阶段,因此用户首先会看到:project label - 1'st stage然后几秒钟后,请参阅:project label - 2'nd stage有什么方法可以修改它,以便用户在页面加载完成后看不到更改吗?这是我当前的代码:

<script>
document.addEventListener('DOMContentLoaded', (event) => {
  window.setTimeout(() => {
      let titles = document.querySelectorAll(".thumbnails .title span");
    let titlesArray = Array.from(titles);
    let tArray = [titlesArray.length];
    titlesArray.forEach(el => {
      let titleSplit =[];
      titleSplit = el.textContent.split('---');
      for (let i = 0; i < tArray.length; i++)
      {
        el.textContent = "";
        for (let j = 0; j < titleSplit.length; j++)
        {
          el.innerHTML += `${titleSplit[j]}</br>`;
        }
      }
});
  }, 400);
});
</script>

我需要提及的几件事:1.系统仅允许内部js脚本,不允许HTML编辑,这意味着只能在脚本标签之间插入代码2.解决方案必须使用JavaScript,以备将来使用。3.“ ---”仅用于化妆品用途,将替换为SVG图像。4.脚本标签的位置在文件的中间。同样,脚本和页面末尾之间有很多内容。5.对于查看源:webpage in context

javascript dom dom-events domcontentloaded
1个回答
0
投票

不要等待DOMContentLoaded,也不要将功能放入setTimeout。而是将<script>放在脚本所依赖的最后一个元素之后-最后一个.thumbnails .title span

<div class="thumbnails">
  <div class="title">
    <span>
      ...
    </span>
  </div>
</div>
<script>
// Put the code here
</script>

这样,更改应该立即发生,甚至还没有为用户呈现页面,因此,当他们第一次看到它时,它将看起来像所希望的。

关于代码,let tArray = [titlesArray.length];没有多大意义-您正在创建一个包含单个元素(一个数字)的数组,然后继续在嵌套循环中进行迭代。如果您只想用空白行替换---,并且跨度仅包含纯文本,请使用:

for (const span of document.querySelectorAll(".thumbnails .title span")) {
  span.innerHTML = span.innerHTML.split('---').join('<br><br>');
}

<div class="thumbnails">
  <div class="title">
    <span>
      foobar
      ---
      barbaz
    </span>
  </div>
</div>
<script>
for (const span of document.querySelectorAll(".thumbnails .title span")) {
  span.innerHTML = span.innerHTML.split('---').join('<br><br>');
}
</script>

((您需要两个<br>,两个单词之间必须有两个换行符,以便在渲染的输出中出现一条空行)


如果无法更改<script>标记的位置,脚本和HTML末尾之间有很多内容,脚本在所需元素之前运行存在,那么您将无法在脚本运行时立即选择元素,也无法等待DOMContentLoaded使它们存在,因为从出现所需元素到DOM出现之间可能要花费相当长的时间。完全解析。唯一的选择是将MutationObserver附加到文档,该文档可以在插入新节点时运行回调。如果新节点是您要更改的节点之一,请对其进行更改。这样可以确保在渲染之前尽快进行更改:

<script>
new MutationObserver((mutations) => {
  for (const mutation of mutations) {
    for (const node of mutation.addedNodes) {
      if (node.nodeType === 1 && node.matches('.thumbnails .title span')) {
        node.innerHTML = node.innerHTML.split('---').join('<br><br>');
      }
    }
  }
})
  .observe(document.body, { childList: true, subtree: true });
</script>
<div class="thumbnails">
  <div class="title">
    <span>
      foobar
      ---
      barbaz
    </span>
  </div>
  <div class="title">
    <span>
      foobar
      ---
      barbaz
    </span>
  </div>
</div>

它可以变得更便宜-例如,仅在所有thumbnails的容器存在后才附加深度观察者,并在容器结束后将其取消附加-但是为此需要有关DOM结构的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.