JavaScript Photo Slider - javascript

I'm working on making a JS script that will go in the header div and display a few pictures. I looked into JQuery Cycle, but it was out of my league. The code I wrote below freezes the browser, should I be using the for loop with the timer var?
<script type="text/JavaScript" language="JavaScript">
var timer;
for (timer = 0; timer < 11; timer++) {
if (timer = 0) {
document.write('<img src="images/one.png">');
}
if (timer = 5) {
document.write('<img src="images/two.png">');
}
if (timer = 10) {
document.write('<img src="images/three.png">');
}
}
</script>
Thanks!

Assuming you want a script to rotate images and not just write them to the page as your code will do, you can use something like this:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="target"></div>
<script>
var ary = ["images/one.png","images/two.png","images/three.png"];
var target = document.getElementById("target");
setInterval(function(){
target.innerHTML = "<img src=\""+ary[0]+"\" />";
ary.push(ary.shift());
},2000);
</script>
</body>
</html>
Of course the above code has no effects (like fading) which jQuery will give yous, but it also doesn't require loading the entire jQuery library for something so basic.

How about just running the script after the page loads?
<script>
// in <head> //
function load() {
var headDiv = document.getElementById("head");
var images = ["images/one.png", "images/two.png"];
for(var i = 0; i<images.length; i++) {
image = document.createElement("img");
image.src = images[i];
headDiv.appendChild(image);
}
}
</script>
Then use <body onload="load();"> to run the script.
Edit
To add in a delay loading images, I rewrote the code:
<script>
// in <head> //
var displayOnLoad = true; // Set to true to load the first image when the script runs, otherwise set to false to delay before loading the first image
var delay = 2.5; // seconds to delay between loading images
function loadImage(url) {
image = document.createElement("img");
image.src = images[i];
headDiv.appendChild(image);
}
function load() {
var headDiv = document.getElementById("head");
var images = ["images/one.png", "images/two.png"];
for(var i = 0; i<images.length; i++) {
setTimeout(loadImage(images[i]), (i+displayOnLoad)*(delay*1000));
}
}
</script>
Set displayOnLoad = false; if you want to wait the specified delay before loading the first image. The delay is set in seconds. I recommend waiting over a single second between images, as they may take some time to download (depending on the user's internet speed).
As with the first snippet, I haven't tested the code, so please tell me if an error occurs, and I will take a look.

Since you used the jquery tag on your question, I assume you are OK with using jQuery. In which case, you can do something like this:
In your static HTML, include the img tag and set its id to something (in my example, it's set to myImg) and set its src attribute to the first image, e.g.:
<img id="myImg" src="images/one.png">
Next, use jQuery to delay execution of your script until the page has finished loading, then use setTimeout to create a further delay so that the user can actually spend a few seconds looking at the image before it changes:
<script>
var imgTimeoutMsecs = 5000; // Five seconds between image cycles
$(function() {
// Document is ready
setTimeout(function() {
// We will get here after the first timer expires.
// Change the image src property of the existing img element.
$("#myImg").prop("src", "images/two.png");
setTimeout(function() {
// We will get here after the second, nested, timer expires.
// Again, change the image src property of the existing img element.
$("#myImg").prop("src", "images/three.png");
}, imgTimeoutMsecs);
}, imgTimeoutMsecs);
});
</script>
Of course, that approach doesn't scale very well, so if you are using more than three images total, you want to modify the approach to something like this:
var imgTimeoutMsecs = 5000; // Five seconds between image cycles
// Array of img src attributes.
var images = [
"images/one.png",
"images/two.png",
"images/three.png",
"images/four.png",
"images/five.png",
];
// Index into images array.
var iCurrentImage = 0;
function cycleImage() {
// Increment to the next image, or wrap around.
if (iCurrentImage >= images.length) {
iCurrentImage = 0;
}
else {
iCurrentImage += 1;
}
$("#myImg").prop("src", images[iCurrentImage]);
// Reset the timer.
setTimeout(cycleImages, imgTimeoutMsecs);
}
$(function() {
// Document is ready.
// Cycle images for as long as the page is loaded.
setTimeout(cycleImages, imgTimeoutMsecs);
});
There are many improvements that can be made to that example. For instance, you could slightly simplify this code by using setInterval instead of setTimer.

The code you've provided simply iterates through the for loop, writing the images to the browser as it does so. I suggest you take a look at JavaScript setTimeout function.
JS Timing

Related

Cycling images with javascript

Why doesn't the second (hawk) image appear when the button is clicked? It goes straight to the else statement showing the ant image.
<!DOCTYPE html>
<html>
<body>
<script>
function changeImg() {
if (document.getElementById("cycle").src == "fox.jpg") {
document.getElementById("cycle").src = "hawk.jpg";
} else {
document.getElementById("cycle").src = "ant.jpg";
}
}
</script>
<button onclick = "changeImg()">change image</button>
<img id ="cycle" src ="fox.jpg"/>
</body>
</html>
Please add your script tags at the end of the body to make sure that your dom is rendered before accessing any elements. (like in my example)
The problem with your code is, that you need to add a new if for every new image you add. As you noticed yourself, it becomes hard to understand and debug.
For something like cycling, use an array and modulo operation on the index of that array.
With this solution, you can add as many images to the images array as you like, without touching the code/logic;
<!DOCTYPE html>
<html>
<body>
<button onclick="changeImg()">change image</button>
<img id="cycle" />
<script>
var imageElement = document.getElementById("cycle");
var images = ["fox.jpg", "hawk.jpg", "ant.jpg"]; // add as many images as you want
var counter = 0;
imageElement.src = images[counter] // set the initial image
function changeImg() {
counter = (counter + 1) % images.length;
imageElement.src = images[counter];
}
</script>
</body>
</html>
document.getElementById("cycle").src always has full url of image (example:https://example.loc/example/fox.jpg) and this is not similar from fox.jpg.
You need try another solution.Try use
cycle.getAttribute('src')
Example code:
function changeImg() {
let cycle = document.getElementById("cycle");
console.log(cycle.src,cycle.getAttribute('src')); // show real value and taribute
if (cycle.getAttribute('src') == "fox.jpg") {
cycle.src = "hawk.jpg";
} else {cycle.src = "ant.jpg";
}
}
Use getAttribute('src') if you want to access the actual contents of the attribute. Otherwise you get the resolved URL.
var cycle = document.getElementById("cycle");
if (cycle.getAttribute('src') == "fox.jpg") {
cycle.src = "hawk.jpg";
} else {
cycle.src = "ant.jpg";
}

Execute js after all image loaded not working

(not duplicate, because not find exactly/easy solution)
I'm trying to execute JS after all images completely loaded. My goal is, when all images finish load completely, then removeClass my-loader and addClass visible to main-slider div.
HTML:
<div class='main-slider my-loader'>
<img src="https://unsplash.it/200/300/">
<img src="https://unsplash.it/200/300/">
<img src="https://unsplash.it/200/300/">
</div>
Execute below js when all images completely loaded
$(".main-slider").removeClass("my-loader").addClass("visible");
Tried this js :
But not works properly on my site, problem is when i clear browser cache, then it works/execute! when i reload page then next time it's not works/execute! It only works when i clear browser cache.
var img = $('.main-slider img')
var count = 0
img.each(function(){
$(this).load(function(){
count = count + 1
if(count === img.length) {
$('.main-slider').removeClass('my-loader').addClass('visible')
}
});
});
Any simple solution? Thanks in advance.
jQuery provides a way to register a callback for the window load event which will fire when the entire page, including images and iframes, are loaded.
Reference: https://learn.jquery.com/using-jquery-core/document-ready/
Your code should look something like:
$( window ).load(function () {
var img = $('.main-slider img')
var count = 0
img.each(function(){
$(this).load(function(){
count = count + 1
if(count === img.length) {
$('.main-slider').removeClass('my-loader').addClass('visible')
}
});
});
});
Here's how to do this, using Deferreds and native handlers, and calling the onload handler if the image is cached in older browsers etc.
var img = $('.main-slider img');
var defs = img.map(function(){
var def = new Deferred();
this.onload = def.resolve;
this.onerror = def.reject;
if (this.complete) this.onload();
return def.promise();
});
$.when.apply($, defs).then(function() {
$('.main-slider').removeClass('my-loader').addClass('visible')
});

Using JQuery to create animation frames from PSD layers

I have a PSD file with a bunch of layers that are frames for an animation. How can I create an animation from this using JQuery/JavaScript?
Will I have to save each layer as a separate image, is there a way to have the one image with multiple layers animated? To clarify, I don't want the actual image to move, I just want different layers to be displayed as if they were frames of an animation. What's the standard way this is done with JavaScript?
Thanks!
Here is a fiddle that demonstrates the javascript timer + individual images approach.
Fiddle: http://jsfiddle.net/ZVFu8/2/
The basic idea is to create an array with the names of your images.
var img_name_arr = [];
var img_name_root = "anim-";
var img_name_ext = ".gif";
var num_images = 12;
// init arr of img names assuming frames are named [root]+i+[extension]
for (i = 0; i<=num_images; i++) {
img_name_arr.push(img_name_root + i + img_name_ext);
}
For the animation, use setInterval(). In javascript, an interval executes periodically. You specify the code to execute and the interval at which the code should be run (in milliseconds).
Every time your interval is called, you can display a new image by setting the "src" attribute of the image tag to the next index in the image_name array.
// Create an interval, and save a handle to the interval so it can be stopped later
anim_interval = setInterval(function() {
$("#player").attr("src", s + img_name_arr[(anim_frame++ % num_images)+1] );
}, frame_interval);
Depending on how long your animation is and how large each image file is, it might be necessary to optimize this by pre-loading these images. Before the animation starts, you could create an img tag for each image and hide it. Then, instead of altering the "src" attribute to change the image, you would actually hide the current image and un-hide the next image in the previous image's place.
Here is the full code if you wish to run this locally:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<a id="anim_control" href="">Start</a>
<img id="player" src="" />
<script>
var s = "http://" + atob("YmVucmlkb3V0LmNvbQ==") + "/";
var img_name_arr = [];
var img_name_root = "anim-";
var img_name_ext = ".gif";
var num_images = 12;
var framerate = 1; // Desired frames per second
var frame_interval = 1000/framerate;
$(function(){
// Document is ready
// init arr of img names
for (i = 0; i <= num_images; i++) {
img_name_arr.push(img_name_root + i + img_name_ext);
}
var anim_interval = null;
var playing = false;
var anim_frame = 0;
// Define an interval that will execute every [frame_interval] milliseconds
$("#anim_control").on("click", function(e) {
e.preventDefault();
if (playing == true) {
playing = false;
$(this).html("Start");
clearInterval(anim_interval);
} else {
playing = true;
$(this).html("Stop");
anim_interval = setInterval(function() {
//console.log(s + img_name_arr[(anim_frame++ % num_images)+1]);
$("#player").attr("src", s + img_name_arr[(anim_frame++ % num_images)+1] );
}, frame_interval);
}
});
});
</script>
<style>
#player {
width: 320px;
height: 240px;
border: 1px solid #000;
}
</style>

javascript preloader/progress/percentage

I'm having trouble finding any good information on how to make a javascript(or jquery) progress bar WITH text that tells you the percentage.
I don't want a plug in, I just want to know how it works so that I can adapt it to what I need. How do you preload images and get a variable for the number of images that are preloaded. Also, how do you change html/css and-or call a function, based on the number of images that are loaded already?
<img> elements have an onload event that fires once the image has fully loaded. Therefore, in js you can keep track of the number of images that have loaded vs the number remaining using this event.
Images also have corresponding onerror and onabort events that fire when the image fails to load or the download have been aborted (by the user pressing the 'x' button). You also need to keep track of them along with the onload event to keep track of image loading properly.
Additional answer:
A simple example in pure js:
var img_to_load = [ '/img/1.jpg', '/img/2.jpg' ];
var loaded_images = 0;
for (var i=0; i<img_to_load.length; i++) {
var img = document.createElement('img');
img.src = img_to_load[i];
img.style.display = 'hidden'; // don't display preloaded images
img.onload = function () {
loaded_images ++;
if (loaded_images == img_to_load.length) {
alert('done loading images');
}
else {
alert((100*loaded_images/img_to_load.length) + '% loaded');
}
}
document.body.appendChild(img);
}
The example above doesn't handle onerror or onabort for clarity but real world code should take care of them as well.
What about using something below:
$('#btnUpload').click(function() {
var bar = document.getElementById('progBar'),
fallback = document.getElementById('downloadProgress'),
loaded = 0;
var load = function() {
loaded += 1;
bar.value = loaded;
/* The below will be visible if the progress tag is not supported */
$(fallback).empty().append("HTML5 progress tag not supported: ");
$('#progUpdate').empty().append(loaded + "% loaded");
if (loaded == 100) {
clearInterval(beginLoad);
$('#progUpdate').empty().append("Upload Complete");
console.log('Load was performed.');
}
};
var beginLoad = setInterval(function() {
load();
}, 50);
});
JSFIDDLE
You might also want to try HTML5 progress element:
<section>
<p>Progress: <progress id="p" max=100><span>0</span>%</progress></p>
<script>
var progressBar = document.getElementById('p');
function updateProgress(newValue) {
progressBar.value = newValue;
progressBar.getElementsByTagName('span')[0].textContent = newValue;
} </script>
</section>
http://www.html5tutorial.info/html5-progress.php

How to create a rotating thumbnails functionality in jQuery?

Basically I need the thumbnails to rotate every time the user hovers over an image. Here is my failed attempt:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$('img').hover(function() {
theImage = $(this).attr('id');
otherImages = $(this).attr('class').split('#');
rotateThumbs(otherImages, theImage);
}, function() {
//
});
});
function rotateThumbs(otherImages, theImage) {
for (i=0; i < otherImages.length; i++) {
setInterval($('#'+theImage).attr('src', otherImages[i]), 1000);
}
}
</script>
<img id="myImage" src="http://www.google.com/images/logos/ps_logo2.png" class="http://www.google.com/images/logos/ps_logo2.png#http://l.yimg.com/a/i/ww/met/yahoo_logo_us_061509.png#http://dogandcat.com/images/cat2.jpg" width="174" height="130" />
Does anyone know how this may be accomplished?
Some issues here.
setInterval requires a function reference as it's first argument, but you are executing code that returns a jQuery object.
setInterval executes the first function repeatedly at the specified interval. Is that what you are trying to do? Swap images every second?
Depending on how you correct the first issue, you could run into an issue where i is otherImages.length and thus the src is set to undefined.
Assuming you worked around issue 3, you will have the problem that the image swaps will happen imperceptibly fast and it will appear as though the last image is always displayed.
Instead, don't use a loop. Increment a counter each time a new image is displayed. Try this:
function rotateThumbs(otherImages, theImage) {
var i = 0;
var interval = setInterval(function() {
$('#'+theImage).attr('src', otherImages[i++]);
if (i >= otherImages.length) {
clearInterval(interval);
}
}, 1000);
}
I've implemented a fully-functional example here. This addresses some of the issues that #gilly3 notes, but uses closures instead of an incrementing counter to keep track of the current image:
$(function() {
$('img').hover(function() {
// declaring these variables here will preserve
// the references in the function called by setInterval
var $img = $(this),
imageList = $img.attr('class').split('#'),
intervalId;
// start the cycle
intervalId = window.setInterval(function() {
var next = imageList.pop();
if (next) {
$img.attr('src', next);
} else {
// stop the cycle
intervalId = window.clearInterval(intervalId);
}
}, 1000);
}, function() {});
});
As you can see, using a closure is much easier when you declare the function passed to setInterval inline, rather than as a separate, named function. You could still have a rotateThumbs function if you wanted, but you might need to do some more work to ensure that the variables were being passed properly.
Edit: I made an updated version that continues to cycle as long as the mouse is hovering.
I have adjusted the answer for Sam, taking pre-loading the image into account, so that you won't have a possible deplay at the first rotation.
function rotateThumbs(otherImages, theImage) {
if(!$('#'+theImage).data('setup')){
$('#'+theImage).data('setup', true); // do not double pre-loading images
var $body = $('body');
for(var j = 0; j < otherImages.length; j++){
$body.append($('<img/>').attr('src', otherImages[j])
.css('display', 'none'));
}
}
var i= 0;
setInterval(function(){
$('#'+theImage).attr('src', otherImages[i++]);
if(i >= otherImages.length){i = 0}
}, 1000);
}

Categories