In JavaScript, is it possible to manually trigger a DOM update during consecutive prompts?

My goal is to create a program that transitions between prompts and updates on a page in a cyclical manner. However, when I simplify the issue to just two append calls and two prompts, I notice that the page only visually updates after the second prompt call. The reason behind this desire is somewhat abstract, as I aim to mimic a terminal-like experience where the user inputs information intermittently. Below is an example, adapted from w3c schools, that illustrates this problem:

<!DOCTYPE html>
<html>
<body>

<h1>The Window Object</h1>
<h2>The prompt() Method</h2>

<p>Click the button to demonstrate the prompt box.</p>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {
   
  let person = prompt("Please enter your name", "Prompt1");
  if (person != null) {
    document.getElementById("demo").insertAdjacentHTML('beforeend', "Test1\n");
 }
  
  person = prompt("Please enter your name", "Prompt2")
  if (person != null) {
    document.getElementById("demo").insertAdjacentHTML('beforeend', "Test2\n");
  }
}

</script>

</body>
</html>

My desired outcome is for the first insertAdjacentHTML call to update the DOM and visually reflect on the page before the second prompt appears, allowing the user to see their input. However, in reality, I notice that "Test1" and "Test2" appear visually at the same time after the second prompt. While console logging works as intended, it is not suitable for my current application.

I have tried various methods to address this issue (e.g., attempting to trigger a layout with a scroll call, using requestAnimationFrame), but I have not yet discovered a technique that achieves the desired result. One hypothesis I have is that the second prompt is executed before the next frame, causing it to block any new rendering. Regardless of whether this hypothesis is accurate, I welcome any suggestions on achieving the desired behavior.

Ideally, I would like to see Test1 displayed on the page, followed by the second prompt, and then Test2, assuming the user selects the default options.

Answer №1

Utilizing a brief timeout appears effective...

function myFunction() {
  const d = document.getElementById("demo");
   
  let user = prompt("Please enter your name", "Prompt1");
  if (user != null) {
    d.insertAdjacentHTML('beforeend', "Test1\n");
  }
 
  setTimeout(() => {
    user = prompt("Please enter your name", "Prompt2")
    if (user != null) {
      d.insertAdjacentHTML('beforeend', "Test2\n");
    }
  }, 50);
}
<h4>Demo with setTimeout</h4>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>

HOWEVER, it could become messy quickly if multiple prompts are required. In such cases, consider encapsulating the prompt/write text/delay process in a promise and chaining them together using then:

function myFunction() {
  const d = document.getElementById("demo");
   
  delayPrompt("Please enter your name", "Prompt1", d)
    .then(() => delayPrompt("Please enter your name", "Prompt2", d))
    .then(() => delayPrompt("something else", "Prompt3", d));
}

async function delayPrompt(text, def, container) {
  return new Promise((resolve) => {     
    let response = prompt(text, def);
    if (response != null) {
      container.insertAdjacentHTML('beforeend', response);
    }
    setTimeout(resolve, 50);
  });
}
<h4>Demo with Promise</h4>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>

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

Using JavaScript functions within PHP is not supported

Currently, I am utilizing Laravel for my backend operations. Within my setup, there exists a JavaScript function called StartJob() that facilitates Google crawling. In the scenario where I input a keyword, which is then cross-referenced with the database, ...

Customize the jQuery datepicker by assigning a class to the first 17 days

How can I apply a class to only the first 17 days on a jquery datepicker calendar? I've attempted the following code, but it ends up adding the class to every day... beforeShowDay: function(date) { for (i = 0; i < 17; i++) { return [t ...

Tips for creating a stylish scrollbar in a React Material-Table interface

Currently, I am utilizing the react material-table and looking to implement a more visually appealing scroll-bar instead of the default Pagination option. Although I have experimented with the react-custom-scroll package, it has not produced the desired ...

Interceptors in axios do not trigger when making requests through a PHP proxy

I am currently working on a React app that will be interacting with services hosted on a remote server. During development on my local machine using the react-scripts server at localhost:3000, I disable CORS in the browser and have no issues with axios f ...

How to Make Page Slide in Either Direction Based on User Click Location

Although the title of my question may not be very descriptive, I am essentially trying to implement a functionality where a page will slide right if a user clicks a link to the right of their current active link, and slide left if they click a link to the ...

Is there a way to prevent my smartchatbox from covering my fixed top navbar?

Click here for more information I am seeking assistance. Your help is greatly appreciated. The question's heading reveals all you need to know. All you have to do is resize your browser, scroll down, and the answer will become apparent. ...

Is it possible to integrate payment methods such as PayPal or Stripe in Vue.js without using a server like Express? If so, how can I implement this

After completing the development of my web shop in Vue.js, I realized that the payment method is still missing. I am wondering if I need to integrate Express in order to process payments through Stripe? Currently, I do not have a server like Express set up ...

Getting request parameters within Model in Loopback can be done by accessing the `ctx`

common/models/event.json { "name": "Event", "mongodb": { "collection": "event" }, "base": "PersistedModel", "idInjection": true, "options": { "validateUpsert": true }, "http": { "path": "organizer/:organizer_id/events" }, "properties": {}, "va ...

Ways to align div elements

I am currently in the process of developing my own custom animation player. Utilizing Three.js for object rendering has been successful so far. However, the challenge lies in incorporating control options at the bottom of the player interface (such as play ...

Ways to access a function variable within an AJAX `done` function

This is the JavaScript function I am working with: $('.editable').change(function () { event.preventDefault(); var el_text = this.lastElementChild; var action = this.action; var method = this.method; var data = $(this).serialize(); ...

What occurs when you use the statement "import someModuleName from someModule" in JavaScript?

When reusing a module in multiple places, you typically use module.exports = yourModuleClassName to make the module exportable. Then, when you want to use it elsewhere, you can simply import it with import yourModuleClassName from 'yourmodulePath&apos ...

There seems to be an issue with Node.js/Express: the page at /

Recently, I've been working on some code (specifically in app.js on the server). console.log("Server started. If you're reading this then your computer is still alive."); //Just a test command to ensure everything is functioning correctly. var ...

Implementing the decrement functionality within an onclick event handler for a variable

Can someone assist me with this issue? I am trying to use a variable ID in HTML to call a function on a JavaScript page. For example: (Minus button not functioning) <button class="minus-button quantity-button button" type="button" name="subtract" onc ...

Unable to display elements from an array in the dropdown menu generated by v-for

Having just started learning Vue.js, I am facing a challenge in rendering the following array: countries: ["US", "UK", "EU" ] I want to display this array in a select menu: <select> <option disabled value="">Your Country</option& ...

Imitate the experience of using aframe view manipulation

Is there a method to imitate user input in my Webvr application? Could I reproduce look controls in Aframe? <a-entity listener position="0 0 0" id="camera" camera="userHeight: 1.6" look-controls> ...

Attempting to maintain the main navigation highlighted while browsing through the secondary navigation

I am facing a small issue that seems like it should be an easy fix, but I can't seem to figure it out. While working on my site, I'm having trouble keeping the parent navigation highlighted when scrolling through the sub-menu. If you hover over ...

JavaScript error caused by incorrect JSON parsing

Encountering Another Issue. Here's the Relevant Code: if(localStorage.getItem("temporaryArray")){ var temporaryArray = JSON.parse(localStorage.getItem("temporaryArray")); }else{ var temporaryArray = []; } Essentially, what this code snippet ...

Creating an identifier for the jQuery slideToggle function involves assigning a unique class or ID to

I am currently working on creating an identifier for the jQuery slide.Toggle function. In my PHP code, I have a loop that prints values, each with a button and a div that should be able to slide toggle. So far in PHP, here is what I have attempted, withou ...

Sorting Tables through the Power of Drag and Drop

While utilizing both the Jquery Tablesorter plugin and the Drag and Drop plugin together, everything seems to be functioning correctly. However, when attempting to use the serialize function of the tableDnD, an error message stating "empty string getElemen ...

using async.waterfall with async.apply

Here is a code snippet that I am working with: async.waterfall([ // Read directory async.apply(fs.readdir, '../testdata'), // Load data from each file function(files, callback) { async.each(files, loadDataFromFile, callback); } ], ...