jQuery / JavaScript Scope: Getting Variables Into and Out Of Functions - javascript

I have a simple image rotator script that I'm trying to build but I am having trouble learning scope as it relates to getting variables into and out of JavaScript functions.
Here is my code:
<script type="text/javascript">
jQuery(document).ready(function($) {
function indexUp () {
if (slide_curr == slide_max - 1) {
slide_curr = slide_max;
slide_prev = slide_max - 1;
slide_next = slide_min;
} else if (slide_curr == slide_max) {
slide_curr = slide_min;
slide_prev = slide_max;
slide_next = slide_min + 1;
} else {
slide_curr = slide_next;
slide_prev = slide_curr - 1;
slide_next = slide_curr + 1;
}
}
function doTransition () {
// turn on the display of the next slide
$(slides[slide_next]).css('display','block');
// fade the current slide out (to zero opacity)
$(slides[slide_curr]).fadeOut(600, function() {});
}
function printState () {
var state_str = 'slide_curr='
+ slide_curr
+ '; slide_prev='
+ slide_prev
+ '; slide_next='
+ slide_next
+ '; slide_max='
+ slide_max
+ '; slide_min='
+ slide_min;
$('#bx_state').html(state_str);
}
function doIt () {
doTransition();
indexUp();
printState();
}
// variables
var slides = $('#bx_slider img');
var slide_min, slide_max, slide_curr, slide_prev, slide_next;
// initialize the settings
slide_min = 0;
slide_max = slides.length - 1;
slide_curr = 0;
slide_prev = slide_max;
slide_next = 1;
// start it all off when the page loads
$(slides[slide_curr]).css('display','block');
timeout = setTimeout(doIt, 3000);
});
</script>
<style type='text/css'>
#bx_slider img {
display:none; position:absolute;}
#bx_slider {
width:922px; height:530px; margin:100px auto;
position:relative;}
</style>
<div id="bx_slider">
<img src="slide1.jpg" />
<img src="slide2.jpg" />
<img src="slide3.jpg" />
<img src="slide4.jpg" />
<img src="slide5.jpg" />
</div><!-- #bx_slider -->
<div id='bx_state'></div>
I'm trying to get the slide_curr, slide_next, and slide_prev to change each time the script is run and then print those out to the page in the div tag in an effort to see what is going on; however, even that is not working for me.
Here is the script in action: http://www.exit44.com/slider/
Thanks for the help.

I'm guessing here, but perhaps the problem has nothing to do with variable scope. You mention that you want to create a "simple image rotator". Try changing
timeout = setTimeout(doIt, 3000);
to
timeout = setInterval(doIt, 3000);

Related

How to make clearInterval() work in JavaScript

I want to make an element (id=runner) move across the page by n pixels after a mouseover event, then stop at a certain position (left = 2000px), using setInterval() to repeatedly call move_left(), then clearInterval() when left == 200px. I can make the element move, but when I look in developer tools it never stops - left continues to increase. I am pretty new to JavaScript/HTML/CSS. How do I make it stop?
Relevant code:
<script>
function runner_go()
{
var load_time = performance.now();
const go = setInterval(move_left,20);
}
function move_left()
{
document.getElementById('runner').style.visibility = "visible";
var runner_position = getComputedStyle(document.getElementById('runner')).getPropertyValue('left');
document.getElementById('runner').style.left = parseInt(runner_position,10) + 17 + "px";
if (parseInt(runner_position,10) > 2000)
{
clearInterval(go);
}
}
</script>
</head>
<body style="background-color:gray;" onmouseover = "runner_go();">
<div>
<h1>Running!</h1>
</div>
<img src="images/runner_l.png" alt ="running man" style="position:relative; visibility:hidden;" id = "runner"/>
</body>
You need to create the var 'go' outside the method cause of the scope, also if you let on the 'body' the 'onmouseover' it will set the interval everytime.
Try this code to test:
<head>
<script>
let go = null;
function runner_go()
{
var load_time = performance.now();
go = setInterval(move_left,20);
}
function move_left()
{
document.getElementById('runner').style.visibility = "visible";
var runner_position = getComputedStyle(document.getElementById('runner')).getPropertyValue('left');
document.getElementById('runner').style.left = parseInt(runner_position,10) + 17 + "px";
if (parseInt(runner_position,10) > 2000)
{
clearInterval(go);
}
}
</script>
</head>
<body style="background-color:gray;" onclick = "runner_go();">
<div>
<h1>Running!</h1>
</div>
<img src="images/runner_l.png" alt ="running man" style="position:relative; visibility:hidden;" id = "runner"/> </body>
Problem -
You declared the interval variable as a constant within another function which is not accessible by the move_left function
So just move your interval variable to global scope (outside the function) and it should work
let go;
function runner_go() {
var load_time = performance.now();
go = setInterval(move_left, 20);
}
function move_left() {
document.getElementById('runner').style.visibility = "visible";
var runner_position = getComputedStyle(document.getElementById('runner')).getPropertyValue('left');
document.getElementById('runner').style.left = parseInt(runner_position, 10) + 17 + "px";
if (parseInt(runner_position, 10) > 2000) {
clearInterval(go);
}
}
sample on how intervals and clearIntervals work
let interval, i = 1;
function start() {
interval = setInterval(log, 1000);
}
function log() {
if (i >= 5) clearInterval(interval);
console.log(`Test ${i}`);
i++
}
start();

Image Slider with counter

I know this question is maybe a bit boring. But I'm searching now for serveral hours and find no way to combine the solutions I found on the Internet.
So I hope someone here would like to help me out.
I have a simple Image slider and I need a counter that says maybe "Image 2 of 3".
As I said, there are a lot of solutions on the internet but I'm not able to implement them to my code.
This is the code Im working with:
HTML
<div class="slider">
<img src="http://placehold.it/250x500" class="active"/>
<img src="http://placehold.it/200x500" />
<img src="http://placehold.it/100x500" />
</div>
<!-- ARROW AND COUNTER -->
<div>
<img src="assets/img/arrow-prev.png" class="prev" alt="Prev Arrow"/>
<span id="counter"></span>
<img src="assets/img/arrow-next.png" class="next" alt="Next Arrow"/>
</div>
CSS
.slider{
height: 51vh;
overflow: hidden;
}
.slider img{
display: none;
height: 51vh;
}
.slider img.active{
display: inline-block;
}
.prev, .next{
cursor: pointer;
}
JAVASCRIPT
$(document).ready(function () {
$('.next').on('click', function () {
var currentImg = $('.active');
var nextImg = currentImg.next();
if (nextImg.length) {
currentImg.removeClass('active').css('z-index', -10);
nextImg.addClass('active').css('z-index', 10);
}
});
$('.prev').on('click', function () {
var currentImg = $('.active');
var prevImg = currentImg.prev();
if (prevImg.length) {
currentImg.removeClass('active').css('z-index', -10);
prevImg.addClass('active').css('z-index', 10);
}
});
});
It would be really great if someome can help me!
So basically you should just keep track of all images and the index of the currently displayed image. Something like the code below could do that.
$(document).ready(function () {
// Get images.
var images = $('.slider > img');
// Set starting index.
var index = images.index($('.active'));
$('#counter').text((index + 1) + ' of ' + images.length);
$('.next').on('click', function () {
var currentImg = $('.active');
var nextImg = currentImg.next();
if (nextImg.length) {
currentImg.removeClass('active').css('z-index', -10);
nextImg.addClass('active').css('z-index', 10);
// Find the index of the image.
var index = images.index(nextImg);
$('#counter').text((index + 1) + ' of ' + images.length);
}
});
$('.prev').on('click', function () {
var currentImg = $('.active');
var prevImg = currentImg.prev();
if (prevImg.length) {
currentImg.removeClass('active').css('z-index', -10);
prevImg.addClass('active').css('z-index', 10);
// Find the index of the image.
var index = images.index(prevImg);
$('#counter').text((index + 1) + ' of ' + images.length);
}
});
});
Link to jsfiddle example.
Explanation: I've added a index variable that checks the active class position:
var index = images.index($('.active'));
$('#counter').text("Image " + (index + 1) + ' of ' + images.length);
Working code:
So Have a look at this code because this should work fine!
$(document).ready(function() {
var images = $('.slider > img');
var index = images.index($('.active'));
$('#counter').text("Image " + (index + 1) + ' of ' + images.length);
$('.next').on('click', function() {
var currentImg = $('.active');
var nextImg = currentImg.next();
if (nextImg.length) {
currentImg.removeClass('active').css('z-index', -10);
nextImg.addClass('active').css('z-index', 10);
var index = images.index(nextImg);
$('#counter').text("Image " + (index + 1) + ' of ' + images.length);
}
});
$('.prev').on('click', function() {
var currentImg = $('.active');
var prevImg = currentImg.prev();
if (prevImg.length) {
currentImg.removeClass('active').css('z-index', -10);
prevImg.addClass('active').css('z-index', 10);
var index = images.index(prevImg);
$('#counter').text("Image " + (index + 1) + ' of ' + images.length);
}
});
});
.slider {
height: 51vh;
overflow: hidden;
}
.slider img {
display: none;
height: 51vh;
}
.slider img.active {
display: inline-block;
}
.prev,
.next {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider">
<img src="https://placehold.it/450x500/red" class="active" />
<img src="https://placehold.it/450x500/r" />
<img src="https://placehold.it/450x500" />
</div>
<!-- ARROW AND COUNTER -->
<div>
<img src="https://placehold.it/50/red" class="prev" alt="Prev Arrow" />
<span id="counter"></span>
<img src="https://placehold.it/50/blue" class="next" alt="Next Arrow" />
</div>
I hope this is the solution you have expected. For any further questions to my answer - let me know :)
Without jQuery, just plain javascript.
With css opacity transition.
https://jsfiddle.net/uatthqjp/3/
const $images = document.querySelectorAll('img');
// `Array.from` for backward compatibility
// to convert `$images` into a real array
// so you can use `forEach` method on it
// use in conjunction with a polyfill
// for example: www.polyfill.io
const images = Array.from($images);
const $buttons = document.querySelector('.buttons');
// counter for current img
let current = 0;
// listen to click events on `$buttons` div
$buttons.addEventListener('click', function(e){
// loop through all images
images.forEach(function(img){
// hide all images
img.classList.remove('active');
});
// if the current clicked button
// contain the class "next"
if (e.target.classList.contains('next')) {
// increment counter by 1
current++;
// reset the counter if reach last img
if (current >= images.length) {
current = 0;
}
// show current img
images[current].classList.add('active');
}
// if the current clicked button
// contain the class "prev"
else {
// decrease counter by 1
current--;
// if "prev" is pressed when first img is active
// then go to the last img
if (current < 0) {
current = images.length - 1;
}
// show current img
images[current].classList.add('active');
}
});
img {
position: absolute;
top: 40px;
opacity: 0; /* hide images */
transition: opacity 1s ease-in-out;
}
.active {
opacity: 1;
}
<img class="active" src="https://dummyimage.com/100x100/e62020/fff&text=IMG1" alt="img1">
<img src="https://dummyimage.com/100x100/20e679/fff&text=IMG2" alt="img2">
<img src="https://dummyimage.com/100x100/4120e6/fff&text=IMG3" alt="img3">
<div class="buttons">
<button class="prev">Prev</button>
<button class="next">Next</button>
</div>
If you look for the easiest solution there is one. All that code added by other users look difficult for me. You can add simple html code with text to each slide and write "1/4", "2/4" etc. Even if you have 10 slides it may be easier than to implement huge jquery or javascript.
The example can be found here W3Schools slideshow
Another very common solution is to use bullet navigator. Many global companies use this solution because it is very easy to understand for everybody. Example - if you have 5 slides you have 5 bullets in the center bottom part of an image. If slide #3 is visible at the moment, third bullet changes color to indicate that you are on slide #3.
There are a few websites that create the entire html/css/js for sliders and you can customize it as you want.
Example of a page: Jssor.com

Java Script Slide Show (add slide effect)

I have a problem
this are my first steps in javascript and I'm trying to make a Javascript slide show.
I try to add a "slide in" "slide out" effect
But I don't know how I can do this.
I google about 2-3 hours but still no solution.
Please help me and give me some feedback please
Here is my code
<head>
<title>Test Slider</title>
</head>
<body>
<div id="slider" style="width: 400px; height: 200px;color: orange; font-weight: bold; font-size: 30px;font-family: sans-serif" onclick="javascript:superlink()" style="cursor:pointer;"></div>
<script type="text/javascript">
//Init//
var SlideDauer = 2000;
var ImgInX = 0;
var ImgInXposition = 0;
var background = 'url(http://www.flashforum.de/forum/customavatars/avatar47196_1.gif)';
var SldInX = 0;
var LinkInX = 0;
function superlink() {
if (!SliderKannEsLosGehen()) return false;
if (LinkInX >= SliderBilder.length) {
LinkInX = 0;
}
var Ziel = window.location.href = SliderLink[LinkInX];
++LinkInX;
}
var SliderBilder = new Array();
SliderBilder.push("http://ds.serving-sys.com/BurstingRes//Site-80313/Type-0/721dbabb-2dd5-4d92-9754-7db9c5888f48.jpg");
SliderBilder.push("http://bytes.com/images/bytes_logo_a4k80.gif");
SliderBilder.push("http://cdn.qservz.com/file/df8e9dcf202cfddedf6f2d4d77fcf07b.gif");
SliderBilder.push("http://ds.serving-sys.com/BurstingRes//Site-80313/Type-0/721dbabb-2dd5-4d92-9754-7db9c5888f48.jpg");
//SliderBilder.push("http://www.flashforum.de/forum/customavatars/avatar47196_1.gif");
var SliderTitle = new Array();
SliderTitle.push("");
SliderTitle.push("Title 1");
SliderTitle.push("Title 3");
SliderTitle.push("Title 4");
//SliderTitle.push("Title 5");
var SliderLink = new Array();
SliderLink.push("http://www.google.de");
SliderLink.push("http://spiegel.de");
SliderLink.push("http://bing.com");
SliderLink.push("http://youtube.com");
//SliderLink.push ("http://www.flashforum.de/forum/customavatars/avatar47196_1.gif");
function SliderKannEsLosGehen() {
if (SliderBilder.length < 2) return false;
return true;
if (SliderTitle.length < 2) return false;
return true;
}
//Run//
function SliderRun() {
if (!SliderKannEsLosGehen()) return false;
if (ImgInX >= SliderBilder.length) {
ImgInX = ImgInXposition;
}
if (SldInX >= SliderBilder.length) {
SldInX = 0;
}
document.getElementById("slider").style.backgroundImage = 'url(' + SliderBilder[ImgInX] + ')';
++ImgInX;
document.getElementById("slider").innerHTML = SliderTitle[SldInX];
++SldInX;
window.setTimeout("SliderRun()", SlideDauer);
}
window.setTimeout("SliderRun()", SlideDauer);
</script>
</body>
</html>
For effects i would look into JQuery and use the animate function. There is loads of fun to be had with this as long as you have an understanding of css.

Slide div every click once right and then on same click back again(left)

My div goes right but when i click again should be back to its original location.....
i tried many stuff but not working.Here is my code...
How do i reverse it when clicked. on every click it should be the reverse of the previous action i.e.
if on click the div moves right then on next click at the same location it should move left similar to a pendulum
<html>
<head><title></title>
<script type="text/javascript" language="javascript">
//<![CDATA[
window.onload=function()
{
document.getElementById("d2").onclick = slideIt;
};
function slideIt()
{
var slidingDiv = document.getElementById("d1");
var stopPosition = 50;
if (parseInt(slidingDiv.style.left) < stopPosition )
{
slidingDiv.style.left = parseInt(slidingDiv.style.left) + 2 + "px";
setTimeout(slideIt, 1);
}
/*
if(parseInt(slidingDiv.style.left) > stopPosition )
{
slidingDiv.style.left = parseInt(slidingDiv.style.left) + 2 + "px";
setTimeout(slideIt, 1);
}*/
}
//]]>
</script>
</head>
<body>
<div id="d1" style="position:absolute; left:-131px;">
<div style=" float:left" >click here to slide the div</div>
<div id="d2" style=" float:left" >click here to slide the div</div> </div>
</body>
</html>
Change your JavaScript with this one
<script type="text/javascript" language="javascript">
$(document).ready(function(){ $("#d2").click(function(){
if($("#d1").css("left") <="-131px")
{
$("#d1").animate({left:'250px'});
}
else {
$("#d1").animate({left:'-131px'});
}
});
});
</script>
This will work fine
Good Luck..
Okay, so here's how I have done things...
DEMO: http://jsfiddle.net/xDDX8/2/
HTML
<div id="d1">
<div id="d2">click here to slide the div</div>
</div>
CSS
#d1 {
position: absolute;
border: 1px solid red;
cursor: pointer;
left: 0;
}
.moveLeft {
color: blue;
}
.moveRight {
color: lime;
}
Javascript
window.onload = bindEvents();
function bindEvents() {
document.getElementById('d2').onclick = slideIt;
}
// Global variables
var slidingDiv = document.getElementById('d1'); // Cache the element
var timeout = 0;
var minPosition = 0;
var maxPosition = 50;
function slideIt() {
// Work out current position
var currentPosition = slidingDiv.offsetLeft;
// Check which direction to move
if (hasClass(slidingDiv, 'moveRight'))
{
// Have we hit our movement limit?
if (currentPosition <= minPosition)
{
// remove all classes and set a class to move the other direction
slidingDiv.removeAttribute('class');
slidingDiv.setAttribute('class', 'moveLeft');
// Clear our timeout
clearTimeout(timeout);
}
else
{
// Still space to move so let's move a few pixels (-)
slidingDiv.style.left = (currentPosition - 2) + "px";
timeout = setTimeout(slideIt, 1);
}
}
else // all comments as above really
{
if (currentPosition >= maxPosition)
{
slidingDiv.removeAttribute('class');
slidingDiv.setAttribute('class', 'moveRight');
clearTimeout(timeout);
}
else
{
slidingDiv.style.left = (currentPosition + 2) + "px";
timeout = setTimeout(slideIt, 1);
}
}
}
// Function to test whether an element has a specific class
// https://stackoverflow.com/questions/5898656/test-if-an-element-contains-a-class
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}

Life Counter Issue

I was builiding lately life counter and i can't figure out what the issue around here, I mean i got 2 divs, when you on div with class "alive" you get score up and when you in "dead" div you get score down.
Now I've made this code that work on seconds, but it not working stright, I mean 1, 2, 3. But it working like this: http://jsfiddle.net/4Tby5/
Or as visual code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Alive - Dead</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
var l = 1;
var good = " Excelent!";
var bad = " OH NO!";
$(document).ready(function () {
$('#alive').hover(function () {
if (l > 100) {
window.clearTimeout("tim");
}
else {
document.getElementById("percent").innerHTML = "Life: " + l + good;
l++;
var tim = window.setTimeout("count()", 1000);
}
count();
});
});
$(document).ready(function () {
$('#dead').hover(function () {
if (l < 0) {
window.clearTimeout("tim");
}
else {
document.getElementById("percent").innerHTML = "Life: " + l + bad;
l--;
var tim = window.setTimeout("count()", 1000);
}
count();
});
});
</script>
<style>
body {
background: red;
}
.dead {
cursor: url(thumb-down.cur) 6 6, auto;
padding-bottom: 285px;
}
.alive {
background: #32ff0a;
height: 300px;
margin: -8px;
cursor: url(thumb-up.cur) 6 6, auto;
}
</style>
</head>
<body>
<div class="alive" id="alive">
Stay here to survive!
</div>
<div class="dead" id="dead">
<br />
Stay away from dead area!
</div>
<div id="percent"></div>
</body>
</html>
So my question is how can i fix this to get it 1,2,3 (replace 1 with 2 and 3, 4...)?
You do not have a count function, make one
And you clear a timeout using the variable itself not its name
window.clearTimeout(tim);
also with your current code you will need to use a global variable
window.tim = window.setTimeout("count()", 1000);
window.clearTimeout(window.tim);
otherwise the clearTimeout wont see it.
Here is solution to your problem.
Problem in your code is... Hover function is calulated only when Mouse enters... Not as long as mouse remains inside.
http://jsfiddle.net/Vdq39/2/
$(document).ready(function () {
var good = " Excelent!";
var bad = " OH NO!";
var tim;
var counter = 0;
function count() {
counter++;
document.getElementById("percent").innerHTML = "Life: " + counter + good;
if (counter > 100) {
window.clearInterval(tim);
}
}
function countDown() {
counter--;
document.getElementById("percent").innerHTML = "Life: " + counter + bad;
if (counter < 0) {
window.clearInterval(tim);
}
}
$('#alive').hover(function () {
if (counter > 100) {
window.clearInterval(tim);
} else {
tim = window.setInterval(count, 1000);
}
}, function () {
window.clearInterval(tim);
});
$('#dead').hover(function () {
if (counter < 0) {
window.clearInterval(tim);
} else {
tim = window.setInterval(countDown, 1000);
}
},
function () {
window.clearInterval(tim);
});
});

Categories