Eliminieren Sie das Flackern während Seitenladeereignissen beim Ändern vorhandener DOM-Elemente
P粉143640496
P粉143640496 2024-03-26 19:30:32
0
2
528

Ich habe die folgende Funktion zum Ändern von DOM-Elementen mit einfachem JavaScript, bei der ich das Seitenladeereignis verwende, um ein Span-Element zu ändern, das eine Textzeichenfolge des DOM enthält.

Mit dem folgenden Code ändern sich die DOM-Elemente wie erwartet. Sie werden jedoch immer noch den kleinsten Teil des desktopmobile Flackerns sehen, bis sich das DOM-Element der Variablen ändert.

Flicker-Szenenbeispiel:

  • Ich habe den Tag-Bereich „Text, den ich ändern möchte“ im Bruchteil einer Sekunde gesehen.
  • Nachdem der Inhalt vollständig geladen ist, sehe ich den geänderten Tag-Bereich „text1 geändert“.

Ich denke, das passiert, weil DOM-Änderungen angewendet werden, wenn der DOM-Inhalt der Seite vollständig geladen ist. Ich möchte vorhandene Beschriftungselemente ausblenden, bis Änderungen angewendet werden, und sie dann anzeigen.

Die Elementstruktur von desktopmobile, die ich bedienen möchte, ist wie folgt:

<span class="first-headline target-span">Text I want to change</span>

Siehe die folgenden Konzepte:

var changesObj = {
  "us": {
    title: "text1 changed"
  },
  "eu": {
    title: "text2 changed"
  }
};

function changes() {
  var webshop = changesObj[window.location.pathname.split('/')[1]];
  console.log(webshop);
  var changesText;
  if (!webshop) {
    console.log('webshop not found');
  }
  changesText = webshop.title;
  
  if (document.querySelector('.target-span').innerText.length > 0) {
    var desktop = document.querySelector('.target-span');
    console.log(desktop);
    desktop.innerText = changesText;
    console.log(desktop.innerText);
    console.log("applied changes for dekstop");
  }
  if (document.querySelector('.target-span').innerText.lenght > 0) {
    var mobile = document.querySelector('.target-span');
    mobile.innerText = changesText;
    console.log(mobile.innerText);
    console.log("applied changes for mobile");
  }
}

function invokeChanges() {
  document.addEventListener("DOMContentLoaded", function () {
    changes();
  });
}

invokeChanges();

Gibt es eine Möglichkeit, ein DOM-Element zunächst auszublenden, bis Änderungen am vorhandenen Element vorgenommen werden, und es dann anzuzeigen?

Ich denke darüber nach, Inline-CSS-Regeln wie diese zu verwenden:

Einstellungen.style.visbility='hidden',当文本内容改变时用.style.visbility='visble'Anzeige.

Aber ich bin mir nicht sicher, wie ich diese Lösung richtig in meinem Code implementieren soll.

P粉143640496
P粉143640496

Antworte allen(2)
P粉195402292

它闪烁的原因有很多,但您可以采取两个预防措施:

  • 在脚本标签 <script defer> 上使用 defer,因为这可以让浏览器处理脚本的运行顺序,而不是使用 DOMContentLoaded。您还可以避免 changes 包装函数。
  • 按照这个问题的建议(以及您自己的问题)推理)将内联 CSS / CSS 文件附加到页面以将文本设置为不可见,然后将其标记为可见
  • 如果它不会对页面布局产生太大影响,您也可以选择动态生成该元素。

但是,请注意,无论其中任何一个,这些仍然需要执行 JS,并且可能仍然会有延迟。如果您能够使用它,您可能会对预渲染您的网页感兴趣 -从您的 JS 代码中,它会查找路由名称(如果是 euus),这意味着您的页面是可预渲染的。

P粉478188786

无论如何,您都需要等到 DOM 加载完毕后才能对其进行操作。使用 DOMContentLoaded 的偶数侦听器将是可行的方法。因此,需要发生三件事:

  1. 等待 DOM 加载
  2. 查找元素并更改文本
  3. 使元素可见。您可以使用属性 visibility:hiddendisplay:none。不同之处在于,使用 visibility:hidden 元素仍会占用空间。因此,选择取决于上下文。

在第一个示例中,我添加了一个超时,以便您可以在文本更改之前看到页面的外观。我还设置了 <p> (display: inline-block) 的样式,以便您可以看到隐藏跨度的大小。

window.location.hash = "us"; // for testing on SO
var changesObj = {
  "us": { title: "text1 changed" },
  "eu": { title: "text2 changed" }
};

function changes(e) {
  //let webshop = changesObj[window.location.pathname.split('/')[1]];
  let webshop = changesObj[window.location.hash.substring(1)]; // for testing on SO
  if (webshop) {
    [...document.querySelectorAll('.target-span')].forEach(span => {
      span.textContent = webshop.title;
      span.classList.add('show');
    });
  }
}

document.addEventListener('DOMContentLoaded', e => {
  setTimeout(changes, 1000);
});
p {
  border: thin solid black;
  display: inline-block;
}

.target-span {
  visibility: hidden;
}

.target-span.show {
  visibility: visible;
}

Text I want to change

Text I want to change

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage