create DOM elements by a limited interval with Jquery [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I want to create 1 div container every x second. And I want to do this n times.
So I started creating this
$(document).ready(function() {
for (var i = 0; i < 5; i++) {
createEle(i);
}
});
function createEle(value) {
var d = $("<div></div>");
d.addClass("d");
d.html(value);
$("#container").append(d);
}
.d {
height: 20px;
color: white;
background: red;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
this works fine. But I want to integrate the time interval.
$(document).ready(function() {
for (var i = 0; i < 5; i++) {
setTimeout(function() {
createEle(i);
}, i * 1000);
}
});
function createEle(value) {
var d = $("<div></div>");
d.addClass("d");
d.html(value);
$("#container").append(d);
}
.d {
height: 20px;
color: white;
background: red;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
As you can see in the second example, I always get the wrong value because it passes in the wrong index value.
How can I fix that?

Replace var with let.
for (let i = 0; i < 5; i++) {
Demo
$(document).ready(function() {
for (let i = 0; i < 5; i++) {
setTimeout(function() {
createEle(i);
}, i * 1000);
}
});
function createEle(value) {
var d = $("<div></div>");
d.addClass("d");
d.html(value);
$("#container").append(d);
}
.d {
height: 20px;
color: white;
background: red;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
Reason
var doesn't let go of the bindings of the parent lexical-environment hence its hoisted value is retained in the asynchronous callback handler (of setTimeout), however let doesn't hold on to the bindings of any lexical-environment other than its own current one.

please update your code. no need of for loop.
var i=1;
$(document).ready(function() {
setInterval(function() {
createEle(i);
}, i * 1000);
});
function createEle(value) {
var d = $("<div></div>");
d.addClass("d");
d.html(value);
$("#container").append(d);
i++;
}

Loop will completely executed before the first setTimeout runs. So the value of the i will be 5
Treat setTimeout and setInterval as a asynchronous function.
$(document).ready(function() {
var i = 0;
var tmer = setInterval(function() {
createEle(i);
i = i + 1;
if(i==5)
clearInterval(tmer);
}, 1000);
});
function createEle(value) {
var d = $("<div></div>");
d.addClass("d");
d.html(value);
$("#container").append(d);
}
.d {
height: 20px;
color: white;
background: red;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>

Related

Show images in quiz javascript

I'm trying to create a quiz that tests users awareness of real and fake emails. What I want to do is have the question displayed at the top saying "Real or Fake", then have an image displayed underneath which the user needs to look at to decided if it's real or fake. There are two buttons, real and fake, and regardless of whether they choose the right answer I want to swap the original image with annotated version - showing how users could spot that it was fake or real.
But I'm not sure how to show the annotated version once the answer has been submitted. Could someone help?
function Quiz(questions) {
this.score = 0;
this.questions = questions;
this.questionIndex = 0;
}
Quiz.prototype.getQuestionIndex = function() {
return this.questions[this.questionIndex];
}
Quiz.prototype.guess = function(answer) {
if (this.getQuestionIndex().isCorrectAnswer(answer)) {
this.score++;
}
this.questionIndex++;
}
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
}
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
Question.prototype.isCorrectAnswer = function(choice) {
return this.answer === choice;
}
function populate() {
if (quiz.isEnded()) {
showScores();
} else {
// show question
var element = document.getElementById("question");
element.innerHTML = quiz.getQuestionIndex().text;
// show options
var choices = quiz.getQuestionIndex().choices;
for (var i = 0; i < choices.length; i++) {
var element = document.getElementById("choice" + i);
element.innerHTML = choices[i];
guess("btn" + i, choices[i]);
}
showProgress();
}
};
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populate();
}
};
function showProgress() {
var currentQuestionNumber = quiz.questionIndex + 1;
var element = document.getElementById("progress");
element.innerHTML = "Question " + currentQuestionNumber + " of " + quiz.questions.length;
};
function showScores() {
var gameOverHTML = "<h1>Result</h1>";
gameOverHTML += "<h2 id='score'> Your scores: " + quiz.score + "</h2>";
var element = document.getElementById("quiz");
element.innerHTML = gameOverHTML;
};
// create questions here
var questions = [
new Question("<img src= 'netflix_fake.jpg' />", ["Real", "Fake"], "Fake"),
new Question("<img src= 'dropbox_real.jpg' />", ["Real", "Fake"], "Real"),
new Question("<img src= 'gov_real.jpg' />", ["Real", "Fake"], "Real"),
new Question("<img src= 'paypal_fake.jpg' />", ["Real", "Fake"], "Fake"),
new Question("<img src= 'gmail.jpg' />", ["Real", "Fake"], "Fake")
];
//create quiz
var quiz = new Quiz(questions);
// display
populate();
body {
background-color: #538a70;
}
.grid {
width: 600px;
height: 500px;
margin: 0 auto;
background-color: #fff;
padding: 10px 50px 50px 50px;
border: 2px solid #cbcbcb;
}
.grid h1 {
font-family: "sans-serif";
font-size: 60px;
text-align: center;
color: #000000;
padding: 2px 0px;
}
#score {
color: #000000;
text-align: center;
font-size: 30px;
}
.grid #question {
font-family: "monospace";
font-size: 30px;
color: #000000;
}
.buttons {
margin-top: 30px;
}
#btn0,
#btn1,
#btn2,
#btn3 {
background-color: #a0a0a0;
width: 250px;
font-size: 20px;
color: #fff;
border: 1px solid #1D3C6A;
margin: 10px 40px 10px 0px;
padding: 10px 10px;
}
#btn0:hover,
#btn1:hover,
#btn2:hover,
#btn3:hover {
cursor: pointer;
background-color: #00994d;
}
#btn0:focus,
#btn1:focus,
#btn2:focus,
#btn3:focus {
outline: 0;
}
#progress {
color: #2b2b2b;
font-size: 18px;
}
<div class="grid">
<div id="quiz">
<h1>Can you spot the fake email?</h1>
<hr style="margin-bottom: 20px">
<p id="question"></p>
<div class="buttons">
<button id="btn0"><span id="choice0"></span></button>
<button id="btn1"><span id="choice1"></span></button>
</div>
<hr style="margin-top: 50px">
<footer>
<p id="progress">Question x of y</p>
</footer>
</div>
</div>
When user clicks button I trigger class and I add it second name, on second I have written to get swapped, I wrote you basically full project, and please read the whole comments, to understand logic
//Calling Elements from DOM
const button = document.querySelectorAll(".check");
const images = document.querySelectorAll(".image");
const answer = document.querySelector("h1");
//Declaring variable to randomly insert any object there to insert source in DOM Image sources
let PreparedPhotos;
//Our Images Sources and With them are its fake or not
//fake: true - yes its fake
//fake: false - no its real
const image = [
[
{
src:
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/1200px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg",
fake: true
},
{
src:
"http://graphics8.nytimes.com/images/2012/04/13/world/europe/mona-lisa-like-new-images/mona-lisa-like-new-images-custom4-v3.jpg",
fake: false
}
],
[
{
src:
"https://cdn.shopify.com/s/files/1/0849/4704/files/Creacion_de_Adan__Miguel_Angel_f5adb235-bfa8-4caa-8ffb-c5328cbad953_grande.jpg?12799626327330268216",
fake: false
},
{
src:
"https://cdn.shopify.com/s/files/1/0849/4704/files/First-image_Fb-size_grande.jpg?10773543754915177139",
fake: true
}
]
];
//Genrating Random Photo on HTML
function setRandomPhoto() {
//Random Number which will be length of our array of Object
//if you array includes 20 object it will generate random number
// 0 - 19
const randomNumber = Math.floor(Math.random() * image.length);
//Decalaring our already set variable as Array Object
PreparedPhoto = image[randomNumber];
//Our first DOM Image is Variables first object source
images[0].src = PreparedPhoto[0].src;
//and next image is next object source
images[1].src = PreparedPhoto[1].src;
}
//when windows successfully loads, up function runs
window.addEventListener("load", () => {
setRandomPhoto();
});
//buttons click
//forEach is High Order method, basically this is for Loop but when you want to
//trigger click use forEach - (e) is single button whic will be clicked
button.forEach((e) => {
e.addEventListener("click", () => {
//decalring variable before using it
let filtered;
//finding from our DOM image source if in our long array exists
//same string or not as Image.src
//if it exists filtered variable get declared with that found obect
for (let i = 0; i < image.length; i++) {
for (let k = 0; k < 2; k++) {
if (image[i][k].src === images[0].src) {
filtered = image[i][k];
}
}
}
//basic if else statement, if clicked button is Fake and image is true
//it outputs You are correct
//if clicked button is Real and Image is false it outputs Correct
//Else its false
//Our image checking comes from filtered variable
if (e.innerText === "Fake" && filtered.fake === true) {
answer.innerText = "You Are Correct";
images.forEach((image) => {
image.classList.toggle("hidden");
});
} else if (e.innerText === "Real" && filtered.fake === false) {
answer.innerText = "You Are Correct";
images.forEach((image) => {
image.classList.toggle("hidden");
});
} else {
answer.innerHTML = "You are Wrong";
images.forEach((image) => {
image.classList.toggle("hidden");
});
}
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100%;
min-height: 100vh;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column;
}
.image-fluid {
display: flex;
}
.image-fluid .image {
width: 200px;
margin: 0 10px;
transition: 0.5s;
}
.image-fluid .image:nth-child(1).hidden {
transform: translateX(110px);
}
.image-fluid .image:nth-child(2).hidden {
transform: translateX(-110px);
}
<div class="container">
<div class="image-fluid">
<img src="" class="image hidden">
<img src="" class="image hidden">
</div>
<div class="button-fluid">
<button class="check">Fake</button>
<button class="check">Real</button>
</div>
</div>
<h1></h1>

Jquery number counter for updates

I have this jquery functions. I want to make it just one function so I can get thesame results by just calling a function and passing some arguements.
As you can see, the function does basically the same thing counting numbers. I would love to just have one function , then parse out arguments to get the same results. something like startcount(arg1, arg2);
var one_countsArray = [2,4,6,7,4252];
var two_countsArray = [3,3,4,7,1229];
var sumemp = one_countsArray.reduce(add, 0);
var sumallis = two_countsArray.reduce(add, 0);
function add(a, b) {
return a + b;
}
var count = 0;
var inTv = setInterval(function(){startCount()},100);
var inTv2 = setInterval(function(){startCount2()},100);
function startCount()
{
if(count == sumemp) {
clearInterval(inTv);
} else {
count++;
}
$('.stats_em').text(count);
}
var count2 = 10;
function startCount2()
{
if(count2 == sumallis) {
clearInterval(inTv2);
} else {
count2++;
}
$('.stats_iss').text(count2);
}
div {
padding:50px 0;
background: #000000;
color: #ffffff;
width: 100px;
height:100px;
border-radius:50%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="stats_em"></div>
<div class="stats_iss"></div>
How about a very simple jquery plugin
$.fn.countTo = function(arrNums){
var self = this;
function add(a,b){
return a+b;
}
var current = 0;
var max = arrNums.reduce(add,0);
var int = setInterval(function(){
if(current == max)
clearInterval(int);
else
current++;
self.text(current);
},100);
return this;
}
$('.stats_em').countTo([2,4,6,7,4252]);
$('.stats_iss').countTo([3,3,4,7,1229]);
div {
padding:50px 0;
background: #000000;
color: #ffffff;
width: 100px;
height:100px;
border-radius:50%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="stats_em"></div>
<div class="stats_iss"></div>
When you notice you're rewriting chunks of similar code, moving to one generic function is the right approach! The best way to start is by trying to determine what you're parameters would be:
count and count2 show that you need a start count for your timer to start at
sumemp and sumpallis show that you need to be able to specify a maximum count
inTv and inTv show that you need to be able to set the interval
$('.stats_iss') and $('.stats_em') show that you need to be able to determine the output element
This means your final class, function or jquery extension will at least have a signature that resembles this:
function(startCount, maximumCount, interval, outputElement) { }
Once you've written this, you can paste in the code you already have. (I've replaced your setInterval with a setTimeout, other than that, not much changed)
var createCounter = function(start, max, interval, outputElement) {
var count = start;
var timeout;
var start = function() {
count += 1;
outputElement.text(count);
if (count < max) {
timeout = setTimeout(start, interval);
}
}
var stop = clearTimeout(timeout);
return {
start: start,
stop: stop
}
}
var one_countsArray = [2, 4, 6, 7, 300];
var two_countsArray = [3, 3, 4, 7, 100];
var sumemp = one_countsArray.reduce(add, 0);
var sumallis = two_countsArray.reduce(add, 0);
function add(a, b) {
return a + b;
}
var counters = [
createCounter(0, sumemp, 100, $('.stats_em')),
createCounter(10, sumallis, 100, $('.stats_iss'))
];
counters.forEach(function(counter) {
counter.start();
});
div {
padding: 50px 0;
background: #000000;
color: #ffffff;
width: 100px;
height: 100px;
border-radius: 50%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="stats_em"></div>
<div class="stats_iss"></div>

Perform click on one div after the other

I hope you understand my problem.
At the moment I have a JS-function that choses randomly a div of a specific Html-Class.
Now i would like to rewrite the function that it picks one div after the other, just like they are ordered in the HTML-content.
How can I do this?
For information: the random selection is made with jquery and looks like this:
function pickrandom() {
var elems = $(".classname");
if (elems.length) {
var keep = Math.floor(Math.random() * elems.length);
console.log(keep);
$(elems[keep]).click();
}
}
Thanks
$(document).on('click', '.classname', function(){
var self = $(this);
var total_items = $('.classname').length; // 10
var index = self.index(); //2 for 3rd element
if (index < total_items) {
setTimeout(function () {
$('.classname').eq(index+1).trigger('click');
}, 3000);
}
});
this will call the next clicks in 3 sec interval
i don't know why you are using a randomizer function.you can allow the user to make that click
Hopefully this helps you - can't see your markup, but it should get you on the right track. I've also changed your .click() to a .trigger('click') which should be quite a bit more dependable.
JavaScript
function pickrandom() {
var elems = $(".classname");
if (elems.length) {
var curTarget = Math.floor(Math.random() * elems.length);
console.log(curTarget);
$(elems[curTarget]).trigger('click');
// Find index of our next target - if we've reached
// the end, go back to beginning
var nextTarget = curTarget + 1;
if( nextTarget > elems.length ) {
nextTarget = 0;
}
// Wait 3 seconds and click the next div
setTimeout( function() { $(elems[nextTarget]).trigger('click'); }, 3000 );
}
}
$("div").click(function() {
var el = $(this);
setTimeout(function() {
console.log(el.text());
el.toggleClass("click");
}, 2000);
});
var random = Math.floor((Math.random() * $("div").length) + 1);
var index = random - 1;
console.log("Random number: ", random);
var clicker = setInterval(function() {
if (index === $("div").length) {
clearInterval(clicker);
console.log("cleared interval");
} else {
$("div").eq(index).click();
index++;
}
}, 2000)
div {
height: 50px;
width: 100%;
border: 2px solid black;
background-color: lightgreen;
margin-bottom: 10px;
text-align: center;
font-size: 30px;
}
.click {
background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
Div 1
</div>
<div>
Div 2
</div>
<div>
Div 3
</div>
<div>
Div 4
</div>
<div>
Div 5
</div>
<div>
Div 6
</div>

Make appear text in Javascript

I'm trying to make appear text in Javascript.
That's my code :
HTML :
<div id="t1">Ecologie</div>
<div id="t2">Planète</div>
<div id="t3">BIO</div>
<div id="t4">Responsable</div>
<div id="t5">Changement</div>
<div id="t6">Durable</div>
<script type="text/javascript">var mytimeout = setTimeout(DisplayElem(), 2000)
</script>
CSS :
#t1
{
position: absolute;
color: green;
font-size: 50px;
top: 50%;
left: 13%;
display: none;
}
#t2
{
position: absolute;
color: green;
font-size: 60px;
top: 40%;
left: 70%;
display: none;
}
and Javascript :
function Display (elem) {
elem.style.display = block;
}
var compteur = 0;
function DisplayElem()
{
compteur += 1;
var id = 't' + compteur;
elem = document.getElementById(id);
Display(elem);
mytimeout = setTimeout(DisplayElem(), 2000)
if(compteur == 6)
{
window.clearTimeout(mytimeout);
}
}
I got this error : Uncaught ReferenceError: block is not defined
on my line :elem.style.display = block;
When i open my page i want all of my div invisible. But after a few second i would like to have on who appear, and the next one, and the next one...
Thank you
Here is your complete working code:
var compteur = 1;
function Display (elem) {
elem.style.display = 'block';
}
function DisplayElem()
{
var id = 't' + compteur;
elem = document.getElementById(id);
Display(elem);
compteur += 1;
if (compteur <= 6)
setTimeout(DisplayElem, 2000);
}
DisplayElem();
See the DEMO here
You have forgotten the delimiters around the string block:
function Display (elem) {
elem.style.display = 'block';
}
Side note: Instead of setting the timeout the last time and then removing it, just skip setting it:
if (compteur < 6) {
mytimeout = setTimeout(DisplayElem(), 2000)
}

Trying to make these divs not reset position when I add new one with jquery

I have tried changing the keyup part of the code to a button and I have also tried some code to get the draggable element to store its position in the cookie but to no avail. When I change the empty tag to ready it repeats the previous lines every time. Any help would be much appreciated.
jsFiddle for original code
jsFiddle for my attempt at a button
HTML
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<textarea></textarea>
<div id="opt"></div>
CSS
d {
position: relative;
left: 0;
top: 0;
width: 60px;
height: 60px;
background: #ccc;
float: left;
font-family: arial;
font-size: 10px;
}
JavaScript
$(document).ready(function() {
$("textarea").keyup(splitLine);
function splitLine() {
$("#opt").empty();
var lines = $("textarea").val().split(/\n/g);
for (var i = 0; i < lines.length; i++) {
var ele = $("<d>");
ele.html(lines[i]);
$("#opt").append($(ele).draggable());
}
}
});
I think you shouldn't remove all your <d> and start over every time. I have made some changes in the code to reuse the old <d> so that it's position is preserved
$(document).ready(function () {
$("textarea").keyup(splitLine);
function splitLine() {
//$("#opt").empty();
var lines = $("textarea").val().split(/\n/g);
for (var i = 0; i < lines.length; i++) {
var ele;
if ($("d:eq(" + i + ")").get(0)) {
ele = $("d:eq(" + i + ")");
ele.html(lines[i]);
} else {
ele = $("<d>");
ele.html(lines[i]);
$("#opt").append($(ele).draggable());
}
}
}
});

Categories