How to increment jQuery variable? - javascript

I'm trying to browse through a picture gallery with jquery, so I have a button which is supposed to increment a variable by 1 and then use that to load the next picture.
Using the top answer on this SO question, I thought this would be the solution:
<div id="pic"></div>
<div id="browse-right">NEXT</div>
<%= image_tag("/1.JPG", id:"1") %>
<%= image_tag("/2.JPG", id:"2") %>
<%= image_tag("/3.JPG", id:"3") %>
$("#1").click(function() {
var x = 1;
$("#pic").html('<img src="/' + x + '.JPG" />');
});
$("#2").click(function() {
var x = 2;
$("#pic").html('<img src="/' + x + '.JPG" />');
});
$("#3").click(function() {
var x = 3;
$("#pic").html('<img src="/' + x + '.JPG" />');
});
//...
$("#browse-right").click(function() {
x = x + 1;
$("#pic").html('<img src="/' + x + '.JPG" />');
});
But it just reloads the same picture, which means var x doesn't change. Anyone know the proper syntax?
UPDATE: Okay, I think I've figured out the problem. x is set when a picture is clicked on, and apparently it isn't persisting after the function is complete. I didn't include that part in the original code because I thought it would make the whole thing more complicated to read.....lesson learned. How can I get x to persist after the function it is set in?

How can I get x to persist after the function it is set in?
Try defining x outside of and before click handler
var x = 1;
$("body").on("click", function() {
x = x + 1;
$(this).html(x)
})
body {
width: 300px;
height: 300px;
border: 1px solid purple;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
click

Your code looks ok. and here's a working version https://jsfiddle.net/a50nz178/1/
A couple of things you could check:
check that the image is actually there /1.JPGas well
check that images are not all named as jpg all lower case?

If I had to guess, looking at your previous You've updated. Turns out I was right. Your x was out of scope. correct code, I'd bet your problem is scope. Scope Tutorial
I'm willing to bet, somewhere else in your code your using something like for(x in ; ... Which is reassigning x. If that's not the case, I'd still bet on either scope, or the image is src isn't correct. You should use your developer console to check if a bad image source is being pulled. Your using / at the begining of your img src which will go back to base path. If you images are in an images folder you need to include the proper directory path.
You could easily shorten the scope of this by attaching your increment variable to your element object like so:
$("#browse-right").click(function(e) {
// the following is a simple inline `if` statement
// what it says is (this is your element)
// if this.i does not exist, create it equal to one,
// else count it up once
!this['i'] ? this.i=1: this.i++;
$("#pic").html('<img src="/' + this.i + '.JPG" />');
// the following simply shows what `i` currently is
$('h3').text(this.i);
});
p { cursor: pointer; background: #aabb00; padding: 1em .5em; text-align: center; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p id="browse-right">Browse Right</p>
<h3></h3>
<div id="pic">
IMG HERE
</div>

Related

Can't Toggle Through Images With JQuery Function

I'm trying to write a function that upon each button click, it changes the shape of the triangle.
I'm a novice, and I could probably do this quicker with toggle() but I want to get better at writing functions because it's holding me back. Any help would be appreciated. You don't have to give me the answer, but a point in the right direction would be so appreciated! Thank you.
I have the first two shapes but I don't know how to bring in the last two.
https://jsfiddle.net/gs0c30vd/2/
$(document).ready(function(){
$("#tri").click(function(){
$('#triangleup').hide();
$('#triangleright').show();
}) ;
});
A very simple and small jQuery script can do it like below - the only requirement for this is that you add the same class to the elements (see HTML beneath):
$(document).ready(function(){
// declare the first element in the range w. respect to the order of the HTML
var firstElement = $(".firstTriangle");
// declare the last element in the range here to reset the "loop" of elements
var lastElement = $(".lastTriangle");
$("#tri").click(function() {
if ($(lastElement).is(":hidden")){
$(".triangle").filter(":visible").hide().next().show();
} else {
$(lastElement).hide();
$(firstElement).show();
};
});
// ------------------------------------------------------------
// The original uni-directional method is above.
// Beneath I have added "support" for a bi-directional method;
// i.e. going either up or down in the HTML
// ------------------------------------------------------------
$("#counterclockwise").click(function() {
if ($(firstElement).is(":hidden")){
$(".triangle").filter(":visible").hide().prev().show();
} else {
$(firstElement).hide();
$(lastElement).show();
};
});
});
You can check it out in this fiddle. The real benefit of this little method is that you dont have to declare every element in the range which you would like to show. If you apply it for a slider with a lot of images it gets tiresome to type in every element (at least in my opinion); and especially if you change some of the elements. To make this method even easier to maintain you could just use some fixed classes which you always hold as the first and last element; such as "firstTriangle" and "lastTriangle" and then adjust the variables accordingly. I've also added this approach to the script and the HTML for future reference and ease-of-use.
However the drawbacks should also be noted:
You must have your elements which u wish to toggle inside a container with no other siblings (such as shown in the HTML). Otherwise it will move on to other elements and showing/hiding these, thereby breaking the function.
There can only be one direction in which you switch between the elements (downwards in the HTML document).
However, with regard to the unidirectional "drawback" you could easily reverse the function and add another button to make up for this. Such an example can be seen here: Change slides/elements in both directions.
This effectively grants you a pretty much fully functional slider.
HTML:
<div class="myContainer">
<div id="triangleup" class="triangle firstTriangle"></div>
<div id="triangleright" style="display: none;" class="triangle"></div>
<div id="triangledown" style="display: none;" class="triangle"></div>
<div id="triangleleft" style="display: none;" class="triangle lastTriangle"></div>
</div>
<button id="tri">Click me to change the direction of the triangle</button>
<!-- Button for changing direction beneath -->
<button id="counterclockwise">Change direction <b>counter-clockwise</b></button>
Interpretation of the function:
If the last element in the range is hidden (we're not through the range yet) then find the visible one (.filter(":visible")) and hide it, and afterwards find its next (next()) sibling and show (show()) this.
However, if the last Element is visible (then you are at the end of the range), manually hide this and show the first element - thereby starting the range over again.
Note: Pardon my lengthy answer (although that might not be a bad thing) but this was also a learning process for me as well - I wasn't even aware that a "slideshow" effectively could be made that easy with jQuery until I found the .filter() parameter in connection with this question.
You can use a Switch statement to track the current position of the triangle from 0..3 like so:
$(document).ready(function() {
var rot = 0
$("#tri").click(function() {
switch (rot) {
case 0:
$('#triangleup').hide();
$('#triangleright').show();
rot += 1;
break;
case 1:
$('#triangleright').hide();
$('#triangledown').show();
rot += 1;
break;
case 2:
$('#triangledown').hide();
$('#triangleleft').show();
rot += 1;
break;
case 3:
$('#triangleleft').hide();
$('#triangleup').show();
rot = 0;
break;
}
});
});
If your html looks like this
<div id="container">
<div class="shape visible"></div>
<div class="shape"></div>
<div class="shape"></div>
<div class="shape"></div>
</div>
And your css class for .shape is display:none and .visible is display:block
Than your js can be
$("#tri").click(function() {
var current = $(".visible");
var options = $("#container");
var index = options.index(current);
$(".visible").removeClass("visible");
If(index<options.length -1){
options[index + 1].addClass("visible");
}else{
options[0].addClass("visible");
}
});
Forgive me for the typeos I did this on my phone.
One way to do it is to store the names of the shapes in an array then have some sort of counter that increases each time you click the button. The modulus/remainder from that counter as compared to the array length will enable you to loop through them.
Code example:
var index = 0
var shapeArr = [
'#triangleup',
'#triangleright',
'#triangledown',
'#triangleleft'
]
var len = shapeArr.length
$(document).ready(function(){
$("#tri").click(function(){
$(shapeArr[index % len]).hide();
$(shapeArr[++index % len]).show();
}) ;
});
$(document).ready(function(){
var count = 0;
$("#tri").click(function(){
if( count == 0)
{
$('#triangleup').hide();
$('#triangleright').show();
count++;
}
else if(count == 1)
{
$('#triangleright').hide();
$('#triangledown').show();
count++;
}
else if(count == 2)
{
$('#triangledown').hide();
$('#triangleleft').show();
count++;
}
else
{
$('#triangleleft').hide();
$('#triangleup').show();
count = 0;
}
}) ;
});
this is not a good way you make upon this
You can use a flag isUp to know the current status and negate it on every click
$(document).ready(function(){
var isUp = true;
$("#tri").click(function(){
if (isUp) {
$('#triangleup').hide();
$('#triangleright').show();
} else {
$('#triangleup').show();
$('#triangleright').hide();
}
isUp = !isUp;
}) ;
});
EDIT:
I have seen you have four triangles. If you want a full rotation, then you might want to do this:
$(document).ready(function(){
var directions = ["up", "right", "down", "left"];
var directionIndex = 0;
$("#tri").click(function(){
$("#triangle" + directions[directionIndex]).hide();
$("#triangle" + directions[directionIndex = ((directionIndex + 1) % directions.length)]).show();
}) ;
});
You could have an alternative solution using just a few lines of CSS and a small addition in your jQuery code. The point is to simply rotate the triangle by using CSS transform attribute.
Example using jQuery
$(document).ready(function() {
var degrees = 0;
$("#tri").click(function() {
degrees = degrees + 90;
$('#triangle').css("transform", "rotate(" + degrees + "deg)");
});
});
#triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="triangle"></div>
<br>
<button id="tri">Click me to change the direction of the triangle</button>
You can also check this out in this updated Fiddle.
Example using only Javascript
var degrees = 0;
var triangle = document.getElementById("triangle");
document.getElementById("tri").addEventListener("click", function() {
degrees = degrees + 90;
var style = triangle.style;
style.transform = "rotate(" + degrees + "deg)";
});
#triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<div id="triangle"></div>
<br>
<button id="tri">Click me to change the direction of the triangle</button>

Animate background image javascript not working

I want to achieve a background animate image, that moves from right to left, but the image won´t animate, could you help me verify my code?
<body>
<div id="background-container"></div>
<script> type="text/javascipt">
function animateBackground(elem, speed) {
var x = 0 ;
var y = -50;
elem.style.backgroundPosition = x + 'px' + ' ' + y + 'px';
var timer = setInterval (function(speed) {
elem.style.backgroundPosition = x + 'px' + ' ' + y + 'px';
x--;
if (x == -600) {
clearInterval(timer);
}
},speed)
}
document.addEventListener("DOMContentLoaded", animateBackground(document.getElementById('background-container'), 15), false);
</script>
</body>
Your code is quite ugly but actually it looks fine. What is definitely wrong is how you are adding the event handler. Instead of adding a handler function, you call your handler function inline, so it actually doesn't add any listener. You should pass the function itself, for example like this, using an anonymous function inline.
document.addEventListener("DOMContentLoaded", function() { animateBackground(document.getElementById('background-container'), 15); }, false);
You could have provided a jsfiddle link, which would have made it easy. By the way here is the working jsfiddle, https://jsfiddle.net/pmankar/4o88z0tt/
I added a css background to the div tag using
div{
background-image: url("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png");
height: 100px;
width: 600px;
border: 2px solid green;
}
Rest assured, I didn't do any changes to your js code or the html code. It worked fine for me.

Change Background Image Multiple Times JS

Everytime I click on body the background-image should change and repeat when the images are over. I tried this but doesn't work:
HTML
<body id="change-image">
</body>
JS
var images = ['../img/1.jpg', '../img/2.jpg', '../img/3.jpg', '../img/4.jpg'],
i = 0;
$("#change-image").click(function(){
$("body").css("background-image", images[i]);
i = (i==images.length-1) ? 0 : (i+1);
});
I think that code should work, but it doesn't. I tried with backgroudColor and it works perfectly, but with images is not happening. I would love if u help me please!
At some point you'll be increasing the counter out of the available number of background images so... (also by using properly url() like background-image:"url(image.jpg)")
do like:
var images = [
'http://placehold.it/500x320/07f',
'http://placehold.it/500x320/f70',
'http://placehold.it/500x320/7f0',
'http://placehold.it/500x320/0f7'
],
i = 0,
n = images.length;
$("#change-image").click(function(){
$("body").css({backgroundImage: "url("+ images[i++ % n] +")" });
});
html, body{height:100%;}
body{
background: red none 50% / cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="change-image">CHANGE</button>
The i++ % n will increment and loop-back your counter
You should use this
$("body").css("background-image", "url:('" + images[i] + "')");
background-image needs url like this:
$("#change-image").click(function(){
$("body").css("background-image", "url("+ images[i]+")");
i = (i==images.length-1) ? 0 : (i+1);
});

Loop with trigger (which contains animation) not working

So I seem to have run into a bit of a dead end. I'm making a page which has an image slider. The slider has three images, one centered on the screen, the other two overflow on the left and right. When you click on the button to advance the slides it runs this code....
$('#slideRight').click(function() {
if ($('.container').is(':animated')) {return false;}
var next=parseInt($('.container img:last-of-type').attr('id')) + 1;
if (next == 12) {
next = 0;
}
var diff = galsize() - 700;
if ($('.thumbs').css("left") == "0px") {
var plus = 78;
} else {
var plus = 0;
}
var app='<img id="' + next + '" src="' + imgs[next].src + '">';
$('.container').width('2800px').append(app);
$('.container').animate({marginLeft: (diff + plus) + "px"}, 300, function() {
$('.container img:first-of-type').remove();
$('.container').width('2100px').css("margin-left", (galsize() + plus) + "px");
});
}); // end right click
This works just fine, not a problem..... I also have an interval set up to run this automatically every 5 seconds to form a slideshow...
var slideShow = setInterval(function() {
$('#slideRight').trigger("click");
}, 5000);
This also works perfectly, not a problem.... However my problem is this.... I have thumbnails, when you click on a thumbnail, it should run this code until the current picture is the same as the thumbnail.... here is the code....
$('img.thumbnail').click(function() {
clearInterval(slideShow);
var src = $(this).attr("src");
while ($('.container img:eq(1)').attr('src') != src) {
$('#slideRight').trigger("click");
}
});
When I click on the thumbnail nothing happens... I've used alert statements to try and debug, what ends up happening is this....
The while loop executes, however nothing happens the first time. The slide is not advanced at all. Starting with the second execution, the is('::animated') is triggered EVERY TIME and the remainder of the slideRight event is not executed...
So my first problem, can anyone shed some light on why it doesn't run the first time?
And my second question, is there any way to wait until the animation is complete before continuing with the loop?
Any help would be appreciated. Thank you!
I'm going to start with the second part of your question, regarding completing the animation before continuing with the loop.
I have done something similar in the past, and what I did was set two global variables to control the animation. One variable is for how long you want the period to be, the other is a counter for how much time since the last loop.
So, for example:
$timeToChange = 5; // in Seconds
$timeSinceReset = 0; // also in Seconds
Set your interval for one second and call a new function (autoAdvance()):
var slideShow = setInterval(function() {
autoAdvance();
}, 1000); // only one second
and then use the counter variable to count each time the interval is called (each second). Something like:
function autoAdvance(){
if($timeSinceReset == $timeToChange){
$timeSinceReset = 0;
$('#slideRight').trigger("click"); // execute click if satisfied
}
else{$timeSinceReset++;}
}
To stop from looping until the animation is done, reset $timeSinceReset back to 0 (zero) when you click on the thumbnail. Something like:
$('#thumbnail').click(function(){
$timeSinceReset = 0;
});
That'll give you a nice 5 second buffer (or whatever you set $timeToChange) before the loop continues.
As for the first part of your question, grab the number of the particular thumbnail, and use that to scroll to the appropriate image. Something like:
$('.thumb').click(function (each) {
$childNumber = $(this).index();
});
which you cansee in this fiddle. Click in one of the grey boxes and it'll tell you which one you clicked in. Use that info to scroll to the appropriate image (1, 2 or 3 if you only have three images).
Hope this helps.
Here is a full solution for one possible way of doing it at this fiddle.
HTML:
The top container holds the images. In this particular example I've included three, using divs instead of images. Whether you use images or divs doesn't change anything.
<div class="holder_container">
<div class="img_container">
<div class="photo type1">ONE</div>
<div class="photo type2">TWO</div>
<div class="photo type3">THREE</div>
</div>
</div>
.img_container holds all the images, and is the same width as the sum of the widths of the images. In this case, each image (.photo) is 150px wide and 50px tall, so .img_container is 450px wide and 50px tall. .holder_container is the same dimensions as a single image. When this runs, the .holder_container is set to hide any overflow while .img_container moves its position left or right.
Included also are two nav buttons (forward and back)
<div class="nav_buttons">
<div class="nav back"><<<</div>
<div class="nav forward">>>></div>
</div>
As well as three thumbnail images - one for each image in the top container
<div class="top">
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
</div>
CSS:
Refer to the JS Fiddle for all CSS rules.
The most important are:
.holder_container {
margin: 0px;
padding: 0px;
height: 50px;
width: 150px;
position: relative;
overflow: hidden;
}
.img_container {
margin: 0px;
padding: 0px;
height: 50px;
width: 450px;
position: relative;
left: 0px;
top: 0px;
}
In the example, .type1, .type2 and .type3 are only used to color the image divs so you can see the animation. They can be left out of your code.
JavaScript:
The javascript contains the following elements…
Variables:
var timeToChange = 3; // period of the image change, in seconds
var timeSinceReset = 0; // how many seconds have passed since last image change
var currentImage = 1; // Which image you are currently viewing
var totalImages = 3; // How many images there are in total
Functions:
autoAdvance - called once every second via setInterval. Counts the number of seconds since the last image change. If the number of seconds that has passed is equal to the period, a function is called that switches the images.
function autoAdvance() {
if (timeSinceReset == timeToChange) {
timeSinceReset = 0;
moveNext();
} else {
timeSinceReset++;
}
}
moveNext() - moves to the next image. If the current image is the last (currentImage == totalImages) then currentImages is set back to 1 and the first image is displayed.
function moveNext(){
if(currentImage == totalImages){
currentImage = 1;
var newPos = 0 + 'px';
$('.img_container').animate({left: newPos}, 300);
}else{
currentImage++;
var newPos = -((currentImage-1) * 150) + 'px'; // child numbers are zero-based
$('.img_container').animate({left: newPos}, 300);
}
}
Rest of code:
If one of the thumbs is clicked, move to the corresponding image.
$('.thumb').click(function (each) {
timeSinceReset = 0;
var childNumber = $(this).index();
currentImage = childNumber + 1; // child numbers are zero-based
var newPos = -(childNumber * 150) + 'px'; // child numbers are zero-based
$('.img_container').animate({left: newPos}, 300);
});
If one of the navigation buttons is clicked, move accordingly. If "back" is clicked, move one image backwards (or to last image if currently on first). If "first" is clicked, move one image forwards (or to first image if currently on last).
$('.nav').click(function(){
timeSinceReset = 0;
if($(this).hasClass('back')){ // Back button
if(currentImage == 1){
currentImage = totalImages;
}else{
currentImage--;
}
}else{ // Forward button
if(currentImage == totalImages){
currentImage = 1;
}else{
currentImage++;
}
}
var newPos = -((currentImage-1) * 150) + 'px';
$('.img_container').animate({left: newPos}, 300);
});
Here is the link to the fiddle example.

Javascript - Browser skips back to top of page on image change

I have some simple code to replace an image src. It is working correctly but everytime the image is updated, the browser skips right back to the top of the page.
I have several image tags in my page. All of which hidden, except for the first one. The script just iterates through them and uses the src attribute to update the first image.
Here is the code I am using:
var j = jQuery.noConflict();
var count = 1;
var img;
function update_main_image()
{
count++;
if (j('#main_image_picture_'+count).length > 0)
{
img = j('#main_image_picture_'+count).attr('src');
}
else
{
count = 1;
img = j('#main_image_picture_'+count).attr('src');
}
j(".main_image_picture_auto").fadeOut(1500, function() {
j(this).fadeIn();
j(this).attr("src", img);
});
}
j(document).ready(function()
{
setInterval(update_main_image, 6000);
});
Any ideas what might be causing it?
Any advice appreciated.
Thanks.
Try to add DIV around your IMG.main_image_picture_auto with width and height style properties setted to maximum posible image size, for example:
<div style='width:400px; height:400px; border: 0px; background: transparent; '>
<img class='main_image_picture_auto' src=''/>
</div>
<!-- Where width:400px and height:400px is maximum allowed image size -->
And I think, that is better to use setTimeout instead of setInterval
function update_main_image() {
// ....
setTimeout(update_main_image, 6000);
}
j(document).ready(function() {
setTimeout(update_main_image, 6000);
});
http://jsfiddle.net/UBEWS/

Categories

Resources