im trying to create a automatic image slider which also responds to an onclick function, for some odd reason the onclick event is pretty much doing nothinig i suspect its cause of the settime out as javascript is single threaded but im no master at javascript! could someone please tell me what i'm doing wrong stuck with this for the past two days! thank you!
var i = 0;
var starterimages= [];
var time = 3000;
var eventaction=0;
var timeoutId;
starterimages[0] = "https://i.pinimg.com/236x/f4/92/39/f492399e154bd9f564d7fc5299c19911--purple-rain-deep-purple.jpg";
starterimages[1] = "https://image.shutterstock.com/image-photo/purple-butterfly-isolated-on-white-260nw-44004850.jpg";
starterimages[2] = "https://www.birdscanada.org/images/inbu_norm_q_townsend.jpg";
var nextbutton=document.querySelector("#rightbutton");
nextbutton.addEventListener("click",rightbuttonclick);
var prevbutton=document.querySelector("#leftbutton");
nextbutton.addEventListener("click",leftbuttonclick);
function rightbuttonclick()
{
eventaction=1;
clearTimeout(timeoutId);
}
function leftbuttonclick()
{
eventaction=2;
clearTimeout(timeoutId);
}
function changeImg(){
document.getElementById('startersliders').src = starterimages[i];
if(eventaction==1)
{
i++;
if(i < starterimages.length - 1)
{document.getElementById('startersliders').src = starterimages[i];
eventaction=0;}
else
{
i=0;
document.getElementById('startersliders').src = starterimages[i];
eventaction=0;
}
}
else if(eventaction==2)
{
i--;
if(i== - 1)
{
i=3;
document.getElementById('startersliders').src = starterimages[i];
eventaction=0;
}
else
{
document.getElementById('startersliders').src = starterimages[i];
eventaction=0;
}
}
else if(eventaction==0){
if(i < starterimages.length - 1){
i++;
}
else {
i = 0;
}
}
// Run function every x seconds
timeoutId = setTimeout("changeImg()", time);
}
// Run function when page loads
window.onload=changeImg;
#staratersliders {
width: 10%;
height: 10%;
position: relative;
margin: 0% 0% 0% 0%;
}
<button class="button button3" id="leftbutton"> previous</button>
<img id="startersliders" />
<button class="button button3" id="rightbutton">next</button>
I got it all working in Firefox 51, buttons included. Just paste the whole thing in a blank page and save it with an .htm or .html extension.
<!DOCTYPE=HTML><html><meta charset="UTF-8">
<script>
var i = 0;
var starterimages= [];
var time = 3000;
var eventaction=0;
var timeoutId;
starterimages[0] = "https://i.pinimg.com/236x/f4/92/39/f492399e154bd9f564d7fc5299c19911--purple-rain-deep-purple.jpg";
starterimages[1] = "https://image.shutterstock.com/image-photo/purple-butterfly-isolated-on-white-260nw-44004850.jpg";
starterimages[2] = "https://www.birdscanada.org/images/inbu_norm_q_townsend.jpg";
function rightbuttonclick() {
eventaction = 1;
clearTimeout(timeoutId);
changeImg();
}
function leftbuttonclick() {
eventaction = 2;
clearTimeout(timeoutId);
changeImg();
}
function changeImg() {
if (eventaction == 1) {
if (i < starterimages.length - 1) {
i++;
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
} else {
i = 0;
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
}
} else if (eventaction == 2) {
i--;
if (i < 0) {
i = 2;
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
} else {
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
}
} else {
if (i < starterimages.length - 1) {
i++;
} else {
i = 0;
};
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
}
timeoutId=setTimeout("changeImg()", time);
}
</script>
<style>
#startersliders {width: 10%;height: 10%;position: relative;margin: 0% 0% 0% 0%;}
</style>
<body onload="changeImg();">
<button class="button button3" id="leftbutton">previous</button>
<img id="startersliders">
<button class="button button3" id="rightbutton">next</button>
<script>
var nextbutton=document.querySelector("#rightbutton");
nextbutton.addEventListener("click",rightbuttonclick);
var prevbutton=document.querySelector("#leftbutton");
prevbutton.addEventListener("click",leftbuttonclick);
</script>
</body>
</html>
It won't work because this:
setTimeout("changeImg()", time);
Is invalid syntax for setTimeout. To fix it, just do this:
setTimeout(changeImg, time);
var nextbutton=document.querySelector("#rightbutton");
nextbutton.addEventListener("click",rightbuttonclick);
var prevbutton=document.querySelector("#leftbutton");
nextbutton.addEventListener("click",leftbuttonclick);
I copy/pasted the code into my machine and the above came up null because they need to be between script tags at the bottom of the body of the doc.
When the parser sees those at the top, it doesn't know what #rightbutton and #leftbutton are because it hasn't parsed the html in the body section yet so it comes back as a null element
just move them to the bottom of the body section after the html and put script /script tags around them and see what happens
You need to do both of the above, what Matthew Herbst said is correct and what Jack Bashford said is correct. Create a variable for the setTimeout
var mytimeinverval;
var mytimer;
mytimer=setTimeout(myfunctionname,mytimeinterval);
The function name inside the setTimeout doesn't get quotes or parenthesis.
If you put parenthesis in, it might fire instantly or who knows?
It still recognizes myfunctionname as a function without the parenthesis.
Putting quotes around it makes it a string-won't work in my experience.
I don't want credit, they answered it, just letting you know to do both.
Related
I have a JSFiddle that shows my code now:
https://jsfiddle.net/qtu1xgw3/2/
Basically there is an image button (pink flower) and then there are 4 images that change when the button is clicked.
Now the issue is that I want the button to hide when I get to the last image. Right now I need to click the button twice to get it to hide on the last image. But I want with the last click of the button to hide it at the same time that the last image in the gallery is shown.
One of the images is in the html part of the code, which might be what causes this issue, I think, but I'm not sure how to do this differently without breaking the code?
(random images from google used for the sake of testing)
HTML:
<div class="test">
<div class="desc">
<h2 id="title_text">test1</h2>
<p id="under_text">test2</p>
</div>
<div id="pink">
<img src="https://images.vexels.com/media/users/3/234325/isolated/lists/cba2167ec09abeeee327ffa0f994151b-detailed-flower-illustration.png" onclick="imagefun()"></div>
<div class="game">
<img src="https://images.vexels.com/media/users/3/143128/isolated/lists/2a84565e7c9642368346c7e6317fa1fa-flat-flower-illustration-doodle.png" id="getImage"></div>
</div>
CSS:
.game img {
width: 300px;
height: auto;
}
.test {
display: flex;
flex-direction: row;
}
JS:
var counter = 0,
gallery = ["https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg", "https://api.assistivecards.com/cards/gardening/flowers.png", "https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg"],
imagefun = function () {
if (counter >= gallery.length) {
document.getElementById("title_text").innerHTML = "test3"; document.getElementById("under_text").innerHTML = "test4"; document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};
I have made some change to your code. It will help you.
var counter = 0,
gallery = ["https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg", "https://api.assistivecards.com/cards/gardening/flowers.png", "https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg"],
imagefun = function () {
if (counter == gallery.length -1) {
document.getElementById("getImage").src = gallery[counter];
document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};
try this
Evaluate when the counter is equal to the size of your array if so then do the job you want
imagefun = function () {
if(counter==gallery.length)
{
document.getElementById("getImage").style.display = "none";
}
if (counter >= gallery.length) {
document.getElementById("title_text").innerHTML = "test3";
document.getElementById("under_text").innerHTML = "test4";
document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};
The issue is that you increment your counter after the counter >= gallery.length check.
The correct solution is:
const gallery = [
"https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg",
"https://api.assistivecards.com/cards/gardening/flowers.png",
"https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg",
];
let counter = 0;
document.getElementById("getImage").src = gallery[counter];
function imagefun() {
counter += 1;
document.getElementById("getImage").src = gallery[counter];
if (counter >= gallery.length - 1) {
document.getElementById("title_text").innerHTML = "test3";
document.getElementById("under_text").innerHTML = "test4";
document.getElementById("pink").style.display = "none";
}
};
This question already has an answer here:
jQuery page scroll event logic -- how to throttle
(1 answer)
Closed 6 years ago.
I am trying to mimic the functionality of the following website: www.verbaasd.net. Each scrolling "session" will only trigger one action.
Each time a user scrolls down an action will happen depending on the status of variabel count. I only want this to happen ONCE per scroll. For example if a user has a Macbook with touchpad it will fire multiple times very vast. The count will go from 1 to 4 pretty much instantly. Is there a way to set a timeout or something so it stops for 0.5 sec when variabel count increases or decreases by 1?
Current code:
var count = 1;
$(window).on('mousewheel DOMMouseScroll', function(e) {
if (e.originalEvent.wheelDelta / 120 > 0) {
count -= 1;
} else {
count += 1;
}
if (count < 1) count = 1;
if (count > 4) count = 4;
switch (count) {
case 1:
// do something
break;
case 2:
// do something
break;
case 3:
// do something
break;
case 4:
// do something
break;
}
$(".cd-background-wrapper").attr("data-slide", count);
});
I recommend other way.
You should use 'preventDefault' and delay effect using setTimeout.
I wrote a simple prototype code below link.
(only tested on Chrome and safari)
http://codepen.io/nigayo/pen/PNEvmY
[HTML]
<body>
<div id="wrap">
<section>section A</section>
<section>section B</section>
<section>section C</section>
<section>section D</section>
</div>
</body>
[CSS]
body {
overflow: hidden;
height: 100%;
}
#wrap {
position: relative;
width: 100%;
height: 100%;
top: 0;
}
section {
width: 100%;
height: 600px;
}
section:nth-child(1) {
background: red;
}
section:nth-child(2) {
background: blue;
}
section:nth-child(3) {
background: green;
}
section:nth-child(4) {
background: magenta;
}
[JavaScript]
(function() {
var currentPanel = 1;
var wrap = $('#wrap');
var panelsize = 600;
var step = 10;
var interval = 1000;
var direction = 1;
var bAnimation = false;
function animation() {
setTimeout(function() {
var currentTop = parseInt(wrap.css("top"));
if (direction < 0) {
if (currentTop <= minValue) {
setTimeout(function() {
bAnimation = false;
}, interval);
return;
}
} else {
if (currentTop >= minValue) {
setTimeout(function() {
bAnimation = false;
}, interval);
return;
}
}
wrap.css({
"top": currentTop - step
});
animation();
}, 16);
}
$(window).bind('mousewheel DOMMouseScroll', function(event) {
event.preventDefault();
if (bAnimation) return;
var currentTop = parseInt(wrap.css("top"));
if (event.originalEvent.wheelDelta < 0) {
//down scroll
minValue = currentTop - panelsize;
step = 10;
direction = -1;
} else {
//up scroll
minValue = currentTop + panelsize;
step = -10;
direction = 1;
}
console.log(minValue, bAnimation);
bAnimation = true;
animation();
});
})();
If you refer to my codes, you should use 'jquery animate function' or 'requestAnimationframe' for animation logic.
Answer thanks to A. Wolff. Using _.throttle with lodash.js did the trick! You can find more info here: https://css-tricks.com/the-difference-between-throttling-and-debouncing/
how would I make a loading bar, I would also like it to be "stackable" like have 2 on the same page and have the first one trigger the second one when its complete then the second one redirects to a URL at 100%, this may or may not be basic to you guys but its really hard for me. I have an outdated JavaScript one already but it disappears when I add the second one and don't know how to make it trigger the second one. if you want to try and edit the one I have so It triggers the second one and is stackable then just say so, but note its outdated, I know that, I am using it because it is really simple to configure and setup.
This is the relevant code so far:
var currentAdb = 0;
var imgCtb = 25;
function cycleb() {
var output = '[';
for (var i = 0; i < imgCtb; i++) {
output += i > currentAdb ? ' ' : '/';
}
output += ']';
document.getElementById('adLinkb').innerHTML = output;
++currentAdb;
if(currentAdb == imgCtb) {
window.clearInterval(myInterval);
}
}
var myInterval = window.setInterval(cycleb, 500);
#adLinkb {
font-size: 12px;
color: #000;
font-family: monospace;
}
<div id="adLinkb"></div>
OK, let's expand the code I gave you in the last question by grouping it into functions and introducing callbacks:
function buildBar(id, callback) {
var currentAdb = 0;
var imgCtb = 25;
function cycleb() {
var output = '[';
for (var i = 0; i < imgCtb; i++) {
output += i > currentAdb ? ' ' : '/';
}
output += ']';
document.getElementById(id).innerHTML = output;
++currentAdb;
if (currentAdb == imgCtb) {
window.clearInterval(myInterval);
if (typeof callback == 'function') {
callback();
}
}
}
var myInterval = window.setInterval(cycleb, 500);
}
function callback1() {
buildBar('adLinkb2', callback2);
}
function callback2() {
//window.location... stuff here
alert('redirect should go here');
}
buildBar('adLinkb', callback1);
#adLinkb,
#adLinkb2 {
font-size: 12px;
color: #000;
font-family: monospace;
}
<div id="adLinkb"></div>
<div id="adLinkb2"></div>
i have tried it within the loop function but it says the function isn't being used so i put it outside still doesnt work and i dont know how to fix it as i thought that would work, rmember first day on javascript, thanks for the help in advance and please no jquery.
<html>
<head>
<style type="text/css">
#PictureContainer {
height: 300px;
width: 500px;
margin: 0 auto;
overflow: hidden;
display: inline-block;
}
#SliderWrapper {
width: 628px;
height: 300px;
margin: 0 auto;
overflow: hidden;
}
#image {
height: 300px;
width: 500px;
}
#Next {
float: right;
}
#Before {
float: left;
}
</style>
</head>
<body>
<div id="SliderWrapper">
<img id="Next" src="Forward.png" alt="Forward">
<img id="Before" src="Back.png" alt="Back">
<div id="PictureContainer">
<img id="image" src="html.png" alt="HTML">
</div>
</div>
<script language="javascript" type="text/javascript">
var i = 1;
function loop() {
i = i+1;
if(i == 5){
i = 1;
}
if (i == 1) {
document.getElementById('image').src = "html.png";
} else if(i == 2) {
document.getElementById('image').src = "css3.png";
} else if (i == 3) {
document.getElementById('image').src = "WebdevLogo's.jpg";
} else {
document.getElementById('image').src = "WebdevLogo's.jpg";
}
}
var pictureloop = setInterval(loop, 3000);
function Forward() {
if(i == 5) {
i = 1;
} else {
i = i+1;
}
}
function Back() {
if(i == 1) {
i = 4;
} else {
i = -1;
}
}
</script>
</body>
</html>
You have a function called loop, but you never call it, so it's never changing the source attribute of the image. In the forward and back functions, add a call to the loop function at the end. There are also a few problems internally with Back() that I've fixed.
function Forward() {
if(i == 5) {
i = 1;
} else {
i++;
}
loop();
}
function Back() {
if(i == 1) {
i = 5;
} else {
i--;
}
loop();
}
Within the loop() function, consider using a switch block instead of all those else ifs. Also in the loop function, use the increment operator - i++; - which increases the value by 1, rather than the manual statement i = i+1; Also, the if i==5 statement is redundant. You already have it in your Forward function.
this is more of a question for https://codereview.stackexchange.com/ but here are a few things that would make this code cleaner.
instead of duplicating image setting code, declare an array of images.
var images = ['img1.png','img2.png'];
var currentImage = 0;
function forward() {
currentImage++;
if (currentImage > images.length-1) currentImage == 0;
setImage()
}
function setImage() {
document.getElementById('image').src = images[currentImage];
}
setInterval(forward, 5000);
I am working on a wordpress website who's client would like me to adjust our AdSanity plugin to display groups of ads in a rotating image gallery fashion like the ones on this page. The leaderboard ads for sure are AdSanity run. I was able to stem from viewing the source that this is the script I need:
$(function() {
var adsLists = $('.adsanity-group'),
i = 0;
var divs = new Array();
adsLists.each(function() {
divs[i] = $("#" + $(this).attr('id') + " div").not(".clearfix").hide();
i++;
});
var cycle_delay = 12000;
var num_groups = $('.adsanity-group').length;
function cycle(divsList, i) {
divsList.eq(i).fadeIn(400).delay(cycle_delay).fadeOut(400, function() {
cycle(divsList, ++i % divsList.length); // increment i, and reset to 0 when it equals divs.length
});
};
for (var j = divs.length - 1; j >= 0; j--) {
if (divs[0].eq(0).attr('num_ads') > 1)
cycle(divs[j], 0);
else
divs[j].show();
};
//////////
$('#slides').slidesjs({
width: 552,
height: 426,
navigation: false,
play: {
auto: true
}
});
//////////
$('.three_lines_fixed').each(function() {
$clamp(this, {
clamp: 3
});
});
var top_divs = $("#adspace div").not(".clearfix").hide(),
top_i = 0;
var top_num_ads = $('#adspace > div').attr("num_ads");
var top_cycle_delay = 12000;
function top_cycle() {
top_divs.eq(top_i).fadeIn(400).delay(top_cycle_delay).fadeOut(400, top_cycle);
top_i = ++top_i % top_divs.length; // increment i,
// and reset to 0 when it equals divs.length
};
if (top_num_ads > 1) {
top_cycle();
} else {
top_divs.show();
}
var site_url = $("body").attr("site_url");
$("#brpwp_wrapper-2 ul").append("<li style='text-align: center;'><a class='widgetized_read_more' href='" + site_url + "/2013'>Read More</a></li>")
/**/
And some of that I don't believe I need, like the three_lines_fixed or the slides. I also have the CSS used for #adspace:
div.header div#adspace {
float: right;
max-width: 728px;
max-height: 90px; }
div.header div#adspace img {
float: right; }
There is also this CSS:
div#page .main_content ul.widgets li.adspace {
display: none; }
On my site http://dsnamerica.com/eisn/ I want the 300px width ads on the right sidebar to rotate like those on the Vype site. These ads though are not listed with ul and li, they are divs.
So far I've added this to my header.php theme file right before the closing tag:
<script type="text/javascript" src="<?php bloginfo('template_url'); ?>/js/fading-ads.js"></script>
And in that file (js/fading-ads.js), I have this:
function adsanitygroup() {
var adsLists = $('.adsanity-group'),
i = 0;
var divs = new Array();
adsLists.each(function() {
divs[i] = $("#" + $(this).attr('id') + " div").not(".clearfix").hide();
i++;
});
var cycle_delay = 12000;
var num_groups = $('.adsanity-group').length;
function cycle(divsList, i) {
divsList.eq(i).fadeIn(400).delay(cycle_delay).fadeOut(400, function() {
cycle(divsList, ++i % divsList.length); // increment i, and reset to 0 when it equals divs.length
});
};
for (var j = divs.length - 1; j >= 0; j--) {
if (divs[0].eq(0).attr('num_ads') > 1)
cycle(divs[j], 0);
else
divs[j].show();
var top_divs = $("#adspace div").not(".clearfix").hide(),
top_i = 0;
var top_num_ads = $('#adspace > div').attr("num_ads");
var top_cycle_delay = 12000;
function top_cycle() {
top_divs.eq(top_i).fadeIn(400).delay(top_cycle_delay).fadeOut(400, top_cycle);
top_i = ++top_i % top_divs.length; // increment i,
// and reset to 0 when it equals divs.length
};
if (top_num_ads > 1) {
top_cycle();
} else {
top_divs.show();
};
};
}
That is my attempt to define the function and clean out what I didn't need. I don't think, no, I know it's not right. So I'll put my questions in a list, since this post is already wordy.
1) Did I link the js file correctly in the theme's header.php file? It's right before the closing </head> tag.
2) Do I need the second CSS part that says "display: none" and if so, how do I change the CSS to work with divs instead of ul and li? Do I just change div#page .main_content ul.widgets li.adspace {
display: none;}
to
div#page .main_content .widgets .adspace {
display: none; }
then add the class .adspace to the widget?
See, I have been trying to get this to work for a couple days now and I've thought so much on it I'm not making cohesive theories anymore, just shots in the dark. How to solve this?