Problem With Coded JavaScript Won't Replace Element After 3 Clicks - javascript

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>

Related

deleting character from a string one by one

i've been trying to create an effect like a string is being typed in my webpage. In other words that string will appear character by character. so I did this using jquery and succeded .
the code I used is something like this,
$(function() {
var string = "Coming Soon|",
stringCount = 0;
setInterval(function(){
$('.main_section_animate span').append(string[stringCount]);
stringCount += 1;
},100);
})
Note that the span tag is empty, nothing is in there.
Problem is now I'm trying to delete the string character by character, backwards. I've tried using setInterval and replace(string[stringCount],''), selecting the main section span and main section span.text() but it didn't work and gave some weird results.
And also there are other thing I tried but mainly some combinition of text() with replace
so, anyone can help me out with this?
can be:
let str = 'Coming Soon |';
const $span = $('.main_section_animate span');
$span.html(str);
const animation = setInterval(() => {
str = str.slice(0, -1)
$span.html(str)
!str.length && clearInterval(animation)
}, 100)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main_section_animate">
<span></span>
</div>
You should probably clear that interval to get the intended result, see: https://jsfiddle.net/2mj5zp7h/
HTML:
<div class="main_section_animate">
<span></span>
</div>
JS:
$(function() {
var string = "Coming Soon|",
stringCount = 0;
var animation = setInterval(function(){
$('.main_section_animate span').append(string[stringCount]);
stringCount += 1;
if(stringCount>=string.length) {
clearInterval(animation);
animation = setInterval(function(){
$('.main_section_animate span').text(string.substr(0,stringCount));
stringCount -=1;
if(stringCount<0)
clearInterval(animation);
},100);
}
},100);
})
EDITED: Change code.
This is a solution for you :)
Use split();
const str = "Coming Soon ...";
let timer;
function deletingEffect() {
let word = str.split("");
var loopDeleting = function() {
word.pop();
document.getElementById('word').innerHTML = word.join("");
timer = setTimeout(loopDeleting, 200);
};
loopDeleting();
};
deletingEffect();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main_section_animate">
<span id="word"></span>
</div>
Use .slice() and a simple for loop to get what you need.
let str = 'Coming Soon|';
for (let i = -1+str.length; i > 0; i--) {
let delay = 100*(str.length-(i+1))
setTimeout(()=>{
$('.main_section_animate span').html( str.slice(0, i) );
}, delay);
}
Notice the for loop starts at .length and walks downwards (i--) while i > 0. This gives you an easy way to use str.slice().
Also notice the removal of setInterval which is a waste of CPU in your case. Instead, just set a one-shot setTimeout for each removal.
Finally, use .html instead of .append.

How to insert 100 headings at page load without a loop?

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>

Multiple Class Names - getelementsbyclassname

Basically I want a logo to change, there are 2 current logos, individually labelled with the classes... 'Header-branding-logo' & 'Mobile-bar-branding-logo'. I can change either one of them, but not at both at the same time.
I can't seem to figure out where I need to put it. Can anyone help?
<script>
window.onload = function() {
document.getElementsByClassName('Header-branding-logo')[0].src = 'https://static1.squarespace.com/static/5a9e8da0aa49a18379207907/t/5ac52f062b6a28a603df30cf/1522872070340/GBL+Shop+-+Black+1500.png';
};
</script>
UPDATE
Thanks to the genius below, this now works for me
<script>
window.onload = function() {
var elements = document.querySelectorAll('.Header-branding-logo,.Mobile-bar-branding-logo');
elements.forEach((element) => {
element.src = "https://static1.squarespace.com/static/5a9e8da0aa49a18379207907/t/5ac52f062b6a28a603df30cf/1522872070340/GBL+Shop+-+Black+1500.png"
})
};
</script>
Please use the querySelectorAll function
var elements = document.querySelectorAll('.Header-branding-logo,.Mobile-bar-branding-logo');
elements.forEach((element) => {
element.src = "https://static1.squarespace.com/static/5a9e8da0aa49a18379207907/t/5ac52f062b6a28a603df30cf/1522872070340/GBL+Shop+-+Black+1500.png"
})
<script>
window.onload = function() {
var classes = document.querySelectorAll(".Header-branding-logo, .Mobile-bar-branding-logo") // Gets multiple classes whereas getElementsByClassName() fetches only one. Also dont miss the '.' before classnames here
for(i = 0; i <= classes.length; i++){
classes[i].src = "https://static1.squarespace.com/static/5a9e8da0aa49a18379207907/t/5ac52f062b6a28a603df30cf/1522872070340/GBL+Shop+-+Black+1500.png"
}
}

Javascript, Click eventlistener doing the same thing with multiple classes

I'm very new to learning JavaScript, and I've tried to read, and look for similar answers, but everything is pointing at jQuery, which I want to avoid using for this problem. I can't quite work out what is jQuery and what still works in JS...
I have set up a function that can grab the innerHTML but I can't seem to assign it to the same classes, else it'll only work on the first instance, and I tried creating multiple classes but essentially they're all the same button with different values...
document.querySelector(".b1").addEventListener("click", writeDisp);
document.querySelector(".b2").addEventListener("click", writeDisp);
document.querySelector(".b3").addEventListener("click", writeDisp);
document.querySelector(".b4").addEventListener("click", writeDisp);
function writeDisp() {
if(dispNum.length < 9){
if(dispNum === "0") {
dispNum = this.innerHTML
} else {
dispNum = dispNum + this.innerHTML};
document.querySelector(".display").textContent = dispNum;
}
}
}
How can I make this more simple. As there are way more .b* classes to add, and I'd rather not have a massive list if possible.
Thanks,
var class_elem = document.querySelectorAll("button[class^='b']");
function writeDisp(){
if(dispNum.length < 9){
if(dispNum === "0"){dispNum = this.innerHTML}else{dispNum = dispNum + this.innerHTML};
document.querySelector(".display").textContent = dispNum;
}
}
for (var i = 0; i < class_elem.length; i++) {
class_elem[i].addEventListener('click', writeDisp, false);
}
//Here your code in javascript only.
If you don't want to use jquery, you can use native document.querySelectorAll API like this
function writeDisp(){
if(dispNum.length < 9){
if(dispNum === "0"){
dispNum = this.innerHTML
} else {
dispNum = dispNum + this.innerHTML
}
document.querySelector(".display").textContent = dispNum;
}
}
// this line will select all html tags that contains a class
// name starting with 'b'
var doms = document.querySelectorAll("[class^=b]");
doms.forEach(function(dom) {
dom.addEventListener('click', writeDisp);
})
Note
querySelectorAll will fetch only those DOM instance in which b* is defined as first class, so in case of multiple class defintion, it will not fetch those DOMs which don't have the desired classname at first. That means if you have a DOM defintion like <div class="a box"></div>, this will be ignored, as here, classname starting with b sits after a class.

Jquery Problem Sort of Auto Slideshow

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.

Categories