In my html body I am using a javascript that writes and changes a line of text in my div, with ID "moto", every 5 seconds.
var text = ["TEXT 1","TEXT 2","TEXT 3","TEXT 4"];
var counter = 0;
var elem = document.getElementById("moto");
ChangeFunction();
setInterval(ChangeFunction, 5000);
function ChangeFunction() {
elem.innerHTML = text[counter];
counter++;
if(counter >= text.length) { counter = 0; }
}
#moto{
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
<div id="moto"></div>
Do I need to apply some java fade-in fade-out? I would rather use CSS...
You can use jquery to do this easily as below
var text = ["TEXT 1","TEXT 2","TEXT 3","TEXT 4"];
var counter = 0;
var elem = document.getElementById("moto");
ChangeFunction();
setInterval(ChangeFunction, 5000);
function ChangeFunction() {
var moto = text[counter++];
$(elem).fadeOut('slow', function() {
$(elem).html(moto);
$(elem).fadeIn('slow');
});
if(counter >= text.length) { counter = 0; }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="moto"></div>
You don't need JavaScript at all. Here's a pure CSS implementation:
#keyframes fade {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#moto {
position: relative;
}
#moto div {
position: absolute;
top: 0;
left: 0;
opacity: 0;
animation: fade 4s 0s infinite alternate-reverse;
}
#moto :nth-child(1) {
animation-delay: -2s;
}
#moto :nth-child(2) {
animation-delay: 0s;
}
#moto :nth-child(3) {
animation-delay: 2s;
}
#moto :nth-child(4) {
animation-delay: 4s;
}
<div id="moto">
<div>TEXT 1</div>
<div>TEXT 2</div>
<div>TEXT 3</div>
<div>TEXT 4</div>
</div>
Related
I have the below code to begin an animation for an acronym that makes the code transform to a vertical form. I'd like to have it where it will type the rest of the acronym out next to the letters on the button click. However doing so adds far to much space between all the type I want them to basically line up how they do before the button is pressed you can see what it currently does here:
var a = 0;
var b = 0;
var c = 0;
var d = 0;
var e = 0;
var f = 0;
var balance = 'alance';
var execution = 'xecution';
var teamwork = 'eamwork';
var training = 'raining';
var experience = 'xperience';
var results = 'esults';
var speed = 50;
function typeWriter() {
while (a < balance.length) {
document.getElementById("balance").innerHTML += balance.charAt(a);
a++;
setTimeout(typeWriter, speed);
}
while (b < execution.length) {
document.getElementById("execution").innerHTML += execution.charAt(b);
b++;
setTimeout(typeWriter, speed);
}
while (c < teamwork.length) {
document.getElementById("teamwork").innerHTML += teamwork.charAt(c);
c++;
setTimeout(typeWriter, speed);
}
while (d < training.length) {
document.getElementById("training").innerHTML += training.charAt(d);
d++;
setTimeout(typeWriter, speed);
}
while (e < experience.length) {
document.getElementById("experience").innerHTML += experience.charAt(e);
e++;
setTimeout(typeWriter, speed);
}
while (f < results.length) {
document.getElementById("results").innerHTML += results.charAt(f);
f++;
setTimeout(typeWriter, speed);
}
}
function scroller() {
var move = document.querySelectorAll(".move");
var fade = document.querySelectorAll(".fade");
for (var i = 0; i < move.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = move[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
move[i].classList.add("active");
} else {
move[i].classList.remove("active");
}
}
for (var i = 0; i < fade.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = fade[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
fade[i].classList.add("active");
} else {
fade[i].classList.remove("active");
}
}
}
window.addEventListener("scroll", scroller);
.move {
font-size: 105px;
position: relative;
}
.move.active {
font-size: 105px;
position: relative;
animation: mover 5s ease 0s normal forwards;
}
.fade {
font-size: 105px;
position: relative;
}
.fade.active {
font-size: 105px;
position: relative;
animation: fader 2s ease 0s normal forwards;
}
.move.active span {
margin: 0px;
position: relative;
display: inline-block;
animation: rotate 5s ease 0s normal forwards;
}
#keyframes mover {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(-20%, 300px) skew(0deg) rotate(90deg);
}
}
#keyframes rotate {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(0px, 0px) skew(0deg) rotate(-90deg);
}
}
#keyframes fader {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
opacity: 0;
}
}
#keyframes typing {
0% {
width: 0%
}
100% {
width: 100%
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<CENTER>
<h2 class="fade">IT'S </h2>
<h2 class="move">
<span id="balance">B</span>
<span id="execution">E</span>
<span id="teamwork">T</span>
<span id="training">T</span>
<span id="experience">E</span>
<span id="results">R</span>
</h2>
<h2 class="fade">TOGETHER </h2>
</CENTER>
<button onclick="typeWriter()">Click me</button>
https://noahark.w3spaces.com/saved-from-Tryit-2022-04-29.html
Any and all help will be extremely appreciated.
In your particular example, the spacing is coming from the lengths of the words. When I undo the rotation caused by the animation, we can see this:
So, if you force the length of the word to be one character (regardless of how many characters are actually there), then you no longer have the spacing problem caused by the words' length.
.move span {
display: inline-block;
width: 1.5ch;
}
Although forcing the span's width works, it can feel a little naughty. We're now relying on nice overflow behaviour, and hopefully we don't need the true width of the element for anything else.
I found that I didn't have to force width if we start at the end rather than the beginning. By default (no transform applied), it is already arranged as a column of words exactly like what you want at the end of the animation.
Then, you apply the 90 degree rotation to get the horizontal "BETTER" text. The animation undoes the rotation, meaning you always get what you expect at the end.
const betterAcronym = document.querySelector('#better-acronym')
const revealButton = document.querySelector('#reveal-button')
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms))
const typeElement = async (element) => {
const word = element.dataset['word']
const start = element.textContent.length
for (let c = start; c < word.length; ++c) {
element.textContent += word[c]
await wait(100)
}
}
revealButton.addEventListener('click', async () => {
betterAcronym.classList.add('revealed')
await wait(2750) // length of the animation plus some
Array.from(betterAcronym.children).forEach(typeElement)
})
.acronym {
font-size: 1.25rem;
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
transform: rotate(-90deg);
transform-origin: 0.5em 0.5em;
transition: transform 2.5s ease-in-out;
}
.acronym > li {
display: inline-block;
transform: rotate(90deg);
transform-origin: 0.5em 0.5em;
transition: transform 2.5s ease-in-out;
}
.acronym.revealed {
transform: rotate(0deg);
}
.acronym.revealed > li {
transform: rotate(0deg);
}
body {
overflow: hidden;
}
button {
font-size: 1.25rem;
}
<ol id="better-acronym" class="acronym">
<li data-word="balance">B</li>
<li data-word="execution">E</li>
<li data-word="teamwork">T</li>
<li data-word="training">T</li>
<li data-word="experience">E</li>
<li data-word="results">R</li>
</ol>
<button id="reveal-button">Reveal</button>
You just have to provide width: 73px to .move.active span. And after the animation ends adjust the parent height.
In the demo look for code comments. I've also fixed the typing effect code. View in full page mode.
const move = document.querySelector(".move");
const fade = document.querySelectorAll(".fade");
const words = ['balance', 'execution', 'teamwork', 'training', 'experience', 'results'];
let col = 1;
let row = 0;
const speed = 100;
function typeWriter() {
const e = document.getElementById(words[row]);
e.textContent += words[row][col];
col++;
if(col >= words[row].length){
col = 1;
row++;
}
if(row < words.length)
setTimeout(typeWriter, speed);
else
typeWriter = () => console.log('can not rerun the animation');
}
function scroller() {
var windowHeight = window.innerHeight;
var elementTop = move.getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
move.classList.add("active");
} else {
move.classList.remove("active");
}
for (var i = 0; i < fade.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = fade[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
fade[i].classList.add("active");
} else {
fade[i].classList.remove("active");
}
}
}
// adjust parent height after the animation ends
// change the calculation as per your requirements
move.onanimationend = (event)=>{
if(move === event.target) {
move.parentElement.style.height = move.parentElement.offsetHeight - move.offsetHeight + move.offsetWidth + - move.nextElementSibling.scrollHeight + 'px';
}
};
window.addEventListener("scroll", scroller);
center{ border: 1px dashed gray;}
.move {
font-size: 105px;
position: relative;
}
.move.active {
font-size: 105px;
position: relative;
animation: mover 5s ease 0s normal forwards;
/* we need exact width to adjust the parent's height */
width: fit-content;
}
.fade {
font-size: 105px;
position: relative;
}
.fade.active {
font-size: 105px;
position: relative;
animation: fader 2s ease 0s normal forwards;
}
.move.active span {
margin: 0px;
position: relative;
display: inline-block;
animation: rotate 5s ease 0s normal forwards;
/* specify width equal to one character in the font */
width: 73px;
}
#keyframes mover {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(-20%, 300px) skew(0deg) rotate(90deg);
}
}
#keyframes rotate {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(0px, 0px) skew(0deg) rotate(-90deg);
}
}
#keyframes fader {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
opacity: 0;
}
}
#keyframes typing {
0% {
width: 0%
}
100% {
width: 100%
}
}
button {
position: fixed;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<CENTER>
<h2 class="fade">IT'S </h2>
<h2 class="move">
<span id="balance">B</span>
<span id="execution">E</span>
<span id="teamwork">T</span>
<span id="training">T</span>
<span id="experience">E</span>
<span id="results">R</span>
</h2>
<h2 class="fade">TOGETHER </h2>
</CENTER>
<button onclick="typeWriter()">Click me</button>
Adjust the calculations as per your requirements.
when i use this code it change the background color yo yellow in one time and i want to change the color one by one red then blue then green and so on.....thanks in advance
var colorss = ["red", "blue", "green","maroon","yellow"];
for (i=0;i<colorss.length;i+=1) {
document.body.setAttribute('style',"background-color:" + colorss[i]);
}
Is this what you mean?
jQuery(function($) {
function changeColor(selector, colors, time) {
var curCol = 0,
timer = setInterval(function() {
if (curCol === colors.length) curCol = 0;
$(selector).css("background-color", colors[curCol]);
curCol++;
}, time);
}
$(window).load(function() {
changeColor(".container", ["green", "yellow", "blue", "red"], 3000);
});
});
.container {
background-color: red;
height: 500px;
-webkit-transition: background-color 0.5s ease-in-out;
-moz-transition: background-color 0.5s ease-in-out;
-o-transition: background-color 0.5s ease-in-out;
-khtml-transition: background-color 0.5s ease-in-out;
transition: background-color 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container"></div>
OR
using CSS only:
html,
body {
height: 100%;
}
body {
-webkit-animation: background 5s cubic-bezier(1, 0, 0, 1) infinite;
animation: background 5s cubic-bezier(1, 0, 0, 1) infinite;
}
#-webkit-keyframes background {
0% {
background-color: #f99;
}
33% {
background-color: #9f9;
}
67% {
background-color: #99f;
}
100% {
background-color: #f99;
}
}
#keyframes background {
0% {
background-color: #f99;
}
33% {
background-color: #9f9;
}
67% {
background-color: #99f;
}
100% {
background-color: #f99;
}
}
Your code is correct, but the computer computes faster than you can see or the webpage can load.
also you have an s too much in colors document.body.setAttribute('style',"background-color:" + colors[i]);
here is working code if you want to see the loop
var colors = ["red", "blue", "green","maroon","yellow"];
let body = document.getElementById('body');
var i = 0;
function myLoop () {
setTimeout(function () {
document.body.setAttribute('style',"background-color:" + colors[i]);
i++;
if (i < colors.length) {
myLoop();
}
}, 1500) /*1.5 seconds*/
}
myLoop();
<body>
<h1>hello</h1>
</body>
I have a problem. I made a CSS animation on the body, going from one color to the other for like 10 seconds, only showing one image and one paragraph, and ignoring the rest of the paragraphs and other stuff written in my HTML code.
When the animation is finished, I would like that the body displays the actual HTML content (other paragraphs and DIV's, etc.). Now that is the problem, I tried with opacity and setting it to 0 during the animation and then resetting it to 1 after the animation ends but I could not do it? Could you help me? I created the animations in JS with event listeners and keyframes in CSS.
let backColor = document.querySelector('body');
let banner = document.querySelector('#banner p');
let img = document.querySelector('#banner img');
function myMove() {
backColor.style.WebkitAnimation = 'mymove 7s 1s 1 forwards';
backColor.style.animation = 'mymove 7s 1s 1 forwards';
}
backColor.addEventListener('animationstart', () => {
this.style.backgroundColor = 'white';
});
backColor.addEventListener('animationend', () => {
this.style.backgroundColor = 'black';
});
myMove();
function yourMove() {
banner.style.WebkitAnimation = 'yourmove 6s 4s 1';
banner.style.animation = 'yourmove 6s 4s 1';
}
banner.addEventListener('animationstart', () => {
this.style.opacity = 0;
});
banner.addEventListener('animationend', () => {
this.style.opacity = 1;
});
yourMove();
function hisMove() {
img.style.WebkitAnimation = 'hismove 3s 6s 1';
img.style.animation = 'hismove 3s 6s 1';
}
img.addEventListener('animationstart', () => {
this.style.opacity = 0;
});
img.addEventListener('animationend', () => {
this.style.opacity = 1;
});
hisMove();
body {
margin: 0;
padding: 0;
}
#keyframes mymove {
from {
background-color: white;
}
to {
background-color: black;
}
}
#banner p {
color: white;
font-size: 25px;
font-family: Georgia;
opacity: 0;
text-align: center;
}
img {
position: relative;
left: 35%;
opacity: 0;
}
#keyframes yourmove {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes hismove {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="banner">
<p>In the loving memory of <br />Kobe Bryant (1978 - 2020)</p>
<img src="https://i.ytimg.com/vi/tiE7aa9HTec/maxresdefault.jpg" width="450" height="300">
</div>
<div id="container">
<!-- rest of the html content -->
</div>
<script type="text/javascript" src="kobe.js"></script>
</body>
</html>
Wouldn't had make it this way,but it's fixed:
let backColor = document.querySelector('body');
let banner = document.querySelector('#banner p');
let img = document.querySelector('#banner img');
function myMove() {
backColor.style.WebkitAnimation = 'mymove 7s 1s 1 forwards';
backColor.style.animation = 'mymove 7s 1s 1 forwards';
}
backColor.addEventListener('animationstart', () => {
backColor.style.backgroundColor = 'white';
});
backColor.addEventListener('animationend', () => {
backColor.style.backgroundColor = 'black';
});
myMove();
function yourMove() {
banner.style.WebkitAnimation = 'yourmove 6s 4s 1';
banner.style.animation = 'yourmove 6s 4s 1';
}
banner.addEventListener('animationstart', () => {
banner.style.opacity = 0;
});
banner.addEventListener('animationend', () => {
banner.style.opacity = 1;
});
yourMove();
function hisMove() {
img.style.WebkitAnimation = 'hismove 3s 6s 1';
img.style.animation = 'hismove 3s 6s 1';
}
img.addEventListener('animationstart', () => {
img.style.opacity = 0;
});
img.addEventListener('animationend', () => {
img.style.opacity = 1;
});
hisMove();
body {
margin: 0;
padding: 0;
color: white;
}
#keyframes mymove {
from {
background-color: white;
}
to {
background-color: black;
}
}
#banner p {
color: white;
font-size: 25px;
font-family: Georgia;
opacity: 0;
text-align: center;
}
img {
position: relative;
left: 35%;
opacity: 0;
}
#keyframes yourmove {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes hismove {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="banner">
<p>In the loving memory of <br />Kobe Bryant (1978 - 2020)</p>
<img src="https://i.ytimg.com/vi/tiE7aa9HTec/maxresdefault.jpg" width="450" height="300">
</div>
<div id="container">
<!-- rest of the html content -->
RIP RIP RIP RIP RIP RIP
</div>
<script type="text/javascript" src="kobe.js"></script>
</body>
</html>
I'm trying to get an action to occur when one clicks on an image, however only when the image is at full opacity
function func() {
if ($('.Absolute-Center').css('opacity') == 1) {
alert("it works");
}
}
.Absolute-Center {
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
img.Absolute-Center {
opacity: 0.05;
filter: alpha(opacity=5);
-webkit-transition: opacity 20s linear;
}
img.Absolute-Center:hover {
opacity: 1;
filter: alpha(opacity=100);
-webkit-transition: opacity 20s linear;
}
<img src="picture.png" class="Absolute-Center" onclick="func()" />
Try using transitionend event , .addClass() , .removeClass() ; removing :hover from css
function func(e) {
if ($(this).css("opacity") == 1) {
alert("it works");
$(this).removeClass("clicked")
}
};
$(".Absolute-Center").on({
"click": function() {
$(this).addClass("clicked")
},
"transitionend": func
})
.Absolute-Center {
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
img.Absolute-Center {
opacity: 0.05;
filter: alpha(opacity=5);
transition: opacity 20s linear;
}
img.Absolute-Center.clicked {
opacity: 1;
filter: alpha(opacity=100);
transition: opacity 20s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<img src="http://lorempixel.com/50/50" class="Absolute-Center" />
This should help improve understanding and should be easily adaptable to do exactly what you want.
$(function() {
$('img').on('click', function() {
var alpha = $(this).css('opacity');
$("#msg").text((alpha == 1) ? "full" : alpha);
}).on('transitionend', function() {
var alpha = $(this).css('opacity');
if (alpha == 1) {
$("#msg2").fadeIn().delay(700).fadeOut();
} else {
$("#msg3").fadeIn().delay(700).fadeOut();
}
});
});
img {
border: 1px solid #000;
}
img {
opacity: 0.05;
filter: alpha(opacity=5);
-webkit-transition: opacity 5s linear;
}
img:hover {
opacity: 1;
filter: alpha(opacity=100);
-webkit-transition: opacity 5s linear;
}
#msg2, #msg3 {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img src="picture.png" />
<div>Last clicked at opacity: <span id="msg"></span>
</div>
<div id="msg2">End of fade-IN transition</div>
<div id="msg3">End of fade-OUT transition</div>
I have the following animation which fade in and out some images. But after the last images the animation will stop.
First, I want to loop this animation over and over again.
Second, I think is a CSS issue that the fading is not working so well as there is a pause between images when fade out and I want to know if I can overlap the images when fading.
CSS:
#foo {
position:relative;
width: 300px;
height: 250px;
}
#foo img {
left:0;
-webkit-transition: opacity 3s ease-in-out;
-moz-transition: opacity 3s ease-in-out;
-o-transition: opacity 3s ease-in-out;
transition: opacity 3s ease-in-out;
}
#keyframes bannerFadeInOut {
0% {
opacity:0;
}
50% {
opacity:1;
}
100% {
opacity:0;
}
}
#-moz-keyframes bannerFadeInOut {
0% {
opacity:0;
}
50% {
opacity:1;
}
100% {
opacity:0;
}
}
#-webkit-keyframes bannerFadeInOut {
0% {
opacity:0;
}
50% {
opacity:1;
}
100% {
opacity:0;
}
}
#frames {
position: absolute;
animation: bannerFadeInOut;
animation-duration: 3s;
animation-iteration-count: 99999;
animation-timing-function: ease-in-out;
}
JS
var img, i = 1;
var nImg = 4;
div = document.getElementById('foo');
img = new Image();
div.appendChild(img);
img.src = 'http://tdhdemo.com/frames/frame_' + i + '.jpg';
img.id = "frames";
var interval = setInterval(function() {
i++;
var element = document.getElementById("frames");
element.outerHTML = "";
delete element;
if(i > nImg) {
clearInterval(interval);
} else {
img = new Image();
div.appendChild(img);
img.src = 'http://tdhdemo.com/frames/frame_' + i + '.jpg';
img.id = "frames";
}
}, 3000);
Demo: http://jsfiddle.net/o1zj2c1w/
I just added a quick if statement to make a loop, it resets i back to 1 if nImg is exceeded:
if(i>nImg){
i=1;
}
JSfiddle
Put the entire code into a function and call after you clearInterval
Demo:
function init() {
var img, i = 1;
var nImg = 4;
div = document.getElementById('foo');
img = new Image();
div.appendChild(img);
img.src = 'http://tdhdemo.com/frames/frame_' + i + '.jpg';
img.id = "frames";
var interval = setInterval(function () {
i++;
var element = document.getElementById("frames");
element.outerHTML = "";
delete element;
if (i > nImg) {
clearInterval(interval);
init();
} else {
img = new Image();
div.appendChild(img);
img.src = 'http://tdhdemo.com/frames/frame_' + i + '.jpg';
img.id = "frames";
}
}, 3000);
}
init();
#foo {
position:relative;
width: 300px;
height: 250px;
}
#foo img {
left:0;
-webkit-transition: opacity 3s ease-in-out;
-moz-transition: opacity 3s ease-in-out;
-o-transition: opacity 3s ease-in-out;
transition: opacity 3s ease-in-out;
}
#keyframes bannerFadeInOut {
0% {
opacity:0;
}
50% {
opacity:1;
}
100% {
opacity:0;
}
}
#-moz-keyframes bannerFadeInOut {
0% {
opacity:0;
}
50% {
opacity:1;
}
100% {
opacity:0;
}
}
#-webkit-keyframes bannerFadeInOut {
0% {
opacity:0;
}
50% {
opacity:1;
}
100% {
opacity:0;
}
}
#frames {
position: absolute;
animation: bannerFadeInOut;
animation-duration: 3s;
animation-iteration-count: 99999;
animation-timing-function: ease-in-out;
}
<div id="foo"></div>
http://jsfiddle.net/kishoresahas/o1zj2c1w/2/
You can copy this and try again:
var img, i = 1;
var nImg = 4;
div = document.getElementById('foo');
img = new Image();
div.appendChild(img);
img.src = 'http://tdhdemo.com/frames/frame_' + i + '.jpg';
img.id = "frames";
var interval = setInterval(function() {
var element = document.getElementById("frames");
element.outerHTML = "";
delete element;
img = new Image();
div.appendChild(img);
img.src = 'http://tdhdemo.com/frames/frame_' + i + '.jpg';
img.id = "frames";
i = i == nImg ? 1 : i + 1;
}, 3000);
I'd just replace
i++;
with
i < nImg ? i++ : i = 1;