Prevent any flashing or flickering while updating current DOM elements during the page loading event

In my vanilla JavaScript code, I have a function that changes the text content of a span element in the DOM on page load event.

Although the DOM elements are changed as expected, there is still a slight flickering effect before the text is updated for the variables desktop and mobile.

Illustration of the flickering issue:

  • Initially, the span tag displays "Text I want to change" briefly.
  • After the content fully loads, the span tag shows the updated text as "text1 changed".

This flickering may be occurring because the DOM changes are applied only after the entire page content has loaded. I would like to hide the span elements until the changes are made, and then reveal them.

The structure of elements for desktop and mobile that I intend to modify looks like this:

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

Check out the concept below:

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

Is there a way to initially hide the DOM element until the change to the existing element has been applied and then show it?

I was considering using inline CSS rules like so:

Set .style.visibility='hidden' and then reveal it with .style.visibility='visible' once the text content is updated. However, I am unsure how to implement this solution effectively in my code.

Answer №1

There are a couple of reasons why the flickering issue may occur, but there are two proactive measures you can implement:

  • To prevent flickering, consider using the defer attribute on your script tag <script defer>. This allows the browser to manage the order in which your scripts are executed rather than relying on DOMContentLoaded. It also eliminates the need for the changes wrapper function.
  • Another suggestion, as mentioned in this post (and based on your own observations), is to apply inline CSS or link a CSS file to hide the text initially and then reveal it later.
  • If adjusting the layout of your page is not an issue, you could also consider dynamically creating the element instead of loading it directly.

However, keep in mind that all of these solutions still require JavaScript execution and may introduce some delay. If feasible, explore the option of prerendering your webpage. Your JS code indicates that it checks for route names like eu or us, suggesting that your page is suitable for prerendering.

Answer №2

Before you start manipulating the DOM, it is important to ensure that the DOM has finished loading. You can achieve this by using an event listener for DOMContentLoaded. Here are the three key steps involved:

  1. Wait for the DOM to finish loading
  2. Identify the elements and modify their content
  3. Show the elements. You can either use visibility: hidden or display: none, depending on whether you want the element to occupy space or not.

In the initial example, a timeout is added to demonstrate the page's appearance before the text changes occur. The <p> is styled with display: inline-block to visualize the size of the hidden span.

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.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;
}
<p>
  <span class="first-headline target-span">Text I want to change</span>
</p>
<p>
  <span class="first-headline target-span">Text I want to change</span>
</p>

The second example consolidates all code into one HTML page, including defining styles in the header section. This approach ensures that when the DOM loads, the CSS rules are applied simultaneously without requiring an external stylesheet (although alternative approaches exist as well).

<html>

<head>
  <style>
    p {
      border: thin solid black;
    }
    .target-span {
      visibility: hidden;
    }
    .target-span.show {
      visibility: visible;
    }
  </style>
  <script>
    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.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', changes);
  </script>
</head>

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

</html>

Answer №3

Simple & Effective:

To change the text, place the script tag right after the span tag:

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

  <script>
    var changesObj = {
      "us": {
        title: "text1 modified"
      },
      "eu": {
        title: "text2 modified"
      }
    };

    function applyChanges() {
      var region = changesObj[window.location.pathname.split('/')[1]];
      console.log(region);
      var newText;
      if (!region) {
        console.log('Region not found');
      }
      newText = region.title;

      if (document.querySelector('.target-span').innerText.length > 0) {
        var desktopSpan = document.querySelector('.target-span');
        console.log(desktopSpan);
        desktopSpan.innerText = newText;
        console.log(desktopSpan.innerText);
        console.log("Changes applied for desktop");
      }
      if (document.querySelector('.target-span').innerText.lenght > 0) {
        var mobileSpan = document.querySelector('.target-span');
        mobileSpan.innerText = newText;
        console.log(mobileSpan.innerText);
        console.log("Changes applied for mobile");
      }
    }

    applyChanges();
  </script>

This method helps avoid any asynchronous issues.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Assistance with JavaScript regular expressions for dividing a string into days, hours, and minutes (accounting for plural or singular forms)

My challenge is with handling different variations in a string var str = "2 Days, 2 Hours 10 Minutes"; When I use : str.split(/Days/); The result is: ["2 ", ", 2 Hours 10 Minutes"] This method seems useful to extract values like "days", "hours" and " ...

The JavaScript else statement is failing to execute as intended

Hello, I am new to JavaScript and could really use some assistance. In the code snippet below, I am having trouble with the logic for the submit button. The line _btn.addEventListener seems to be causing an issue where only the "if" part is being executed ...

Encountering issues with the functionality of async await

I am a beginner when it comes to utilizing the async, await, and promise features in JavaScript. My current focus is on: async function sendTextMessage(text) { console.log("----1----"); var messageData = { message: { text: tex ...

Locate a specific text within a complex array of objects and retrieve the objects that contain the match as

I have an array of objects named input as shown below. Each object in the array contains a property vertical of type string, an array called platformList, and a nested object named radar_metadata. I am looking to implement a search functionality where I c ...

What is the best way to show translated messages using i18next when displaying JavaScript alerts?

We are in the process of developing an application that makes use of html/css/js, incorporating i18next for displaying translated strings. To display these translations, I insert an attribute within a tag. Here's an example: <a href="#top" id="ag ...

Is there a way to create unique animations for CSS drop down div

I've been attempting to implement a hover effect on my drop-down cart that makes it fade or slide up similar to submenus. But, CSS transitions are not my forte! I've tried using generic fades with the transition property, but no luck. Currently ...

Opting for a name selector over an id for more specific styling

Is there a way to modify the code below in order to make it function based on a name selector instead of an id? <div id="light" class="change_group_popup"> <a class="close" href="javascript:void(0)">Close</a> JavaScript $('.ch ...

Innovative functionality for adding and deleting elements in JQuery/JavaScript

Is there a way to dynamically add and remove items when the Append/Clear buttons are clicked using this code snippet? $("#btn1").click(function(){ $("ul").prepend("<li>List Item</li>"); }); $("#btn2").click(function(){ $("ul").remove ...

How come my form isn't functioning properly on mobile devices?

I recently downloaded a form from the website and integrated it within my desktop site successfully. However, when accessed on mobile devices, specifically iOS, the submit button changes to "sending ..." and the form gets stuck without displaying any erro ...

Express Concurrency: Managing Multiple Tasks Simultaneously

Looking to create an API using Express that is capable of processing requests either through multithreading or multiprocessing. For example, the following API has a 5-second sleep before responding. If I make 3 quick calls to it, the first response will ta ...

Exploring Methods to Access External Iframes Using PHP or JavaScript

I need assistance tracking my package that was sent through the local post service. The tracking information can be found at this link: . Using the tracking number RF166699170SK, I should be able to locate the package. However, when I attempt to retrieve ...

Add array as an element within another array

After initializing the data, I have an object structured like this and I am able to push data using the method below: myObj = { 1: ["a", "b", "c"], 2: ["c", "d", "e"], } data: { types: {} }, methods: { pushValue(key, value) { var ...

What is preventing me from accessing a function that is declared using function declaration while using a debugger?

When pausing at the debugger statement, an attempt to call foo results in a ReferenceError. It appears that the function is not defined within the script's context or scope, similar to how a local variable like x is. The script example.js is as follo ...

Using TypeScript with ReactJS

While working on a form using React-select, I encountered an issue when trying to pass parameters to a function. The error message returned was: Expected 1 arguments, but got 0.ts(2554) index.tsx(31, 31): An argument for 'selectRef' was not pr ...

Require assistance with arranging font-awesome icons in a stacked formation

After upgrading to the latest version of font-awesome, I encountered some stacking issues with my icons. In the previous version, everything was working perfectly. <li><span class="icon-stack stacked"><i class="icon-circle icon-stack-base" ...

Invoke the C# function in the code-behind using an AJAX call

I have been attempting to encrypt two variables and return them as query strings using a code-behind function, but I have not been successful. This is my first time trying Ajax. Here is the method in my code-behind: [WebMethod] public static string Encri ...

Accessing elements in a JSON object was straightforward with the

I need help with accessing values from a JSON object based on a key name stored in a variable. My colleague has written a function to extract keys from the JSON object and compare them with the ones we are interested in. However, I am struggling with fig ...

I am having difficulty aligning the vertical touch event owl carousel

Here is the link: "jsfiddle.net/nLJ79/". Can you try to find a solution to make the owl carousel vertical? ...

Switch up color scheme on table with checkbox activation

I'm currently using the AdminLTE template (Bootstrap) and I'd like to modify the color of the table row when my checkbox is checked. <table id="example1" class="table table-bordered table-striped dataTable" aria-describedby="example1_info"> ...

Is there a way to include core modules in my package.json dependencies in Express in order to utilize them in my JavaScript files?

I'm currently exploring the 'connect' core module, and my understanding is that express utilizes this module internally. I'm attempting to manually require it, but I seem to be encountering issues with installation using git bash. Below ...