So far I created an array with 11 images, initialized the counter, created a function, created a for loop but here is where I get lost. I looked at examples and tutorial on the internet and I can see the code is seeming simple but I'm not getting something basic here. I don't actually understand how to call the index for the images. Any suggestions. Here is the code.
<script type="text/javascript">
var hammer=new Array("jackhammer0.gif",
"jackhammer1.gif",
"jackhammer2.gif",
"jackhammer3.gif",
"jackhammer4.gif",
"jackhammer5.gif",
"jackhammer6.gif",
"jackhammer7.gif",
"jackhammer8.gif",
"jackhammer9.gif",
"jackhammer10.gif")
var curHammer=0;
var numImg = 11;
function getHammer() {
for (i = 0; i < hammer.length; i++)
{
if (curHammer < hammer.length - 1) {
curHammer = curHammer +1;
hammer[i] = new Image();
hammer[i].src="poses/jackhammer" +(i+1) + ".gif";
var nextHammer = curHammer + 1;
nextHammer=0;
{
}
}
}
}
setTimeout("getHammer()", 5000);
</script>
</head>
<body onload = "getHammer()";>
<img id="jack" name="jack" src = "poses/jackhammer0.gif" width= "100" height ="113" alt = "Man and Jackhammer" /><br/>
<button id="jack" name="jack" onclick="getHammer()">Press button</button>
Following on what Paul, said, here's an example of what should work:
var hammer=["jackhammer0.gif","jackhammer1.gif","jackhammer2.gif","jackhammer3.gif",
"jackhammer4.gif","jackhammer5.gif","jackhammer6.gif","jackhammer7.gif",
"jackhammer8.gif","jackhammer9.gif","jackhammer10.gif"];
var curHammer=0;
function getHammer() {
if (curHammer < hammer.length) {
document.getElementById("jack").src= "poses/" + hammer[curHammer];
curHammer = curHammer + 1;
}
}
setTimeout("getHammer()", 5000);
The big missing element is that you need to call getElementById("jack") to get a reference to the DOM Image so that you can change it's source. If you're using jQuery or most other JS frameworks, just type $("#jack") to accomplish the same.
I don't understand the need for the for loop at all, just increment the index value [curHammer] each time you click, and reset if it passes your max index length (in this case 11).
Pseudo-Code:
currentHammer = -1
hammers = [ "a1.jpg", "a2.jpg", "a3.jpg"]
getHammer()
{
currentHammer = currentHammer + 1;
if(currentHammer > 2)
currentHammer = 0;
image.src = hammers[currentHammer];
}
a) are you just trying to show an animated gif? If so, why not use Adobe's Fireworks and merge all those gifs into a single gif?
b) you know that the way you have it the display is going to go crazy overwriting the gif in a circle right?
c) you might want to put a delay (or not). If so, make the load new gif a separate function and set a timeout to it (or an interval).
Also, you are being redundant. How about just changing the src for the image being displayed?:
var jackHammer = new Array();
for (var i=0;i<11;i++) { //pre-loading the images
jackHammer[i] = new image();
jackHammer[i].src = '/poses/jackHammer'+i.toString()+'.gif';
} //remember that "poses" without the "/" will only work if that folder is under the current called page.
for (var i=0;i<11;i++) { //updating the image on
document.getElementById('jhPoses').src = jackHammer[i].src;
}
on the document itself,
< img id='jhPoses' src='1-pixel-transparent.gif' width='x' height='y' alt='poses' border='0' />
Related
I have been writing Javascript code to show a traffic light with a changing image. It uses a set array but I am new to coding and have not been told how to do this. I have written the code below but it is still not working. I can get it to run by clicking it but I need it to run without having to press the button lots of times.
It changes between images that are in the same folder as the code. I want it to work by a person only pressing the button once.
HTML:
<img id="light" src="traffitlr.jpeg">
<button type="button" onclick="changeLights()">changelights(and Start Lights)</button>
<button type="button" onclick=setinterval(change,1000)>start auto cycle</button>
Javascript:
var list = [
"traffitlg.jpg",
"traffitla.jpg",
"traffitlr.jpg",
"traffitly.jpg"
];
var index = 0;
function changeLights() {
index = index + 1;
if (index == list.length) index = 0;
var image = document.getElementById('light');
image.src=list[index];
}
var list = [
"traffitlg.jpg",
"traffitla.jpg",
"traffitlr.jpg",
"traffitly.jpg"
];
var index = 0;
var startChangeLights=function changeLights() {
console.log("change lights");
index = index + 1;
if (index == list.length) index = 0;
var image = document.getElementById('light');
image.src=list[index];
setTimeout(changeLights,6000);//change in 6 seconds ( 6000milliseconds)
startChangeLights=function(){console.log("already started");};//prevent user from starting multiple times
}
Use like this:
startChangeLights();//change lights
startChangeLights();//already started
//after 6 s : change Lights
I mainly use a Timeout, that changes the lights every 6 seconds. I also use an named-anonymous function, to prevent starting twice...
My code is running well...
but there is one thing I can't solve:
when I mouseover the image the loop starts well, but on subsequent mouseovers it starts changing faster and faster...
var Image = new Array("//placehold.it/400x180/?text=Welcome",
"//placehold.it/400x180/?text=To",
"//placehold.it/400x180/?text=My",
"//placehold.it/400x180/?text=Web+page",
"//placehold.it/400x180/?text=INPHP");
var Image_Number=0;
var Image_Length= Image.length;
function change_image(num){
Image_Number = Image_Number + num;
if(Image_Number > Image_Length)
Image_Number = 0;
if(Image_Number < Image_Length)
document.slideshow.src = Image[Image_Number];
return false;
Image_Number = Image_Length;
}
function auto () {
setInterval("change_image(1)", 1000);
}
<img src="//placehold.it/400x180/?text=Welcome" name="slideshow" onmouseover="auto()" />
On every mouseover you're reassigning a brand-new-intervalâ„¢ resulting in multiple functions running at the same time.
name on IMG tag is an obsolete HTML5 attribute - See also img tag # W3.org
"change_image(1)" ...strings inside setInterval or setTimeout tigger eval. Which is bad. The real function name should be used instead: setInterval(functionName, ms)
You're not managing well the argument num
You cannot have code after a return statement
Use the mouseenter event (instead of mouseover)
and many more errors....
Here's a remake:
var images = [
"//placehold.it/400x180/?text=Welcome",
"//placehold.it/400x180/?text=To",
"//placehold.it/400x180/?text=My",
"//placehold.it/400x180/?text=Web+page",
"//placehold.it/400x180/?text=INPHP"
];
var c = 0; // c as Counter ya?
var tot = images.length;
var angryCat = false;
// Preload! Make sure all images are in tha house
for(var i=0; i<tot; i++) {
var im = new Image();
im.src= images[i];
}
function changeImage() {
document.slideshow.src = images[++c%tot];
}
function auto() {
if(angryCat) return; // No more mouse enter
angryCat = true;
setInterval(changeImage, 1000);
}
<img src="//placehold.it/400x180/?text=Welcome" name="slideshow" onmouseenter="auto()" />
The increment and loop is achieved using ++c % tot
The angryCat boolean flag helps to know it the auto() already started (mouse was there!), in that case it will return; (exit) the function preventing the creation of additional overlapping intervals on subsequent mouseenter (which was your main issue).
Additionally, I'd suggest to keep your JS away from HTML, so instead of the JS attribute event
onmouseenter="auto()"
assign an ID to your image id="myimage" and use JS:
document.getElementById("myimage").addEventListener("mouseenter", auto, false);
I think I'm missing an obvious rule here and it would be great to get it clarified -
I'm trying to write an image preloader and I'm following the advice given on this posting:
Preloading images in Javascript? Without jQuery
I can see how it all works up until:
for(var i = 0; i < imageList.length; i++ ) {
var imageObject = new Image();
imageObject.src = imageList[i]; }
I keep thinking this would simply change/overwrite the src property at every iteration, leaving imageObject.src as the last image in the list at the end of the loop, though clearly the function is meant for using multiple images.
So I'm assuming it leaves imageObject containing an array of images but I'm not sure how it does this. What do I have wrong?
What you have will "probably" work. But, it's not the ideal way to do things because it relies on some undocumented aspects of a browser and garbage collection. See here and here for safer ways to do this. I'll try to explain what your code is doing.
When you do this line:
var imageObject = new Image();
it is creating a new DOM image object and placing a reference to that object in the variable imageObject.
When you do this line:
imageObject.src = imageList[i];
it is assigning the .src property of that new image object. This will NOT be overwriting the .src property on the previous image object.
But, because the previous image objects are not stored anywhere and no other javascript has any references to them, they are available for garbage collection by the browser and it is free to get rid of them at any time. To use this for reliable caching, you are hoping that the browser does not cancel the networking operation in progress that is loading the images and you are hoping that they still get into the browser cache so they are preloaded.
It is much safer to store the imageObject in an array as the other solutions I've pointed you to will do. This keeps them from being garbage collected so there is no risk that their image loading will be cancelled.
For example, it would be safer to do this:
var imgs = [];
for (var i = 0; i < imageList.length; i++ ) {
var imageObject = new Image();
imageObject.src = imageList[i];
imgs.push(imageObject);
}
The previous two references to other solutions to this do something similar, but package this in a function and one also has the ability to notify you when all the images have finished preloading.
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
var imageList = new Array("dummyImg1.jpg", "dummyImg2.jpg");
var imagePlaceholder = new Array(imageList.length);
function waitImagesLoaded() {
var allImagesLoaded = true;
for (var i = 0; i < imageList.length && allImagesLoaded; i++) {
allImagesLoaded &= imagePlaceholder[i].complete;
}
if (allImagesLoaded) {
for (var i = 0; i < imageList.length; i++) {
var imgElemIdToReplace = "img" + String(i + 1);
replaceElem(imagePlaceholder[i], document.getElementById(imgElemIdToReplace));
}
} else {
window.setTimeout(waitImagesLoaded, 500);
}
}
function replaceElem(substituteElem, elemToReplace) {
var parentNode = elemToReplace.parentNode;
parentNode.replaceChild(substituteElem, elemToReplace);
}
</script>
</head>
<body>
<img id="img1" src="" alt="">
<img id="img2" src="" alt="">
<script type = "text/javascript">
for (var i = 0; i < imageList.length; i++) {
var imageObject = new Image();
imageObject.src = imageList[i];
imagePlaceholder[i] = imageObject;
}
window.setTimeout(waitImagesLoaded, 500);
</script>
</body>
</html>
Lets say I have these images gallery, how do i randomly display the images everytime when i reload the page?
http://creativepreviews.com/fiddle/study/20131007/
Let's say the image will display in the background of the DIV, then the following should do it.
// JS
var imgArray = ["img1.jpg", "cat.jpg", "sky.jpg"]
function randomBg() {
x = Math.random()
y = Math.round(x * 10)
if (imgArray[y] != undefined) {
document.getElementById("blah").style.backgroundImage = "url('" + imgArray[y] + "')"
} else {
document.getElementById("blah").style.backgroundImage = "url('default.jpg')"
}
}
...and the HTML.
<script src="test.js"></script>
<body onload="randomBg()">
<div id="blah"></div>
...or you could replace the style.backgroundImage in the JS with innerHTML = <img src=" etc...
You could do something along these lines (not tested)
var grd = $('#grid');
var imgs = grd.children();
imgs.sort(function(){return (Math.round(Math.random()) - 0.5);});
grd.remove('li');
for(var i=0;i < imgs.length;i++) grd.append(imgs[i]);
In essence what we are doing is getting all the li elements in 'grid' into an array, randomizing them, removing them all from 'grid' and then putting them back in again.
If you had supplied a working fiddle rather than a link to the finished article it would be easier to modify it and provide a more complete solution.
I have a client who has made a 'Visual Diary' of photographs that he took once a day for 365 days, for his portfolio site. He wants me to put these together into a time-lapse effect piece. I thought about using Flash but in the end opted for JavaScript.
What needs to happen is this: The images cycle really really quickly with no transitions or anything, just image-image-image etc. About 30/fps or something like that. When you click the flashing images, it stops on the image you have selected, so the user can take a look. When you click again, the slideshow starts playing again.
My problem is I'm a PHP/XHTML/CSS bloke who hasn't really the foggiest about JavaScript. I can happily integrate it into any page, but it's just coding the JavaScript that's troubling me.
On his homepage, I have this code used to display a basic slideshow - with transition effects etc. It's in the HTML but you can fathom out the code I'm sure:
<!-- Code for slideshow -->
<!-- Found on http://www.webdeveloper.com/forum/showthread.php?t=81441 -->
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
// Set slideShowSpeed (milliseconds)
var slideShowSpeed = 3000;
// Duration of crossfade (seconds)
var crossFadeDuration = 3;
// Specify the image files
var Pic = new Array();
// to add more images, just continue
// the pattern, adding to the array below
Pic[0] = '1.jpg'
Pic[1] = '2.jpg'
Pic[2] = '3.jpg'
Pic[3] = '4.jpg'
Pic[4] = '5.jpg'
Pic[5] = '6.jpg'
Pic[6] = '7.jpg'
Pic[7] = '8.jpg'
Pic[8] = '9.jpg'
Pic[9] = '10.jpg'
Pic[10] = '11.jpg'
Pic[11] = '12.jpg'
Pic[12] = '13.jpg'
Pic[13] = '14.jpg'
Pic[14] = '15.jpg'
Pic[15] = '16.jpg'
Pic[16] = '17.jpg'
Pic[17] = '18.jpg'
Pic[18] = '19.jpg'
Pic[19] = '20.jpg'
// do not edit anything below this line
var t;
var j = 0;
var p = Pic.length;
var preLoad = new Array();
for (i = 0; i < p; i++) {
preLoad[i] = new Image();
preLoad[i].src = Pic[i];
}
function runSlideShow() {
if (document.all) {
document.images.SlideShow.style.filter="blendTrans(duration=2)";
document.images.SlideShow.style.filter="blendTrans(duration=crossFadeDuration)";
document.images.SlideShow.filters.blendTrans.Apply();
}
document.images.SlideShow.src = preLoad[j].src;
if (document.all) {
document.images.SlideShow.filters.blendTrans.Play();
}
j = j + 1;
if (j > (p - 1)) j = 0;
t = setTimeout('runSlideShow()', slideShowSpeed);
}
// End -->
</script>
Is there any way to modify this code to turn off all transitional effects, and make it stop playing when you click it/start it again? Otherwise, a reference to some different code would be helpful.
Thank you everybody!
Jack
You seem to be using IE-specific code. I would recommend using the various effects modules in a dedicated JavaScript library such as MooTools (my personal favourite), jQuery, or Prototype + script.aculo.us.
To stop the slideshow, you should be able to simply clear timeout t:
clearTimeout(t);
Also, you shouldn't quote the first parameter of setTimeout. Pass it a function reference:
setTimeout(runSlideShow, slideShowSpeed);