I have tree like that style. I want on node click, to show word loading below the node clicked until new nodes are opened..anyone know how to do this?
hajjo 0 Junior Poster
Dani AI
Generated
As discovered, the loading label did not appear because the browser will not repaint the page while a long JavaScript task is running; the alert box forced a repaint, which is why it looked like it "fixed" the problem. As suggested, yielding to the event loop (setTimeout) or letting the browser paint first is the right idea. The best modern pattern is: insert a loading indicator into the DOM, yield so the browser can paint, then perform an asynchronous request for child nodes and remove the indicator when the response arrives.
Avoid busy-wait loops like jsWaitForDelay (they block the event loop) and avoid synchronous XHR (deprecated and blocks UI). Instead, show a small loader element (use role="status" or aria-busy for accessibility), then use requestAnimationFrame or a short setTimeout to let the browser update before starting the network call. When data returns, build the child nodes with DOM methods (or assign innerHTML once) and remove the loader.
Example pattern:
function onNodeClick(nodeId) {
const node = document.getElementById(nodeId);
const loader = document.createElement('span');
loader.className = 'tree-loading';
loader.textContent = 'Loading...';
loader.setAttribute('role', 'status');
node.appendChild(loader);
requestAnimationFrame(() => {
fetch('/getChildren?node=' + encodeURIComponent(nodeId))
.then(r => { if (!r.ok) throw new Error(r.statusText); return r.json(); })
.then(children => {
const frag = document.createDocumentFragment();
children.forEach(c => {
const div = document.createElement('div');
div.textContent = c.label;
frag.appendChild(div);
});
node.appendChild(frag);
})
.catch(err => { loader.textContent = 'Error'; console.error(err); })
.finally(() => loader.remove());
});
} Notes: if the server returns HTML, set innerHTML in a single assignment; if returning JSON, build nodes to avoid XSS. For details see the Fetch API, requestAnimationFrame, and the ARIA attribute aria-busy.
Recommended Answers
Jump to Post— me655321 1Although it's hard to believe you have enough of a delay just showing content to warrant a loading bar, I think the problem you're having is that the window won't update during your function. You might try doing a setTimeout to finish the function and give the window a chance …
Jump to Post— me655321 1When you use the alert function it forces the window to update. Using setTimeout will have the same effect. The key is to use the setTimeout right after you display 'krikor' and point it to a second function that does the rest. Here is how you would use it in …
All 7 Replies
hajjo 0 Junior Poster
here is a sample code
a href="javascript:Toggle('menu1', 'sub1');">
<span id="sub1">+</span><b> Menu 1</b> </a>
<div id="menu1" style="display: none; margin-left: 13px;">
<a href="javascript:Toggle('menu1.1', 'sub1_1');">
<span id="sub1_1">+</span> Submenu 1.1 </a>
<br>
<div id="menu1.1" style="display: none; margin-left: 13px;">
<a href="menunumber.asp?submenu=1.1.1" target="main">
Go to URL 1.1.1 </a>
<br>
<a href="menunumber.asp?submenu=1.1.2" target="main">
Go to URL 1.1.2 </a>
</div>
<a href="javascript:Toggle('menu1.2', 'sub1_2');">
<span id="sub1_2">+</span> Submenu 1.2 </a>
<div id="menu1.2" style="display: none; margin-left: 13px;">
<a href="menunumber.asp?submenu=1.2.1" target="main">
Go to URL 1.2.1 </a>
</div>
</div>
<br>
<a href="javascript:close();"><b>Collapse menu</b> </a> so how to add loading part?
where do i add this? <b style='display:inline-block; margin:2 2 10 30;'>Loading...</b> ? and how to control it?
hajjo 0 Junior Poster
so i have done this
<html>
<head>
<title> My incompatible tree menu </title>
<style type="text/css">
a:link{text-decoration: none; color: 004884}
a:visited{text-decoration: none; color: 004884}
a:hover{text-decoration: underline; color: 004884}
font-family: verdana;}
</style>
<script language="javascript">
//Checks if menu is collapsed or expanded and then expands or collapses accordingly.
function Toggle(which, under) {
var visible = document.getElementById (which).style.display != "none"
//This is the div that should be expanded or collapsed.
var obj = document.getElementById (which);
//This is the div that is clicked to change the plus/minus sign.
var sub1 = document.getElementById (under);
var obj1 = document.getElementById ("menus");
if(obj1.style.display = "none")
obj1.style.display = "block";
if(obj.style.display = "none") {
obj.style.display = "block"
sub1.innerText = "–"
}
obj1.style.display = "none";
if(visible) {
obj.style.display ="none"
sub1.innerText = "+"
}
}
//Collapses the menu completely when called.
function close() {
divs = document.getElementsByTagName("div");
keys = document.getElementsByTagName("span");
for (i=0; i<divs.length; i++)
divs[i].style.display="none";
for (i=0; i<keys.length; i++)
keys[i].innerText ="+"
}
</script>
</head>
<body>
<a href="javascript:Toggle('menu1', 'sub1');">
<span id="sub1">+</span><b> Menu 1</b> </a>
<div id="menu1" style="display: none; margin-left: 13px;">
<a href="javascript:Toggle('menu1.1', 'sub1_1');">
<span id="sub1_1">+</span> Submenu 1.1 </a>
<div id="menus" style="display: none;">
<b style='display:inline-block; margin:2 2 10 30;'>Loading...</b>
</div>
<br>
<div id="menu1.1" style="display: none; margin-left: 13px;">
<a href="menunumber.asp?submenu=1.1.1" target="main">
Go to URL 1.1.1 </a>
<br>
<a href="menunumber.asp?submenu=1.1.2" target="main">
Go to URL 1.1.2 </a>
</div>
<a href="javascript:Toggle('menu1.2', 'sub1_2');">
<span id="sub1_2">+</span> Submenu 1.2 </a>
<div id="menu1.2" style="display: none; margin-left: 13px;">
<a href="menunumber.asp?submenu=1.2.1" target="main">
Go to URL 1.2.1 </a>
</div>
</div>
<br>
<a href="javascript:close();"><b>Collapse menu</b> </a>
</body>
</html> when i click on node submenu 1.1 loading word isnt appearing until new nodes show up
however when i put word alert between showing word load and disappearing it..it shows up..
<html>
<head>
<title> My incompatible tree menu </title>
<style type="text/css">
a:link{text-decoration: none; color: 004884}
a:visited{text-decoration: none; color: 004884}
a:hover{text-decoration: underline; color: 004884}
font-family: verdana;}
</style>
<script language="javascript">
//Checks if menu is collapsed or expanded and then expands or collapses accordingly.
function Toggle(which, under) {
var visible = document.getElementById (which).style.display != "none"
//This is the div that should be expanded or collapsed.
var obj = document.getElementById (which);
//This is the div that is clicked to change the plus/minus sign.
var sub1 = document.getElementById (under);
var obj1 = document.getElementById ("menus");
if(obj1.style.display = "none")
obj1.style.display = "block";
alert("here");
if(obj.style.display = "none") {
obj.style.display = "block"
sub1.innerText = "–"
}
obj1.style.display = "none";
if(visible) {
obj.style.display ="none"
sub1.innerText = "+"
}
}
//Collapses the menu completely when called.
function close() {
divs = document.getElementsByTagName("div");
keys = document.getElementsByTagName("span");
for (i=0; i<divs.length; i++)
divs[i].style.display="none";
for (i=0; i<keys.length; i++)
keys[i].innerText ="+"
}
</script>
</head>
<body>
<a href="javascript:Toggle('menu1', 'sub1');">
<span id="sub1">+</span><b> Menu 1</b> </a>
<div id="menu1" style="display: none; margin-left: 13px;">
<a href="javascript:Toggle('menu1.1', 'sub1_1');">
<span id="sub1_1">+</span> Submenu 1.1 </a>
<div id="menus" style="display: none;">
<b style='display:inline-block; margin:2 2 10 30;'>Loading...</b>
</div>
<br>
<div id="menu1.1" style="display: none; margin-left: 13px;">
<a href="menunumber.asp?submenu=1.1.1" target="main">
Go to URL 1.1.1 </a>
<br>
<a href="menunumber.asp?submenu=1.1.2" target="main">
Go to URL 1.1.2 </a>
</div>
<a href="javascript:Toggle('menu1.2', 'sub1_2');">
<span id="sub1_2">+</span> Submenu 1.2 </a>
<div id="menu1.2" style="display: none; margin-left: 13px;">
<a href="menunumber.asp?submenu=1.2.1" target="main">
Go to URL 1.2.1 </a>
</div>
</div>
<br>
<a href="javascript:close();"><b>Collapse menu</b> </a>
</body>
</html> me655321 1 Junior Poster in Training
Although it's hard to believe you have enough of a delay just showing content to warrant a loading bar, I think the problem you're having is that the window won't update during your function. You might try doing a setTimeout to finish the function and give the window a chance to update...
function Toggle(which, under) {
var visible = document.getElementById (which).style.display != "none"
//This is the div that should be expanded or collapsed.
var obj = document.getElementById (which);
//This is the div that is clicked to change the plus/minus sign.
var sub1 = document.getElementById (under);
var obj1 = document.getElementById ("menus");
if(obj.style.display = "none") {
obj.style.display = "block"
sub1.innerText = "–"
}
obj1.style.display = "none";
if(visible) {
obj.style.display ="none"
sub1.innerText = "+"
}
}
function startToggle(which, under){
var obj1 = document.getElementById ("menus");
if(obj1.style.display = "none")
obj1.style.display = "block";
setTimeout("Toggle('"+which+"','"+under+"')",1);
} And then call startToggle() instead of Toggle().
Also a better method of showing the loading tag might be to dynamically add it to the required menu tag via appendChild, then removing it when done...just a thought.
hajjo 0 Junior Poster
Take this mini example
<HTML>
<INPUT TYPE=button ID=btnEmergency VALUE="CLICK!" onclick="startToggle('Link1')"/>
<div id='Link1' style='display: none'>
krikor
</div>
</HTML>
<script>
function startToggle(value)
{
var target1 = document.getElementById(value);
if (target1.style.display == 'none') {
target1.style.display = 'block';
} else {
target1.style.display = 'none';
}
jsWaitForDelay(5000);
if (target1.style.display == 'none') {
target1.style.display = 'block';
} else {
target1.style.display = 'none';
}
}
function jsWaitForDelay(delay) {
var startTime = new Date();
var endTime = null;
do {
endTime = new Date();
} while ((endTime - startTime) < delay);
}
</script> on button click, i show the word krikor.. and after 5 seconds i disappear it. it doenst work
when i add alert("here") after jsWaitForDelay(5000);..
it waits 5 seconds..show the word and alert bxo together..and then disappears
so why is this happening? why on alert box? it stops and shows everything..and when no alert box..the function has to finish so that all changes show up
me655321 1 Junior Poster in Training
When you use the alert function it forces the window to update. Using setTimeout will have the same effect. The key is to use the setTimeout right after you display 'krikor' and point it to a second function that does the rest. Here is how you would use it in the example you gave...
<HTML>
<INPUT TYPE=button ID=btnEmergency VALUE="CLICK!" onclick="startToggle('Link1')"/>
<div id='Link1' style='display: none'>
krikor
</div>
</HTML>
<script>
function startToggle(value){
var target1 = document.getElementById(value);
if (target1.style.display == 'none') {
target1.style.display = 'block';
} else {
target1.style.display = 'none';
}
setTimeout("endToggle('"+value+"')",1);
}
function endToggle(value){
jsWaitForDelay(1000);
var target1 = document.getElementById(value);
if (target1.style.display == 'none') {
target1.style.display = 'block';
} else {
target1.style.display = 'none';
}
}
function jsWaitForDelay(delay) {
var startTime = new Date();
var endTime = null;
do {
endTime = new Date();
} while ((endTime - startTime) < delay);
}
</script> hajjo 0 Junior Poster
I worked it out with settimeout, very much thank you for the help.
The code i posted here are just testings. i am actually getting data from database and creating the div's dynamically..
its a tree, when node is clicked i want loading... to be appeared until i get data from database and generate its childs...
settimeout did it perfectly. i implemented it on main program and worked out
me655321 1 Junior Poster in Training
Glad I could help...don't forget to mark this thread Solved
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.