how to make progressBar work during long loops of computing? - javascript

how to make progressBar work during long-time loops of computing?
by using setInterval()? by using async or await? how? please show me in code.
I know using VUE's bind can help,but I want simple js-code without any outside import to do this.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style type="text/css">
#myProgress {
width: 100%;
background-color: #ddd;
}
#myBar {
width: 10%;
height: 30px;
background-color: #4caf50;
text-align: center;
line-height: 30px;
color: white;
}
</style>
</head>
<body>
<div style="text-align: center">
<h2>RSA!</h2>
<div id="myProgress">
<div id="myBar">10%</div>
</div>
<br />
<label>输入素数的范围,最大:21474836:</label>
<input
type="number"
id="myCount"
placeholder=""
value="2147483"
min="100"
max="21474836"
/>
<button class="dom1" onclick="initPrim()">1.素数生成器</button><br />
<div
id="result0"
style="width: 100%; word-break: break-all; word-wrap: break-word"
></div>
<br />
</div>
</body>
<!--21474836 2147483647 sqrt(Integer.MAX)=46341-->
<script>
var PrimeArray = [2];
//initPrim 生成素数表
async function initPrim(limit) {
document.getElementById("result0").innerHTML = " ";
var count = document.getElementById("myCount").value;
for (i = 2; i < count; i++) {
let j;
let tag = 0;
for (
j = 0;
j < PrimeArray.length && PrimeArray[j] < Math.sqrt(i) + 1;
j++
) {
if (i % PrimeArray[j] == 0) {
tag = 1;
break;
}
}
if (tag == 0) {
PrimeArray.push(i);
}
}
document.getElementById("result0").append("p=\t" + PrimeArray);
}
</script>
</html>

HTML Web Workers is the solution that I need.
Question closed!
https://www.w3schools.com/HTML/html5_webworkers.asp

Related

ReferenceError: document is not defined when creating variable

I'm running my code in node.js I've seen that running code in node could play a part. But this was never a problem. It keeps saying my variable that points to my element 'document is not defined'. I don't know what I'm doing wrong, I'm linking it correctly but still confused I also tried putting my scripts on the bottom and top with defer.
let seconds = 00;
let tens = 00;
let appendTens = document.querySelector('#tens');
let appendSeconds = document.querySelector('#seconds');
let stop = document.querySelector('#button-stop');
let start = document.querySelector('#button-start');
let reset = document.querySelector('#button-reset');
let interval; //store timer values
// this function will run when start is clicked
const startTimer = () =>{
tens++
if(tens < 9){
appendTens.textContent = `0${tens}`
}
if(tens > 9){
appendTens.textContent = tens;
}
if(tens > 99){
seconds++
appendSeconds.textContent = `0${seconds}`;
tens = 0;
appendTens.textContent = "0" + 0;
}
if(seconds > 9){
appendSeconds.textContent = seconds;
}
};
start.onclick = function(){
interval = setinterval(startTimer)
}
<!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>Stopwatch</title>
<link rel="stylesheet" href="stopwatch.css">
</head>
<body>
<div class="wrapper">
<h1>Stopwatch</h1>
<h2>Vanilla JavaScript Stopwatch</h2>
<p><span id="seconds">00</span>:<span id="tens">00</span></p>
<button id="button-start">Start</button>
<button id="button-stop">Stop</button>
<button id="button-reset">Reset</button>
</div>
<script type="module" src="stopwatcj.js"></script>
</body>
</html>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-self: center;
background-color: rgb(248, 180, 55);
}
.wrapper {
margin-top: 10%;
text-align: center;
color: #fff;
}
.wrapper button {
background-color: rgb(248, 180, 55);
border: 1px solid white;
padding: 10px 20px;
color: #fff;
}
.wrapper button:hover {
cursor: pointer;
opacity: 30%;
}
document which is a part of Html DOM is not a part of nodejs. Since you might be using nodejs to compile your js code that's why you are getting this error. Please try to run this simply in browser.

To do list clear button

im creating to-do list without any tutorial and i stucked when i tried to code clear button. I have a problem because this code removing only half of 'li' items in my list. I checked length of document.querySelectorAll('li) and it return correct value of list length , and i think in each loop execution i delete first element because document.querySelector('li) return only first element. Could you help me? And another question : Is somewhere in web program that can i see step by step exection of my code with DOM? I found few sites but there i can only debug code without html and css.
There is my code:
let clear = document.querySelector('.clear');
let input = document.querySelector('.input');
let submit = document.querySelector('.submit');
let list = document.querySelector('.list');
submit.addEventListener('click', function() {
const el = document.createElement('li');
list.appendChild(el);
let items = document.querySelectorAll('li');
for (i = 0; i < items.length; i++) {
items[items.length - 1].textContent = input.value;
}
});
clear.addEventListener('click', function() {
console.log(document.querySelectorAll('li').length);
for (i = 0; i < document.querySelectorAll('li').length; i++)
list.removeChild(document.querySelector('li'));
console.log(list);
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
max-height: 100vh;
max-width: 90vw;
}
h1 {
text-align: center;
}
.wrap {
padding: 50px;
border: 2px solid black;
border-radius: 20%;
background-color: red;
}
.list {
width: 100%;
margin-left: 100px;
font-size: 2rem;
font-weight: bold;
}
<!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>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrap">
<h1>To do list</h1>
<input type="text" placeholder="Add an item!" class="input" />
<button class="submit">Submit</button>
<button class="clear">Clear List</button>
</div>
<ol class="list"></ol>
<script src="script.js"></script>
</body>
</html>
In your case, your loop was calculating its length each time of the loop while i was still incrementing
I you had two elements, it would have deleted the first item, then at the second loop, the list would have a length of 1 and i would be equals to 1 so the loop would break
You can use a for of loop instead of a for i loop and remove the child by reference
clear.addEventListener('click', function() {
const childs = document.querySelectorAll('li')
for (const child of childs){
list.removeChild(child)
}
});
Note : this can also be done using a for i loop if you instantiate the list
clear.addEventListener('click', function() {
const childs = document.querySelectorAll('li')
for (let i = 0; i < childs.length; i++){
list.removeChild(childs[i])
}
});
I invent a new way to solve it
clear.addEventListener('click', function () {
for (i = 0; i < document.querySelectorAll('li').length + i; i++)
list.removeChild(document.querySelector('li'));
console.log(list);
});
In each iteration I add 'i' . So i update length

Trying to make a light bulb using HTML & CSS & JS

<!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>3 Circle</title>
<style>
body {background: black;}
.container {display: flex;}
.circle {
width: 500px;
height: 500px;
-webkit-border-radius: 250px;
-moz-border-radius: 250px;
border-radius: 250px;
background: white;
}
.active {
background: yellow !important;
color: red;
}
</style>
</head>
<body>
<section class="container">
<button class="circle circle1">Circle1</button>
<button class="circle circle2">Circle2</button>
<button class="circle circle3">Circle3</button>
</section>
<script>
let cir1 = document.querySelector('.circle1')
let cir2 = document.querySelector('.circle2')
let cir3 = document.querySelector('.circle3')
let allCircle = document.querySelectorAll('.circle');
cir1.addEventListener('onClick', onButton1Click);
cir2.addEventListener('onClick', onButton2Click);
cir3.addEventListener('onClick', onButton3Click);
function onButton1Click() {
if (cir1.classList.contains("active")) {
allCircle.classList.remove('active');
} else {
allCircle.classList.remove('active');
cir1.classList.add('active');
}
}
function onButton2Click() {
if (cir2.classList.contains("active")) {
allCircle.classList.remove('active');
} else {
allCircle.classList.remove('active');
cir2.classList.add('active');
}
}
function onButton3Click() {
if (cir3.classList.contains("active")) {
allCircle.classList.remove('active');
} else {
allCircle.classList.remove('active');
cir3.classList.add('active');
}
}
</script>
</body>
</html>
I am trying to make 3 light bulbs represented by circles using HTML & CSS.
So if I turn one light bulb on using the button, the other ones should turn off using the addeventlistener. I can't find ways to make the light bulb turn yellow. Is there anything I am doing wrong? I looked for typos but I can't find any.
A few small things need to changed here.
The event type to be passed to the addEventListener is 'click' rather than 'onClick'.
The variable allCircle returns a list of dom nodes and not a single dom node. So it is essentially a []. Hence properties and methods that are available on a dom node are not accessible on the variable. What you can rather do is write a loop to access each element of the array and then modify their classes one by one
Might also suggest you to put debugger inside your code to see what is happening line by line. This article by Google should help you on using the Chrome dev tools.
This is my first answer on Stack Overflow.
let cir1 = document.querySelector('.circle1')
let cir2 = document.querySelector('.circle2')
let cir3 = document.querySelector('.circle3')
cir1.addEventListener('click', onButton1Click);
cir2.addEventListener('click', onButton2Click);
cir3.addEventListener('click', onButton3Click);
function removeActive() {
cir1.classList.remove('active');
cir2.classList.remove('active');
cir3.classList.remove('active');
}
function onButton1Click() {
removeActive();
cir1.classList.add('active');
}
function onButton2Click() {
removeActive();
cir2.classList.add('active');
}
function onButton3Click() {
removeActive();
cir3.classList.add('active');
}
body {
background: black;
}
.container {
display: flex;
align-items: flex-start;
}
.circle {
width: 100px;
height: 100px;
max-height: 100px;
-webkit-border-radius: 250px;
-moz-border-radius: 250px;
border-radius: 250px;
background: white;
}
.active {
background: yellow !important;
color: red;
}
<!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>3 Circle</title>
</head>
<body>
<section class="container">
<button class="circle circle1">Circle1</button>
<button class="circle circle2">Circle2</button>
<button class="circle circle3">Circle3</button>
</section>
</body>
</html>
There seem to be two issues here.
When adding an event listener for a click event, it must be called with click that is to be passed as the first parameter to the listener, but you've added onClick
querySelectorAll returns a HTMLCollection. So classList will not be a valid property on it. You might want to loop through the elements from allCircles to remove the class.
I've modified the listener and corrected the classist related fix for the first button here https://jsfiddle.net/gr33nw1zard/y7f5wnda/
should be click event, not 'onClick'.
cir1.addEventListener('click', onButton1Click);
Created one common function for all 3 buttons. onClick event is not available in plain javascript, it's the click that is the correct keyword here. Also, you have to iterate over allCircle's object or use getElementsByClass. This will work for you!
<!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>3 Circle</title>
<style>
body {
background: black;
}
.container {
display: flex;
}
.circle {
width: 500px;
height: 500px;
-webkit-border-radius: 250px;
-moz-border-radius: 250px;
border-radius: 250px;
background: white;
}
.active {
background: yellow !important;
color: red;
}
</style>
</head>
<body>
<section class="container">
<button class="circle circle1">Circle1</button>
<button class="circle circle2">Circle2</button>
<button class="circle circle3">Circle3</button>
</section>
<script>
let cir1 = document.querySelector('.circle1')
let cir2 = document.querySelector('.circle2')
let cir3 = document.querySelector('.circle3')
let allCircle = document.querySelectorAll('.circle');
cir1.addEventListener('click', onButtonClick);
cir2.addEventListener('click', onButtonClick);
cir3.addEventListener('click', onButtonClick);
function onButtonClick(e) {
const cir = e.toElement;
if (cir.classList.contains("active")) {
Object.keys(allCircle).map(circle => allCircle[circle].classList.remove('active'));
} else {
Object.keys(allCircle).map(circle => allCircle[circle].classList.remove('active'));
cir.classList.add('active');
}
}
</script>
</body>
</html>
The onClick should be edited to click

jquery masonry style grid issue

trying to make a simple masonry style grid with Jquery but keep running into an issue with weird margins appearing and i can't figure out why. Had a few attempts with similar results. Here's the latest
js
$(document).ready(function () {
var $boxes = $('.box');
var rowPos = 0;
var counter = 0;
$boxes.each(function (ind) {
var boxWidth = $(this).width();
var upperBoxHeight = 0;
var upperBoxPosition = 0;
var top = 0;
rowPos = counter * boxWidth;
counter++;
if(counter >= 3){
counter = 0;
}
if(ind >= 3){
upperBoxHeight = $boxes.eq(ind - 3).height();
upperBoxPosition = $boxes.eq(ind -3).position().top;
top = upperBoxHeight + upperBoxPosition; }
$(this).css({
left: rowPos,
top : top
});
});
});
css
.container{
width: 85%;
margin: auto;
position: relative;
}
.box{
width: 33.3333%;
position: absolute;
}
.box1, .box5{
background: #2baf63;
height: 500px;
}
.box2, .box6{
background: #623ec5;
height: 650px;
}
.box3, .box7{
background: #3e81c5;
height: 300px;
}
.box4, .box8{
background: #9fba43;
height: 400px;
}
markup
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/main.css">
<script src="js/jquery-3.1.0.min.js"></script>
</head>
<body>
<div class="container">
<div class="box box1"><span>box 1</span></div>
<div class="box box2"><span>box 2</span></div>
<div class="box box3"><span>box 3</span></div>
<div class="box box4"><span>box 4</span></div>
<div class="box box5"><span>box 5</span></div>
<div class="box box6"><span>box 6</span></div>
<div class="box box7"><span>box 7</span></div>
<div class="box box8"><span>box 8</span></div>
</div>
<script src="js/functions.js"></script>
</body>
</html>
strange thing is, if i open the inspector and refresh the page, all boxes lock into their intended position. if i close the inspector and refresh again, problem comes back.
then with inspector open

Trying to create multiple shakes using shake.js

What I'm trying to accomplish here is to get an alert to show up every time the phone is shaken. But I keep getting an error saying:
Uncaught TypeError: Cannot call method 'addEventListener' of undefined
Is it because it doesn't know what 'shake' is? The reason for more than one shake is because I'll be adding different animations depending on what shake its on.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>Shake animation</title>
<style type="text/css">
body {
background: #E9E9E9;
color: #333;
font: 1em/1.3em "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; /* 16px / 21px */
text-shadow: rgba(255,255,255,0.8) 0 1px 0;
text-align: center;
}
</style>
<script type="text/javascript" src="shake.js"></script>
</head>
<body>
<div class="answerListener" id="answer1"></div>
<div class="answerListener" id="answer2"></div>
<div class="answerListener" id="answer3"></div>
<div class="answerListener" id="answer4"></div>
<script type="text/javascript">
window.onload = function() {
var answer = document.getElementsByClassName('answerListener');
var current = 1;
for (i = 0; answer.length; i++) {
answer[i].addEventListener('shake', function() {
if (current == 1) {
alert('shake1');
}
if (current == 2) {
alert('shake2');
}
if (current == 3) {
alert('shake3');
}
if (current == 4) {
alert('shake4');
}
current = current + 1;
}, false);
}
};
</script>
</body>
Your code looks good except for one small problem: your for loop does not terminate:
for (i = 0; answer.length; i++) {
should be
for (i = 0; i < answer.length; i++) {
You are getting the error because once i exceeds answer.length, answer[i] is undefined and therefore answer[i].addEventListener is attempting to call the method of a non-existing element.
Good luck.

Categories