Javascript/jQuery change <img src=" "> onclick with loop - javascript

I am creating kind of a slideshow in jQuery and on each click of the next button, I need the image src to increase. The file names of the images are 1,2,3,4,5,6,7,8,9,10,11, so I tried using a for loop. But since I'm no javascript/jquery guru, I can't think of other ways to solve my issue and make it actually work.
With my code, nothing happens at all.
This is what I've tried:
$('#right_arrow').click(function()
{
for (i = 1; i <= 11; i++)
{
$('#produkti').attr('src', 'style/images/produktet/' + i + '.gif');
}
});
And this is the actual html for the image:
<img src="style/images/produktet/1.gif" alt="Produkti 1" id="produkti" />

you can not assign one id to same 11 images, it will never work, jquery/javascript will always pick the first element with specified id.
You should use class and pick image element by index.
$('#right_arrow').click(function()
{
for (i = 1; i <= 11; i++)
{
$('.produkti').get(i-1).attr('src', 'style/images/produktet/' + i + '.gif');
}
});
and html here:
<img src="style/images/produktet/6.gif" alt="Produkti 6" class="produkti" />

The logic is - Every time you click that button, the index will return to 1.
for (i = 1; i <= 11; i++)
What you'll need to do, is have a global variable .. say var imgIndex Then, your code should be -
// somewhere ABOVE.. probably the head tag...
var imgIndex = 0;
$('#right_arrow').click(function()
{
$('#produkti').attr('src', 'style/images/produktet/' + imgIndex + '.gif');
imgIndex++;
});
Keep in mind you'll have to reset this imgIndex value when it reaches max.

This is a way to do this with an "auto loop" (when right arrow is clicked and current image is number 11, current image will be number 1)
var current = 6;
$('#right_arrow').click(function()
{
current = (current + 1 <= 11) ? (current + 1) : (1);
$('#produkti').attr('src', 'style/images/produktet/' + current + '.gif');
});

Here's an idea with data tags.
HTML:
<img src="style/images/produktet/1.gif" data-slide="1" data-max="9"/>
JS:
$("#right_arrow").click(function(){
var img = $("#produkti");
var slide = img.data().slide;
var max = img.data().max;
if(slide <= max){
slide ++;
img.attr('src', 'style/images/produktet/' + slide + '.gif');
img.data().slide = slide;
}
});

Related

How To Wait Image Until Complete Loaded to perform the next operation

i'm facing a big problem here every time i call this javascript function it does not wait until the left and right images to load but it goes immediatly to the next operation and what i want is to stop until left and right image to load the image perfectly then it goes to syllable_text.html(slice.The_Syl); line
function showImagesByPairAtInterval(Syllables, interval, index) {
index = index || 0;
let slice = Syllables[index];
left.attr('src', "http://example.com/"+ slice.Url1);
right.attr('src', "http://example.com/"+ slice.Url2);
syllable_text.html(slice.The_Syl);
nextIndex = index + 1;
if (nextIndex <= Syllables.length - 1) {
setTimeout(showImagesByPairAtInterval.bind(
null,
Syllables,
interval,
nextIndex
), interval);
}
}
Here how i call this function
showImagesByPairAtInterval(syllables.Syllables, 3000);
and here the tow images
<div id="images" style="display: flex;">
<img src="" id="left_image" name="left_image" alt="" />
<img src="" id="right_image" name="right_image" alt="" />
</div>
Updated Script
after using ImagesLoaded Script which i found in ImagesLoaded
like
function showImagesByPairAtInterval(Syllables, interval, index) {
index = index || 0;
let slice = Syllables[index];
left.attr('src', "http://deaf-api.azurewebsites.net/"+ slice.Url1);
right.attr('src', "http://deaf-api.azurewebsites.net/"+ slice.Url2);
while (!$("#images").imagesLoaded().always()) {
}
syllable_text.html(slice.The_Syl);
nextIndex = index + 1;
if (nextIndex <= Syllables.length - 1) {
setTimeout(showImagesByPairAtInterval.bind(
null,
Syllables,
interval,
nextIndex
), interval);
}
}
it seems like it doesn't really care when all the images really finish loading i assume that there is a second way to use this script
OK i want to post the solution for this problem since what i think that ImagesLoaded Script maybe confused about neither the left and right images were loaded or not so i decide to make new images which i can tell it's not being yet loaded and after i check it's loaded i change left and right images like this
function showImagesByPairAtInterval(Syllables, interval, index) {
index = index || 0;
let slice = Syllables[index];
var left_img = new Image();
var right_img = new Image();
var div_img = document.createElement('div');
var $div_img = $("<div>");
$div_img.append(left_img);
$div_img.append(right_img);
left_img.src = "example.com/" + slice.Url1;
right_img.src = "example.com/" + slice.Url2;
while (!$div_img.imagesLoaded().done()) {
}
left.attr('src', "http://example.com/" + slice.Url1);
right.attr('src', "http://example.com/" + slice.Url2);
syllable_text.html(slice.The_Syl);
nextIndex = index + 1;
if (nextIndex <= Syllables.length - 1) {
setTimeout(showImagesByPairAtInterval.bind(
null,
Syllables,
interval,
nextIndex
), interval);
}
}

Change Image on click (6 Image Loop)

I have 6 images that I want to swap between by clicking on the image but I can't seem to get the code right in order to make it go to the next picture
HTML
<img src="BCover.jpg" id="ImgGallery" onclick="ImgGallery()"/>
JavaScript
var counter = 1;
ImgGallery.onclick = function (){
if (counter == 1){
document.getElementById("ImgGallery").src = "BCover.jpg";
counter++;
}
else if (counter == 2){
document.getElementById("ImgGallery").src = "MechGP.jpg";
counter++;
}
else if (counter == 3){
document.getElementById("ImgGallery").src = "Mech2.jpg";
counter++;
}
else if (counter == 4){
document.getElementById("ImgGallery").src = "Mech3.jpg";
counter++;
}
else if (counter == 5){
document.getElementById("ImgGallery").src = "Mech4.jpg";
counter++;
}
else if (counter == 6){
document.getElementById("ImgGallery").src = "MCA1.png";
counter==1;
}
};
The problem (other than Spencer's comment about == assignment) seems to be that ImgGallery should be the name of a function, not a reference to the element, as it's being called as a function in the onclick attribute of your img element.
I renamed the ImgGallery() function to rotateGallery to eliminate ambiguity with the id of the element.
I also took some liberty to clean up your code a little by using array cycling instead of a switch statement to handle img gallery rotation.
<img src="BCover.jpg" id="ImgGallery" onclick="rotateGallery()"/>
var counter = 0,
gallery = ["BCover.jpg", "MechGP.jpg", "Mech2.jpg", "Mech3.jpg", "Mech4.jpg", "MCA1.png"],
rotateGallery = function () {
document.getElementById("ImgGallery").src = gallery[counter];
counter++;
if (counter >= gallery.length) {
counter = 0;
}
};
This can be DRYed up a bit. You can include all of your images in an array. JavaScript does not have a native cycle method but you can implement it with the following algorithm.
var images = ["BCover.jpg", "MechGP.jpg", "Mech2.jpg", "Mech3.jpg", "Mech4.jpg", "MCA1.png"];
var gallery = document.getElementById("ImgGallery");
var index = 0;
gallery.addEventListener("click", function() {
gallery.src = images[index];
index = (index === images.length - 1) ? 0 : index + 1;
});
I know the last statement inside the click listener may seem weird, but I wanted to write as little code as possible.
ImageGallery isn't a function, which will cause an error.
However, the main error is counter==1;, on the third last line. The == operator is for testing if a value has equal value (not necessarily equal type though), but for assignment, use the normal = operator.
Try this:
//First, create an array of images (so you can support as many images in the gallery as needed, only needing to update this array)
var images = ["BCover.jpg", "MechGP.jpg", "Mech2.jpg", "Mech3.jpg", "Mech4.jpg", "MCA1.png"],
//and a counter to loop through
c = 0;
//this function is triggered when the image is clicked on sending the image element as a parameter
function nextImg(elem){
//if c is less than the array's length - 1, then add 1 to c, otherwise make c equal 0
c = (c != images.length - 1) ? c + 1 : 0;
//actually change the src attribute of the image
elem.src = images[c];
//and just let you know what image you're up to
document.getElementsByTagName('p')[0].innerHTML = 'Image no. '+(c+1)+'. File name of image: '+images[c];
}
/* Make the image visible */
img{
cursor: pointer;
height: 50px;
width: 50px;
}
<img id='ImageGallery' onclick='nextImg(this)' />
<p>Notice the onclick attribute</p>

Uncaught TypeError: Cannot set property 'src' of undefined

url: http://www.gws-mbca.org
The slide show works in Firefox. It used to work in IE and Chrome. Now I get the following error in both IE and Chrome:
Uncaught TypeError: Cannot set property 'src' of undefined
The script is linked using a <script type="...> in the document head.
The code in the web page is as follows:
<section style="margin: 0 auto; text-align: center;">
<img src="./rPix/rp1.jpg" id="slide" width="900" height="200" alt="slide show images" />
</section>
<body onload="runShow();">
The function runShow is part of slideshow.js - Code is as follows:
/* An automatically rotating slide show using Javascript and the DOM.
This script cobbled together by Paul D.J. Vandenberg */
var j = 1;
var pix = new Array(11);
for (i = 0; i < pix.length; i++) {
pix[i] = "rPix/rp"+j+".jpg";
j++;
}
var index = Math.floor(Math.random() * 11) + 1;
var limit = pix.length - 1;
function runShow() {
if (index > limit) {
index = 0;
}
document.slide.src = pix[index];
setTimeout("runShow()", 10000);
index++;
}
Make sure you call runShow() after the id="slide" element has been added to the DOM.
document.slide is shorthand for document.getElementById("slide"). The latter will return null when no element with that id is defined.
The DOM must be loaded before the document can access any elements. Usually an onload event is used when the script is in the <head>
window.onload = function(){
var j = 1;
var pix = new Array(11);
for (i = 0; i < pix.length; i++) {
pix[i] = "rPix/rp"+j+".jpg";
j++;
}
var index = Math.floor(Math.random() * 11) + 1;
var limit = pix.length - 1;
window.runShow = function() {
if (index > limit) {
index = 0;
}
document.slide.src = pix[index];
setTimeout("runShow()", 10000);
index++;
}
};
"The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading." -MDN
Suggested improvements
I thought I would throw this part in because there are few things I think you can improve here as far as your approach and decided to offer some suggestions.
Lets remove body onload="runShow()" from your code and make it just <body> or whatever other class etc you might have on there.
Lets also go in and use an interval instead of a timeout because for longrunning processes they are more accurate.
Also, lets try to remove all strings from the callbacks.
Example:
<html>
<head>
window.onload = function(){
var pix = [];//array to hold image source strings
var limit = 10;//0 based count for images
for( var i = 0; i < limit+1; i++ ){//runs 11 times
pix.push("rPix/rp"+(i+1)+".jpg";//push incrementally adds to pix array
}
var index = limit;//last index for image source in pix array
var slide = document.getElementById("slide");//cache slide image element
function runShow(){
if( index > limit ) index = 0;//cycle images by array length
slide.src = pix[index++];//change slide image using cached element
}
runShow();//run on load
setInterval(runShow,10000);//run every 10 seconds
};
</head>
<body>
<section style="margin: 0 auto; text-align: center;">
<img src="./rPix/rp1.jpg" id="slide" width="900" height="200" alt="slide show images" />
</section>
</body>
</html>
So here's what the code looks like now.
/* An automatically rotating slide show using Javascript and the DOM.
This script cobbled together by Paul D.J. Vandenberg with a nice
assist from stackoverflow */
window.onload = function() {
var j = 1;
var pix = new Array(11);
for (i = 0; i < pix.length; i++) {
pix[i] = "rPix/rp"+j+".jpg";
j++;
}
var index = Math.floor(Math.random() * 11) + 1; // Start at a random slide
var limit = pix.length - 1;
var slide = document.getElementById("slide"); // Cache slide image element
function runShow() {
if (index > limit) {
index = 0;
}
slide.src = pix[index++];
}
setInterval(runShow, 10000); // Interval more reliable than timeOut
runShow();
}

Turning Javascript into jQuery

Hi there Stack Overflow,
I'm new at learning jQuery and just trying to condense some sample code down, how would I go about the following.
On mouseover of #navweb, select all elements with a class of .web and then change the background of each of these elements to url(back/"+ i +".png) where i is the JS loop, and then fadeIn these new backgrounds.
Here's the JS i have at current which works (except for the fadeIn)
function showweb() {
for(var i=1; i < 45; i++){
var el = document.getElementById("im"+(i));
if(el && /web/.test( (el ||{}).className)){
el.style.backgroundImage = "url(back/"+ i +"col.png)";}
}
}
function hideweb() {
for(var i=1; i < 45; i++){
var el = document.getElementById("im"+(i));
if(el && /web/.test( (el ||{}).className)){
el.style.backgroundImage = "url(back/"+ i +".png)";}
}
}
I started and got to something like this but it doesn't work, becasue i know its not complete, can you use counters in jQuery?
$('#navweb').mouseover(function(){
var i = 1;
$(".web").each(function(){
$(this).css('background-image', 'url(back/" + i + ".col.png)');
i += 1;
});
});
Many thanks to all replies.
EDIT:
Thanks to all replies, Guffa's proved the most ideal and condensed for my use; I have also added the fadeIn() method but doesn't seem to be triggering on the mouseover?
$('#navweb').mouseover(function(){
$(".web").each(function(){
var i = parseInt(this.id.substr(2));
$(this).css('background-image', 'url(back/' + i + 'col.png)').fadeIn(1000);
});
});
You can get the number from the id of the element:
$('#navweb').mouseover(function(){
$(".web").each(function(){
var i = parseInt(this.id.substr(2));
$(this).css('background-image', 'url(back/' + i + '.col.png)');
});
});
You had a small mistake here: 'url(back/" + i + ".col.png)', it should be like I wrote bellow with single quotes.
$('#navweb').mouseover(function(){
var i = 1;
$('.web').each(function(){
$(this).css('background-image', 'url(back/' + i + '.col.png)');
i += 1;
});
});

Background-image won't change using jquery in IE6

There is a panel on my page with no default background-image css. On load it is set with jquery to an initial image, waits for 10 seconds then loads a random image out of some predetermined images. There are previous and next buttons which allow you to cycle through the images. In ie6 the initial image loads and then a random image also loads after 10 seconds, however pressing prev/next causes the background to become white and the images aren't loaded. With alerts I was able to find that it's still keeping track of the position and url of the image it's supposed to load, but just won't load it. Here is the code below.
<script type="text/javascript">
var facts = new Array();
var position;
$(document).ready(function() {
<xsl:for-each select="$currentPage/ancestor-or-self::node[#level=1]/../node[#nodeName='Fun Fact Folder']/node">
facts[<xsl:value-of select="position()" />] = '<xsl:value-of select="." />';
</xsl:for-each>
if(window.location.pathname == "/homepage.aspx" || window.location.pathname == "/") {
$(".fun_facts_bg").css("background-image", "url(images/fun_fact_homepage.JPG)");
setTimeout("randomFact()",10000);
} else {
randomFact();
}
});
function randomFact() {
$("a.previous_button").css("display", "block");
$("a.next_button").css("display", "block");
position = Math.ceil(Math.random() * (facts.length - 1));
changeFact(0);
}
function changeFact(increment) {
position = checkPosition(position, increment);
$(".fun_facts_bg").css("background-image", "url(" + facts[position] + ")");
}
<xsl:text disable-output-escaping="yes"><!--//--><![CDATA[//><!--
function checkPosition(currentPos, increment) {
currentPos = currentPos + increment;
if (currentPos > facts.length - 1) {
currentPos = 1;
} else if (currentPos < 1) {
currentPos = facts.length - 1;
}
return currentPos;
}
//--><!]]></xsl:text>
</script>
<a class="previous_button" href="javascript:void(0);" onclick="changeFact(-1);">
<a class="next_button" href="javascript:void(0);" onclick="changeFact(1);">
I'm pretty sure you should be using a modulus somewhere to ensure that you stay within the intended range. That may help.

Categories

Resources