Javascript - how to update elements inner html? - javascript

I have something like this:
var stopwatch = function (item) {
window.setInterval(function () {
item.innerHtml = myInteger++;
}, 1000);
}
This code was supposed to display myInteger, but it is not updating values of item. Why (item is a div with text inside)?

There could be a lot of reasons (we need to see more of your code), but here is a working example:
var myInteger = 1,
stopwatch = function (item) {
window.setInterval(function () {
item.innerHTML = myInteger++;
}, 1000);
}
stopwatch(document.querySelector('div'));
Important changes:
Calling stopwatch (you probably do this)
- innerHtml +innerHTML (the case matters). You won't get an error for setting innerHtml; it will set that property and you won't notice anything.
Initialize myInteger.
http://jsfiddle.net/Q4krM/

Try this code :
var stopwatch = setInterval(function (item) {
item.innerHtml = myInteger++;
}, 1000);
This should work

Related

How can i toggle innerHTML inside a setInterval() function with JS

I am trying to alternate the innerHTML of a at set Intervals.
Dear friends,
I am new to coding. I have created a div with an image, and a < p > element (that includes a < span >.
I have assigned two classes to the div, and I want it to alternate between the 2 classes at set intervals.
In addittion, I am trying to toggle the text inside the span, by using innerHTML.
So far I have managed succesfully to toggle the class, but I can't make the innerHTML to work.
I have the following code:
if(categProducts[idx].discount && categProducts[idx].low){
var Interval = setInterval(
function changeClass(){
document.getElementById('myDiv').classList.toggle("low");
},3000
)
var Interval2= setInterval(function changeText(){
var x=document.getElementById('mySpan').innerHTML
if (x==="<br> Only Few Cakes Left!!"){
x.innerHTML="<br> Discount! Best Price!!"
}
else {
x="<br> Only Few Cakes Left!!"
}
console.log(x)
}, 3000)
}
So far, the innerHTML of the only toggles once, and then it doesn't change again.
I can't make it work and I don't understand why.
The rest of the code is the following:
for (let idx in categProducts){
if (categProducts[idx].category==="cakes") {
const parentElement=document.getElementById("divCakes")
const myDiv=document.createElement("div")
parentElement.appendChild(myDiv)
myDiv.className="product"
const myImg=document.createElement("img")
myImg.src=categProducts[idx].imageURI
myImg.alt=categProducts[idx].alt
myDiv.appendChild(myImg)
myDiv.id="myDiv"
const myP=document.createElement("p")
myP.innerHTML=categProducts[idx].name
myDiv.appendChild(myP)
mySpan=document.createElement("span")
myP.appendChild(mySpan)
mySpan.id="mySpan"
IMO, you should define your desired classes and content inside arrays. Works for two, and more.
const changeContent = (() => {
const classes = ['first-class', 'second-class'];
const spanText = ['first text', 'second text'];
let index = 0;
return function() {
document.getElementById('mySpan').innerHTML = "";
document.getElementById('myDiv').classList = "";
document.getElementById('mySpan').innerHTML = spanText[index];
document.getElementById('myDiv').classList = classes[index];
index++;
if(index === classes.length) {
index = 0;
}
}
})();
setInterval(changeContent, 3000);
This functions uses closures to define global variables.

Link setIntervals with .each() element

This question is related to this one Clear all setIntervals
I'm using setIntervals within each function like so,
var allIntervals = [];
$(".elements").each(function() {
var myInterval = setInterval(function() {
// code that changes $(this)
});
allIntervals.push(myInterval);
});
I then clear all the intervals like this
jQuery.each(allIntervals, function(index) {
window.clearInterval(allIntervals[index]);
});
I now realized that I want to instead clear intervals of elements that are no longer in the DOM.
So how do I link the setIntervals to each() element, then check if the element is still in the DOM, and if not, clear the Interval associated with that element?
You can store the element with the ID from the timeout in an object, but you have to check again to see if it's in the DOM as the stored element doesn't magically dissapear from the variable, it's just no longer in the DOM.
var allIntervals = [];
$(".elements").each(function(i, el) {
var myInterval = setInterval(function() {
// stuff
}, 1000);
allIntervals.push({id : myInterval, elem : this});
});
$.each(allIntervals, function(index, item) {
if ( $(document).find(item.elem).length === 0 ) window.clearInterval(item.id);
});
FIDDLE
Use an object to store the information (with the element and the intervalid as properties), loop through the object and clear the interval if the DOM element if not available.
$(function() {
var intervals = [];
$(".elements").each(function() {
var myInterval = setInterval(function() {
// code that changes $(this)
});
var obj = new Object();
obj.element = $(this);
obj.intervalId = myInterval;
intervals.push(obj);
});
$.each(intervals, function(index, val) {
console.log(val.element);
if (val.element.length > 0) {
window.clearInterval(val.intervalId);
}
});
});

How to slow down a loop with setTimeout or setInterval

I have an array called RotatorNames. It contains random things but let's just say that it contains ["rotatorA","rotatorB","rotatorC"].
I want to loop through the array, and for each item i want to trigger a click event. I have got some of this working, except that the everything get's triggered instantly. How can i force the loop to wait a few seconds before it continues looping.
Here's what i have.
function Rotator() {
var RotatorNames = ["rotatorA","rotatorB","rotatorC"];
RotatorNames.forEach(function(entry){
window.setTimeout(function() {
//Trigger that elements button.
var elemntBtn = $('#btn_' + entry);
elemntBtn.trigger('click');
}, 5000);
});
}
You can run this to see what my issue is. http://jsfiddle.net/BxDtp/
Also, sometimes the alerts do A,C,B instead of A,B,C.
While I'm sure the other answers work, I would prefer using this setup:
function rotator(arr) {
var iterator = function (index) {
if (index >= arr.length) {
index = 0;
}
console.log(arr[index]);
setTimeout(function () {
iterator(++index);
}, 1500);
};
iterator(0);
};
rotator(["rotatorA", "rotatorB", "rotatorC"]);
DEMO: http://jsfiddle.net/BxDtp/4/
It just seems more logical to me than trying to get the iterations to line up correctly by passing the "correct" value to setTimeout.
This allows for the array to be continually iterated over, in order. If you want it to stop after going through it once, change index = 0; to return;.
You can increase the timeout based on the current index:
RotatorNames.forEach(function(entry, i) {
window.setTimeout(function() {
//Trigger that elements button.
var elemntBtn = $('#btn_' + entry);
elemntBtn.trigger('click');
}, 5000 + (i * 1000)); // wait for 5 seconds + 1 more per element
});
Try:
var idx = 0;
function Rotator() {
var RotatorNames = ["rotatorA", "rotatorB", "rotatorC"];
setTimeout(function () {
console.log(RotatorNames[idx]);
idx = (idx<RotatorNames.length-1) ? idx+1:idx=0;
Rotator();
}, 5000);
}
Rotator();
jsFiddle example
(note that I used console.log instead of alert)
Something like this should do what you're after:
function Rotator(index){
var RotatorNames = ["rotatorA","rotatorB","rotatorC"];
index = (index === undefined ? 0 : index);
var $btn = $("#btn_"+RotatorNames[index]);
$btn.click();
if(RotatorNames[index+1]!==undefined){
window.setTimeout(function(){
Rotator(index+1);
}, 500);
}
}

Change JS function to an object

So I asked a question awhile ago here > Cons of MouseOver for webpages and ran into some issues with enabling/disabling events. According to the answer from the post, I was supposed to update my function as an object to call it out easily. However after a few hours of trial and error as well as online research, I still don't understand how the object works
So this is the function I want to put into an object,
$(function () {
$('#01 img:gt(0)').hide();
setInterval(function () {
$('#01 :first-child').fadeOut(1500)
.next('img').fadeIn(1500)
.end().appendTo('#01');
}, 3000);
});
And this was the code provided to initialize my object,
var Slideshow = (function () {
this.interval;
this.start = function () {
...
initialize
...
// catch the interval ID so you can stop it later on
this.interval = window.setInterval(this.next, 3000);
};
this.next = function () {
/*
* You cannot refer to the keyword this in this function
* since it gets executed outside the object's context.
*/
...
your logic
...
};
this.stop = function () {
window.clearInterval(this.interval);
};
})();
So how exactly should I implement my function into the object so that it works?
I would structure it like this:
function Slideshow(container) {
this.interval = undefined;
this.start = function () {
container.find("img").first().show();
container.find("img:gt(0)").hide();
this.interval = window.setInterval(this.next, 3000);
};
this.next = function () {
var first = container.find(":first-child");
first.fadeOut(1500, function () {
first.next("img").fadeIn(1500);
first.appendTo(container);
});
};
this.stop = function () {
window.clearInterval(this.interval);
};
}
$(function () {
var div = $("#div01");
var slides = new Slideshow(div);
div.hover(function() {
slides.stop();
}, function() {
slides.start();
});
slides.start();
});
DEMO: http://jsfiddle.net/STcvq/5/
latest version courtesy of #Bergi
What you should aim to do, looking at the recommended code, is to move the logic of your setInterval inside the Slideshow.next() function. That basically covers your fadeout, fadein logic.
So your function would look something like:
this.next = function() {
$('#01 :first-child').fadeOut(1500)
.next('img').fadeIn(1500)
.end().appendTo('#01');
};
in the simplest of worlds.
Ideally, you would want to instantiate your Slideshow by telling it which id it should use, by passing that in the constructor. That is, you should be able to call
new Slideshow('#01') as well as new Slideshow('#02') so that you can truly reuse it.
Then, your next function would change to look something like (assuming the id is stored in this.elementId):
this.next = function() {
$(this.elementId + ':first-child').fadeOut(1500)
.next('img').fadeIn(1500)
.end().appendTo('#01');
};
Hope this helps
change syntax to :
var Slideshow = (function () {
return {
interval:null,
start : function () {
// catch the interval ID so you can stop it later on
this.interval = window.setInterval(this.next, 3000);
},
next: function () {
},
stop : function () {
window.clearInterval(this.interval);
}
};
})();
as you are using jquery, a better ans is to create a little plugin:
http://learn.jquery.com/plugins/basic-plugin-creation/

Loop through js array continually with pauses

I want to loop over an array continuously on click. Extra props if you can work in a delay between class switches :-)
I got this far:
// Define word
var text = "textthing";
// Define canvas
var canvas = 'section';
// Split word into parts
text.split();
// Loop over text
$(canvas).click(function() {
$.each(text, function(key, val) {
$(canvas).removeAttr('class').addClass(val);
});
});
Which is not too far at all :-)
Any tips?
The following will wait until you click the selected element(s) in the var el. In this example var el = $('section') will select all <section>...</section> elements in your document.
Then it will start cycling through the values in cssClassNames, using each, in turn as the css class name on the selected element(s). A delay of delayInMillis will be used between each class change.
var cssClassNames = ['c1', 'c2', 'c3'];
var el = $('section');
var delayInMillis = 1000;
// Loop over text
el.click(function() {
var i = 0;
function f() {
if( i >= cssClassNames.length ) {
i = 0;
}
var currentClass = cssClassNames[i];
i += 1;
el.removeClass().addClass(currentClass);
setTimeout(f, delayInMillis);
}
f();
});
I believe you want a delay of X milliseconds between removing a class and adding a class. I'm not sure that you have to have the lines marked // ? or even that they do the job, but what you do have to have is a way to get the value's into the function. Also, the setTimeout anon function might not actually need the parameters, but it should give you an idea.
$(canvas).click(function() {
$.each(text, function(key, val) {
$(canvas).removeAttr('class')
var $canvas = $(canvas) //?
var class_val = val //?
setTimeout(function ($canvas, class_val) {
$canvas.addClass(class_val);
}, 2000);
});
});
Edit: I'd do this instead
function modify_element($element, class_name){
$element.removeClass('class');
setTimeout(function ($element) {
$element.addClass(class_name);
}, 1000);
//adds the class 1 second after removing it
}
$(canvas).click(function() {
$.each(text, function(key, val) {
setTimeout(modify_element($(canvas), val),2000);
//this will loop over the elements with 2 seconds between elements
});
});
"loop over an array continuously" this sounds like a infinite loop, I don't think you want that. About pausing the loop, this is possible, you can use this

Categories

Resources