Why does this JS loop re-write of the entire page - javascript

I have this web page that has a loop to write out a bunch of list elements.
On loading, the for loops runs 56 times, and uses the CSS styles and all.
But, I have the input button that runs the loops() functions running the do code block, and this basically reloads the page with the new list, and none of my other html appears.
How can I make a loops() that will add my list elements and grow the list rather than re-load the whole doc?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="jscss.css">
<script src="js.js"></script>
</head>
<body>
<script>
function loops(){
var i= 0;
do{
document.write("<li id='list'>"+i+"</li>");
i++;
}while(i < 100);
}
document.write("Hello World");
document.write("<br>");
document.write("<input id='string' type='text'>");
document.write("<input onClick='loops()' type='button' value='Submit'>");
document.write("<ul id='list'>");
for (i = 0; i <= 56; i++) {
document.write("<li>"+i+"</li>");
};
document.write("</ul>");
</script>

Because calling document.write after the document is loaded will clear the document.
Note: as document.write writes to the document stream, calling
document.write on a closed (loaded) document automatically calls
document.open which will clear the document.
So by the time you click the button, the document would have already loaded, so it is getting cleared.
You can use appendChild() or add the new content to the innerHTML of the parent element
function loops() {
var i = 0,
lst = document.getElementById('list'),
html = '';
do {
html += "<li>" + i + "</li>";
} while (++i < 100);
lst.innerHTML += html;
}
document.write("Hello World");
document.write("<br>");
document.write("<input id='string' type='text'>");
document.write("<input onClick='loops()' type='button' value='Submit'>");
document.write("<ul id='list'>");
for (i = 0; i <= 56; i++) {
document.write("<li>" + i + "</li>");
};
document.write("</ul>");

Because you use document.write() don't use document.write(). Google innerHTML.

Related

printing output in the same window html and javascript

Below is the code I have written. Every button I press takes me to a new window where another there is another button that is to be pushed by the user. When that button is pushed, an alphabet is printed out. Every alphabet opens to a new page. This setting is not very user friendly and I am trying to get the output on the same window.
Here is the code I have written for the main page:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Alphabets</title>
<script>
function alphabet(alpha){
switch(alpha){
case 1:
window.open("alphabetI.html");
break;
case 2:
window.open("alphabetSS.html");
break;
case 3:
window.open("alphabetH.html");
break;
case 4:
window.open("alphabetA.html");
break;
}
}
</script>
</head>
<body>
<h2>I'm Isha</h2>
<h3> Press either of these buttons to see the output</h3>
<button onclick = "alphabet(1)" >Button-1</button>
<button onclick = "alphabet(2)" >Button-2</button>
<button onclick = "alphabet(3)" >Button-3</button>
<button onclick = "alphabet(4)" >Button-4</button>
</body>
</html>
Here is the code I have written for Alphabet I which is written on "alphabetI.html":
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Alphabet:I</title>
<script>
function here(){
var a;
while(a != 14){
for(a = 0 ; a < 4 ; a++){
document.write("* ");
}
document.write("<br>");
for( a = 4; a < 10 ; a++) {
document.write(" * ");
document.write("<br>");
}
for( a = 10 ; a < 14 ; a++) {
document.write("* ");
}
}
}
</script>
</head>
<body>
<h2><u>I</u>SHA</h2>
<button onclick = "here()" >Alphabet I</button>
</body>
</html>
Codes for other alphabets are similar and include for loops.
I tried using window.alert() as it opens the alert box on the same page thus making it convenient, but that does not give me the desired output when placed in a for loop. For instance, if my loop runs 3 times, it will give me the alert message 3 times rather than printing the asterisks three times in one alert message.
Then I tried console.log, but I realized that it prints a message to the web console, so it would not be of any use. I also tried using document.getElementbyId(); but again, that would not work in a for loop as the id of the place I am printing it to is just being replaced by my new value, thus, it would not print more than one element or value from a for loop.
I finally used document.write() which works in every way but when a button is clicked, the output is printed on the same page and replaces the other buttons. That way, the user can neither press another button because the buttons are replaced by the generated alphabet, nor can the user go back.
Eventually I created more html files and pasted my code to create the letters using for loops there, then I used window.open() to open a new window displaying the code. However, this is not very user friendly, and I would like for output to be displayed on the same page, underneath the buttons.
You can create a div on the screen and give it an ID. Then refer to that Div and add content via innerHTML. In your buttons onclick, you can refer to each function too, no need for a switch.
This is a quick example. The key to reusing an element is adding content for example using += instead of replacing it with =
const output = document.querySelector("#output")
function alpha1() {
output.innerHTML = "";
var a;
while (a != 14) {
for (a = 0; a < 4; a++) {
output.innerHTML += "* ";
}
output.innerHTML += "<br>";
for (a = 4; a < 10; a++) {
output.innerHTML += " * ";
output.innerHTML += "<br>";
}
for (a = 10; a < 14; a++) {
output.innerHTML += "* ";
}
}
}
function alpha2() {output.innerHTML = "2";}
function alpha3() {output.innerHTML = "3";}
function alpha4() {output.innerHTML = "4";}
<h2>I'm Isha</h2>
<h3> Press either of these buttons to see the output</h3>
<button onclick="alpha1()">Button-1</button>
<button onclick="alpha2()">Button-2</button>
<button onclick="alpha3()">Button-3</button>
<button onclick="alpha4()">Button-4</button>
<div id="output"></div>
use JQuery to make the process easy
add JQuery CDN in the head section
<script
src="https://code.jquery.com/jquery-3.6.3.min.js"
integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU="
crossorigin="anonymous"></script>
create a div with id="container"
then use load() function of Jquery
function alphabet(alpha) {
switch (alpha) {
case 1:
$("#container").load("alphabetI.html");
break;
like this
here is the complete code
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta name="viewport" content="width=device-width">
<meta charset="utf-8">
<title>Alphabets</title>
<script
src="https://code.jquery.com/jquery-3.6.3.min.js"
integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU="
crossorigin="anonymous"></script>
</head>
<body>
<h2>I'm Isha</h2>
<h3> Press either of these buttons to see the output</h3>
<button onclick="alphabet(1)">Button-1</button>
<button onclick="alphabet(2)">Button-2</button>
<button onclick="alphabet(3)">Button-3</button>
<button onclick="alphabet(4)">Button-4</button>
<div id="container"></div>
<script>
function alphabet(alpha) {
switch (alpha) {
case 1:
$("#container").load("alphabetI.html");
break;
case 2:
window.open("alphabetSS.html");
break;
case 3:
window.open("alphabetH.html");
break;
case 4:
window.open("alphabetA.html");
break;
}
}
</script>
</body>
</html>
i hope it will help you !!..

My Extensions Google Chrome Does not Work?

I create a simple code to extract URL from a website
but it's not working when I click on icon extensions
My js code
var el = document.getElementById('myPopup');
el && el.addEventListener('click', yourFunction, false);
function yourFunction() {
let x = document.querySelectorAll("a");
let myarray = [];
for (let i = 0; i < x.length; i++) {
let nametext = x[i].textContent;
let cleantext = nametext.replace(/\s+/g, " ").trim();
let cleanlink = x[i].href;
myarray.push([cleantext, cleanlink]);
}
function make_table() {
let links_table = "<table><thead><th>Name</th><th>Links</th></thead><tbody>";
for (let i = 0; i < myarray.length; i++) {
links_table += "<tr><td>" + myarray[i][0] + "</td><td>" + myarray[i][1] + "</td></tr>";
}
let w = window.open("");
w.document.write(links_table);
console.log(w);
console.log(links_table);
}
make_table();
}
yourFunction();
My HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<dev>
<button id="myPopup">Clickme</button>
</dev>
<script src="popup.js"></script>
</body>
</html>
when i click on Clickme the url not show me just empty table
can you tell me where is the Error?
video
imgur.com/a/0OS60qG
The error happens since the popup script does not have access to the list of "a" tags. When you ran it on the browser console it works cause you are manipulating the page content, meanwhile, on the popup, it only interacts with the popup.html page.
Content scripts should be the only scripts able to manipulate the page content, so to fix that you probably should send a message to a content script when clicking on the button, so the content script can scrap the links and send them as a response to the popup or output as you want.
This other question may help you to see how to send messages between files:
How to send the message from popup.html to content script?

JavaScript function only works after page reload

I know this has been asked a lot on here, but all the answers work only with jQuery and I need a solution without it.
So after I do something, my Servlet leads me to a JSP page. My JS function should populate a drop down list when the page is loaded. It only works properly when the page is refreshed tho.
As I understand this is happening because I want to populate, using innerHTML and the JS function gets called faster then my HTML page.
I also get this error in my Browser:
Uncaught TypeError: Cannot read property 'innerHTML' of null
at XMLHttpRequest.xmlHttpRequest.onreadystatechange
I had a soulution for debugging but I can't leave it in there. What I did was, every time I opened that page I automatically refreshed the whole page. But my browser asked me every time if I wanted to do this. So that is not a solution that's pretty to say the least.
Is there something I could do to prevent this?
Edit:
document.addEventListener("DOMContentLoaded", pupulateDropDown);
function pupulateDropDown() {
var servletURL = "./KategorienHolen"
let xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {
console.log(xmlHttpRequest.responseText);
let katGetter = JSON.parse(xmlHttpRequest.responseText);
JSON.stringify(katGetter);
var i;
for(i = 0; i <= katGetter.length -1; i++){
console.log(katGetter[i].id);
console.log(katGetter[i].kategorie);
console.log(katGetter[i].oberkategorie);
if (katGetter[i].oberkategorie === "B") {
document.getElementById("BKat").innerHTML += "" + katGetter[i].kategorie + "</br>";
} else if (katGetter[i].oberkategorie === "S") {
document.getElementById("SKat").innerHTML += "" + katGetter[i].kategorie + "</br>";
} else if (katGetter[i].oberkategorie ==="A") {
document.getElementById("ACat").innerHTML += "" + katGetter[i].kategorie + "</br>";
}
// document.getElementsByClassName("innerDiv").innerHTML = "" + katGetter.kategorie + "";
// document.getElementById("test123").innerHTML = "" + katGetter.kategorie + "";
}
}
};
xmlHttpRequest.open("GET", servletURL, true);
xmlHttpRequest.send();
}
It can depend on how + when you're executing the code.
<html>
<head>
<title>In Head Not Working</title>
<!-- WILL NOT WORK -->
<!--<script>
const p = document.querySelector('p');
p.innerHTML = 'Replaced!';
</script>-->
</head>
<body>
<p>Replace This</p>
<!-- Will work because the page has finished loading and this is the last thing to load on the page so it can find other elements -->
<script>
const p = document.querySelector('p');
p.innerHTML = 'Replaced!';
</script>
</body>
</html>
Additionally you could add an Event handler so when the window is fully loaded, you can then find the DOM element.
<html>
<head>
<title>In Head Working</title>
<script>
window.addEventListener('load', function () {
const p = document.querySelector('p');
p.innerHTML = 'Replaced!';
});
</script>
</head>
<body>
<p>Replace This</p>
</body>
</html>
Define your function and add an onload event to body:
<body onload="pupulateDropDown()">
<!-- ... -->
</body>
Script needs to be loaded again, I tried many options but <iframe/> works better in my case. You may try to npm import for library related to your script or you can use the following code.
<iframe
srcDoc={`
<!doctype html>
<html>
<head>
<style>[Style (If you want to)]</style>
</head>
<body>
<div>
[Your data]
<script type="text/javascript" src="[Script source]"></script>
</div>
</body>
</html>
`}
/>
Inside srcDoc, it's similar to normal HTML code.
You can load data by using ${[Your Data]} inside srcDoc.
It should work :
document.addEventListener("DOMContentLoaded", function(){
//....
});
You should be using the DOMContentLoaded event to run your code only when the document has been completely loaded and all elements have been parsed.
window.addEventListener("DOMContentLoaded", function(){
//your code here
});
Alternatively, place your script tag right before the ending body tag.
<body>
<!--body content...-->
<script>
//your code here
</script>
</body>

inject several hundred of images into divs

I would like to know how to add several hundred images in divs but automatically. I have a folder with the images and I want to know if there is a technique to avoid copying and pasting the same code.
For example: <img src="img/01.png">
the idea is to inject this code into the divs and change the names of the images: 01.png, 02.png, 03.png...
Thanks for the help.
You can generate the html using javascript if you run this html page it'll display the tags for the first 99 images.
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
</head>
<body>
<p id="my_output"></p>
<script>
let escapeHTML = function (aValue) {
return (
aValue.replace(/>/g, '>').
replace(/</g, '<').
replace(/"/g, '"')
)
}
let myOutput = document.querySelector('#my_output')
for (let i = 1; i < 100; ++i) {
let paddedIndex = ('0' + i).slice(-2)
myOutput.innerHTML += escapeHTML('<img src="img/' + paddedIndex + '.png">') + '<br>'
}
</script>
</body>
</html>
You can then copy paste the output into your code.

JavaScript HTML Rendering Out of Sync -- Spring MVC Project

I have a dashboard site in the works, and it makes use of SpringMVC, FusionCharts, and Bootstrap (to give an architectural overview). When I freshly start up the Tomcat server, the very first time I'm served the index page, a panel of buttons will not render properly. I get the correct number of white circles with question marks as made in the first of 3 javascript functions. If I refresh the page, the intended red and green results immediately come up, generated by the second script function.
As a preamble, the panel with buttons on it is correctly generated with the right count, correct names, correct HREFs and all else. The colors just do not change until the page is refreshed. Back when this project was first constructed, the data was being gathered via http request server-side. It was comparably slow to what is occurring now: loading the data from a file server-side and sending it through in the same format. The old way always produced the correct colors and icons after a 10-second wait. Now, the buttons just remain blank white until I refresh the page, and then I get the right results.
I believe this is just the result of two Javascript functions stepping on each other, even though I know JavaScript is single-threaded. If not, I'm stumped and lost.
Index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Free Bootstrap Admin Template : Dream</title>
<!-- Bootstrap Styles-->
<link href="css/bootstrap.min.css" rel="stylesheet" />
<!-- FontAwesome Styles-->
<link href="css/font-awesome.css" rel="stylesheet" />
<!-- Morris Chart Styles-->
<link href="js/morris/morris-0.4.3.min.css" rel="stylesheet" />
<!-- Custom Styles-->
<link href="css/custom-styles.css" rel="stylesheet" />
<!-- Google Fonts-->
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css' />
<script type="text/javascript" src="js/fusioncharts/core/fusioncharts.js"></script>
<script type="text/javascript" src="js/fusioncharts/themes/fusioncharts.theme.fint.js"></script>
</head>
<body>
...
<!-- this is where the button panel is correctly created on every load
but only correctly modified on the 2nd load and later -->
<div class="row"> <div id="AppStatusTable"></div> </div>
...
<script src="js/jquery-1.10.2.js"></script>
<!-- Bootstrap Js -->
<script src="js/bootstrap.min.js"></script>
<!-- Metis Menu Js -->
<script src="js/jquery.metisMenu.js"></script>
<!-- Morris Chart Js -->
<script src="js/morris/raphael-2.1.0.min.js"></script>
<script src="js/morris/morris.js"></script>
<!-- Custom Js -->
<!--
<script src="js/custom-scripts.js"></script> -->
<script>
$(document).ready(function(){
$.get("/buttoninfo", function(data, status) {
tableMaker(data, "AppStatusTable");
});
$.get("/appstatus", function(data, status) {
appStatus(data);
});
$.get("/stackstatus", function(data, status) {
stackUpdater(data);
});
});
</script>
</body>
These last 3 functions fill out the html of a panel to contain a dynamic number of buttons, modify the inner html of those buttons, and then update other panels. The third currently takes a while and always produces correct results. I don't suspect it is the issue.
dashboard.js
function templateLoader(appTag) {
//$.get('/app/' + appTag);
window.location = "/app/" + appTag;
}
function appStatus(data){
for(var i = 0; i < data.length; ++i) {
if(data[i][1] == "up"){
$("#" + data[i][0] + "-appcheck").removeClass("btn-default");
$("#" + data[i][0] + "-appcheck").addClass("btn-success");
$("#" + data[i][0] + "-appcheck-icon").removeClass("fa-exclamation-circle");
$("#" + data[i][0] + "-appcheck-icon").addClass("fa-check");
} else if(data[i][1] == "down"){
$("#" + data[i][0] + "-appcheck").removeClass("btn-default");
$("#" + data[i][0] + "-appcheck").addClass("btn-danger");
$("#" + data[i][0] + "-appcheck-icon").removeClass("fa-exclamation-circle");
$("#" + data[i][0] + "-appcheck-icon").addClass("fa-close");
}
}
}
function tableMaker(data, tableID) {
/* vars used below as the skeleton of the injected buttons*/
var i = 0, j = 0, colLimit = 12;
for(; i < data.length;){
for (var j = 0; j < colLimit && i < data.length; ++j, ++i) {
mytable += colStart + data[i][2] + titleEnd + '\n' + buttonStart + data[i][2] + buttonMiddle1 +
data[i][2] + buttonMiddle2 + data[i][2] + buttonMiddle3 + '><i id="' + data[i][2] +
buttonEnd + colEnd;
}
}
panel += mytable + panelEnd;
document.getElementById(tableID).innerHTML = panel;
}
function stackUpdater(data){
for(var i = 0; i < data.length; ++i){
var curStack = data[i][0];
for(var j = 1; j < data[i].length; j++) {
if(data[i][j] == null) {
break;
} else {
$("#" + curStack + j).removeClass("progress-bar-info");
if(data[i][j] == "up") {
$("#" + curStack + j).addClass("progress-bar-success");
} else {
$("#" + curStack + j).addClass("progress-bar-danger");
}
}
}
}
}
I understand browsers cache the results of javascript functions, but the third function is run on every refresh, so why wouldn't the first two be? And thus, why would the results of the second function only appear after refreshing?
What needs to be changed to make sure the buttons modify correctly the FIRST time this page is loaded?
UPDATE 1
After inserting alerts between the function calls, the rendering works on the first try, so what's the correct way to ensure synchronization without this?
Bottom of Index.html:
$(document).ready(function(){
$.get("/buttoninfo", function(data, status) {
tableMaker(data, "AppStatusTable");
});
alert("Button table made!");
$.get("/appstatus", function(data, status) {
appStatus(data);
});
alert("Button Data Updated!");
$.get("/stackstatus", function(data, status) {
stackUpdater(data);
});
alert("Stack Data Updated!");
});
</script>
Instead of using $.get try using $.ajax with cache set to false. If $.get is absolute necessary try adding a timestamp with each request. You may refer to How to set cache: false in jQuery.get call.
Hope that help.

Categories