First post on here, so bear with me! I'm supposed to insert 100 h3 headings on page load ("Accusation 1, Accusation 2, Accusation 3,...Accusation 100"). We're only using 1 loop for the entire lab, and that will be used with other code in the lab, so I'm trying to do this without using a loop, if possible.
**Also, the lab is supposed to teach about scope and hoisting, so we can't use "let" or "const", only "var".
var accusation = 1;
var createHeading = function () {
var heading = $('<h3></h3>').text("Accusation " + accusation);
$('body').append(heading);
accusation++;
}
$(document).ready(function () {
createHeading();
accusation++;
console.log(accusation);
if (accusation > 100) {
return;
console.log('reached 100');
}
})
I'm wanting this function to repeat and increment without using a loop, but it's only producing the first h3 heading.
Recursion! Have the function call itself.
var accusation = 1;
var createHeading = function() {
var heading = $('<h3></h3>').text("Accusation " + accusation);
$('body').append(heading);
accusation++;
if (accusation >= 100) {
console.log("Reached 100;");
return;
} else {
createHeading();
}
}
$(document).ready(function() {
createHeading();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You could use Array.from() and it's internal mapper callback to build an elements array and simply append that array
var headings = Array.from({length:100}, (_,i) => $('<h3>', {text: `Accusation ${i+1}`}))
$('body').append(headings)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
Been coding this javascript code for some while was in motivation of replacing adsense code manually, when users click on the ad 3 times the adsense ad replaces its data-ad-slot="4092520690" value with data-ad-slot="9092520690". So far i've coded some steps on how that could be possible with JavaScript code but it doesn't seem to work simply for no reason. This is the element, I am trying to trigger the javascript code on <ins data-ad-slot="4092520690">ins</ins>
Here is what, I coded so far for it, I would greatly appreciate if someone could enlighten the problems for me:
function replaceAfter3Clicks(elem, newElem) {
let count = 0;
let callback = function() {
count++;
if (count === 3) {
elem.parentNode.replaceChild(newElem, elem);
}
Array.from(ins1).forEach(element => {
element.addEventListener('click', callback);
});
}
const ins1 = $("ins[data-ad-slot]");
// pre-made second div for future replacement
const ins2 = document.createElement('ins');
ins2.param = '9020596432';
ins2.innerText = 'ins2';
replaceAfter3Clicks(ins1, ins2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ins data-ad-slot="4092520690">ins</ins>
You're missing the close brace for let callback = function() {.... Also, elem is a jQuery object, not a DOM element, so you can't use parentNode. jQuery has a replaceWith() method that can be used to replace an element directly.
function replaceAfter3Clicks(elem, newElem) {
let count = parseInt(sessionStorage.getItem("ins_count") || "0");
let callback = function() {
count++;
sessionStorage.setItem("ins_count", count);
if (count >= 3) {
elem.replaceWith(newElem);
}
}
ins1.click(callback);
}
const ins1 = $("ins[data-ad-slot]");
// pre-made second div for future replacement
const ins2 = document.createElement('ins');
ins2.param = '9020596432';
ins2.innerText = 'ins2';
replaceAfter3Clicks(ins1, ins2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><ins data-ad-slot="4092520690">ins</ins></div>
I'm using a function on my website to randomly addClass to a div.
works fine, but I can't find a way to not repeat the same class twice one after the other (cause sometimes the same class is added and we can think the code is not working)...
here is my jquery code :
$("#switch").click(function(){
var classes = ["vert", "escalier","reverse","demi_escalier","demi_escalier_2","ligne" ];
$("#logo").removeClass().addClass(classes[~~(Math.random()*classes.length)]);
});
can anybody help me with this ?
thanks
if you want classes not repeat you can use following:
var classes = ["vert", "escalier", "reverse", "demi_escalier", "demi_escalier_2", "ligne"];
var classesCopy = classes.slice();
$('#switch').click(function() {
if (!classesCopy.length) {
classesCopy = classes.slice();
} // once alls classes used up it starts from beginning
var classToAdd = classesCopy.splice(Math.floor(Math.random() * classesCopy.length), 1);
$('.current-class').text('current class: ' + classToAdd);
$('#logo').removeClass().addClass(classToAdd+'');
});
#logo {
width: 100px;
height: 100px;
background: green;
}
<div class='current-class'></div>
<div id='logo'></div>
<button id='switch'>switch</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
//put it in an IIFE so the variables are scoped down
(function(){
//constants, don't need to declare them in the click function over and over
var classes = ["vert", "escalier","reverse","demi_escalier"
,"demi_escalier_2","ligne" ];
//keep track of the last class used, -1 initial so no chance of mismatch
var lastNumber = -1;
var $logo = $("#logo");
$("#switch").on('click', function() {
//get a new index
var nextClass = Date.now() * 100 % classes.length;;
//while they match, keep getting a new one
while (nextClass === lastNumber) {
nextClass = Date.now() * 100 % classes.length;
}
$logo.removeClass().addClass(classes[nextClass]);
//save it off so we can do the double check again on the next execution
lastNumber = nextClass;
});
})();
Im still new at javascript ive been learning the concepts for several months and this is my first time taking a crack at it.
Im trying to create a carousel using css3 and Javascript (no Jquery)
the console keeps throwing an error.
Uncaught TypeError: Cannot read property display of undefined
The following is my html and javascript code
var slideShow = document.querySelectorAll('.inside');
for (var i = 0; i < slideShow.length; i++) {
setTimeout(function() {
slideShow[i].display.style = 'inline-block';
}, 2000)
}
<div class="inside">
<div class="inner1">
<h1>This is Inner div 1</h1>
</div>
<div class="inner2">
<h1>This is Inner div2</h1>
</div>
<div class="inner3">
<h1>This is Inner div3</h1>
</div>
<div class="inner4">
<h1>This is Inner div4</h1>
</div>
</div>
Aside from display and style being in the wrong order, the problem is that by the time the setTimeout callback function is executed, the for loop has already ended, and i is equal to the length of the nodeList (and since the last element's index is one less than the length of the nodeList, an error is thrown).
You could capture the value of i in an IIFE:
Example Here
var slideShow = document.querySelectorAll('.inside');
for (var i = 0; i < slideShow.length; i++) {
(function (i) {
setTimeout(function () {
slideShow[i].style.display = 'inline-block';
}, 2000 * (i + 1));
})(i);
}
or you could use the .forEach() method:
Example Here
var slideShow = document.querySelectorAll('.inside');
Array.prototype.forEach.call(slideShow, function (el, i) {
setTimeout(function () {
el.style.display = 'inline-block';
}, 2000 * (i + 1));
});
Alternatively, you could just use setInterval:
Example Here
var slideShow = document.querySelectorAll('.inside');
var i = 0;
var interval = setInterval(function () {
if (i < slideShow.length) {
slideShow[i].style.display = 'inline-block';
i++;
} else {
clearInterval(interval);
}
}, 2000);
You have display and style in the wrong order.
It should be slideShow[i].style.display='inline-block';
Additionally, slideShow is only an array-like object of length 1: it contains the div .inner but not its children. If you want to iterate through the child elements, use
var slideShow = document.querySelector('.inside').children;
Edit: As Josh pointed out in a separate answer, you have another problem as well in using setTimeout within a for loop. By the time the function inside the timeout executes, i will be 4, which will give you an undefined value.
If you insist on using a for loop, you can also do this using the forEach method. However, slideShow is not technically an array, but rather an "array-like object", so it does not have its own forEach method. Instead, you must invoke the Array.prototype method as such:
[].forEach.call(slideShow, function(item) {
setTimeout(function() {
item.style.display = 'inline-block';
}, 2000);
});
problem is you are only selecting div.inside and it is not returning div.inner
Try this if you want to select all .inner
change class="inside" to id="inside" and copy this js
var slideShow=document.getElementById("inside").querySelectorAll('div');
slideShow[1].style.backgroundColor = "red";
for (var i=0; i<slideShow.length; i++){
setTimeout(myFun(i), 2000)
}
function myFun(i ){slideShow[i].style.display = "inline-block";}
This is very similar to a previous question of mine but not the same, I am trying to learn the subtleties of Javascript.
Below is my code, I need to change the text in the body when the image changes, I think I am getting there and working it out but as you can see below, it is not yet exacly how i want it.
I would be very very grateful if you can help me.
<script>
$(document).ready(function() {
element = $("#testElement");
i = 1;
setInterval(function() {
element.removeClass("color"+i);
console.log(i);
i++
if (i == 5) {
i = 1;
}
element.addClass("color"+i);
}, 1000);
})
var arr = ['hi','hello ','how ','are ','you '];
changeColorAndText($('#testElement '), 0);
</script>
Thank you wonderful people in advance, you have taught me lots so far.
Working jsfiddle example
<div id="testElement">This is your element</div>
<script>
$(document).ready(function() {
element = $("#testElement");
var arr = ['hi','hello ','how ','are ','you '];
var i = 1; // localizing scope of this variable (not necessary)
setInterval(function(){
element.removeClass("color"+i);
console.log(i);
i++; // missing semicolon here
if(i == 5) i = 1;
element.addClass("color"+i);
element.text(arr[i]); // change the inner text of element
}, 1000);
});
</script>
I'm having some problems, I'd like to have a sort of slideshow where users have 4 buttons, and when they click one div appears and the others disappear. The div's are all in the same place with the same size. I'd also like to put this automatic
var Idx = 1;
var IntervalKey = setInterval = (auto, 5000);
var auto = function() {
$("#MainImage").eq(Idx).fadeIn(1000);
while(Idx <3) {
Idx++;
$("#MainImage").eq(Idx).hide();
}
Idx++;
if(Idx>3) {
Idx = 0;
}
};
$(".botao-imagem").click(function(){
Idx = $(".botao-imagem").index(this);
auto();
});
Your main issue is repeated IDs, IDs must be unique, so $("#ID").eq() doesn't every have a purpose really, since it should be 1 or 0 results. First give the elements a class instead:
<div class="MainImage"><p>111111</p></div>
<div class="MainImage"><p>222222</p></div>
<div class="MainImage"><p>333333</p></div>
<div class="MainImage"><p>444444</p></div>
and use a class selector, like this:
$(".MainImage")
Also auto needs to be declared before using it or define it as a function directly, overall like this:
var Idx = 0;
var IntervalKey = setInterval(auto, 5000);
function auto() {
$(".MainImage").hide().eq(Idx).fadeIn(1000);
Idx++;
if(Idx>3) Idx = 0;
};
$(".botao-imagem").click(function(){
Idx = $(".botao-imagem").index(this);
auto();
});
You can test the updated/working version with the above code here.