搜索

首页  >  问答  >  正文

修改现有 DOM 元素时消除页面加载事件期间的闪烁

我使用普通 JavaScript 有以下 DOM 元素更改函数,其中我使用页面加载事件更改包含 DOM 的某些文本字符串的 span 元素。

使用以下代码,DOM 元素将按预期更改。但是,在变量 desktopmobile 的 DOM 元素更改之前,他们仍然会看到最小部分的闪烁

闪烁场景示例:

我认为发生这种情况是因为当页面的 DOM 内容完全加载时会应用 DOM 更改。我想隐藏现有的标签元素,直到应用更改,然后显示它们。

我想要操作的 desktopmobile 的元素结构如下:

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

请参阅以下概念:

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();

有没有办法先隐藏 DOM 元素,直到应用了对现有元素的更改,然后再显示它?

我正在考虑使用如下内联 CSS 规则:

设置.style.visbility='hidden',当文本内容改变时用.style.visbility='visble'显示。

但我不确定如何在我的代码中正确实现该解决方案。

P粉143640496P粉143640496250 天前506

全部回复(2)我来回复

  • P粉195402292

    P粉1954022922024-03-27 17:50:03

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

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

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

    回复
    0
  • P粉478188786

    P粉4781887862024-03-27 14:35:48

    无论如何,您都需要等到 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

    回复
    0
  • 取消回复