How would I go about adding a timer to this js so images would change automatically after 'x' amount of time. As it stands the change is made via 'a href' with the 'rel' attribute, but that function with the 'rel' is still required.
js:
$(document).ready(function (){
$('#button a').click(function(){
var integer = $(this).attr('rel');
$('#myslide .cover').css({left:-1476*(parseInt(integer)-1)}).hide().fadeIn(); /*----- Width of div mystuff (here 160) ------ */
$('#button a').each(function(){
$(this).removeClass('active');
if($(this).hasClass('button'+integer)){
$(this).addClass('active')}
});
});
});
html:
<div id="myslide">
<div class="cover">
<div class="mystuff">
<img src="images/header_01.jpg" rel="1"></img>
<img src="images/header_02.jpg" rel="1"></img>
<img src="images/header_03.jpg" rel="1"></img>
</div>
</div>
You should consider using setInterval and and an array of images to change the source. This will force the image to loop continuously
var images = ['header_01.jpg','header_02.jpg','header_03.jpg'],
index = 0, // starting index
maxImages = images.length - 1;
var timer = setInterval(function() {
var curImage = images[index];
index = (index == maxImages) ? 0 : ++index;
// set your image using the curImageVar
$('div.mystuff img').attr('src','images/'+curImage);
}, 1000);
You can use the setTimeout function to call a predefined function to change your images like this:
var changeImage = function (){
<code>
};
var t = setTimeout(changeImage, <time in milliseconds>);
Make sure you are not calling setTimeout(changeImage(), <time in milliseconds>); (note the two parentheses)
This is to be avoided and you should try to use a function instead of a string to be evaluated as the first parameter to setTimeout().
Alternatively, you could use an anonymous function instead of creating changeImage.
Ex.
var t = setTimeout(function() { <code>}, <time in milliseconds>);
Related
I'm trying to get 2 sliders running on a page. As long as I only use one slide, it's fine, but as soon as I add a second slider only the first works. Tried to solve it with each and $this, but being a novice to jquery I'm missing something.
Note: This slider is built in a way, that it takes the class like "dur-7" and uses it to calculate how long a slide is being shown. This allows in Gutenberg to add a class and such the duration for each individual slide.
Tried the concept of each and this in another example and it worked. Used console.log to see the values coming up.
https://jsfiddle.net/francis_hunger/bzvx6rac/5/
<html>
<div class="wp-block-group fhslide">
<div class="wp-block-group__inner-container">
<div class="wp-block-image dur-7"><img src="https://upload.wikimedia.org/wikipedia/commons/5/56/Sequoiadendron_giganteum_at_Kenilworth_Castle.jpg"></div>
<div class="wp-block-image dur-2"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Baum_im_Sossusvlei.jpg/2560px-Baum_im_Sossusvlei.jpg"></div>
<div class="wp-block-image dur-9"><img src="https://upload.wikimedia.org/wikipedia/commons/b/bf/Buchenstamm.jpg"> </div>
</div>
</div>
<hr>
<div class="wp-block-group fhslide">
<div class="wp-block-group__inner-container">
<div class="wp-block-image dur-20"><img src="https://upload.wikimedia.org/wikipedia/commons/1/1b/Baumstamm.jpg"></div>
<div class="wp-block-image dur-20"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Bl%C3%A4tterDurchRinde.jpg/2560px-Bl%C3%A4tterDurchRinde.jpg"></div>
</div>
</div>
</div>
</div>
<script>
jQuery(function() {
if (jQuery('.fhslide').length!==0){
jQuery.each(jQuery('.fhslide'), function () {
var theImage = jQuery('.wp-block-image img',this);
var theWidth = theImage.width(this);
// INIT
jQuery ('.wp-block-group__inner-container', this).children().first().addClass('active').css('opacity', '1');
jQuery ('.wp-block-group__inner-container', this).children().last().addClass('last');
// First Match
var lookup = jQuery('.wp-block-group__inner-container',this).children().first().attr('class').match(/dur-[0-9]*/); // Aktuelles Element, Array
var durStr = '50'; // Standard
if (!lookup == "") {
durStr = lookup[0].substring(4);// We just need the first position of the array [0], then we match "dur-" and keep the seconds (as a string)
}
var durInt = parseInt(durStr)*1000; // string to Milliseconds
/****** CALL *******/
var fh_timer = setTimeout(fh_next(this),durInt);
/****** FH NEXT *******/
function fh_next() {
var a = jQuery('.active');
a.removeClass('active').fadeTo('slow',0).next().fadeTo('slow',1);
// Last element
if (a.hasClass('last')) {
var durStr = a.siblings(":first").attr('class').match(/dur-[0-9]*/)[0].substring(4); // pick the duration of the first element (and go there)
var durInt = parseInt(durStr)*1000; a.siblings(":first").addClass('active').fadeTo('slow',1); // gehe zum ersten Element
}
// All elements
else {
var durStr = a.next().attr('class').match(/dur-[0-9]*/)[0].substring(4);
var durInt = parseInt(durStr)*1000;
a.next().addClass('active'); // go to next element
}
/* Set the duration */
setTimeout(fh_next, durInt);
}// fh_next()
// Maximum height for wrapper
jQuery('.wp-block-group__inner-container', this).css({
width: function() {
return theWidth;
},
height: function() {
return theImage.height();
},
});
// Maximum width for wrapper
var totalWidth = theImage.length * theWidth;
jQuery('figure.wp-block-image', this).css({
width: function() {
return totalWidth;
}
});
});//each
} //if
});// ready function()
</script>
</html>
The expected result would be, that each slider block group with the class "fhslide" works individually. Currently only the first slider runs continuously and the second slider runs once and then no any more.
Issue
You are not assigning this correctly:
var fh_timer = setTimeout(fh_next(this),durInt); // <---
function fh_next() {
And fh_next does not have arguments.
Solution
Bind this when calling:
var fh_timer = setTimeout(() => fh_next.call(this), durInt); // <---
function fh_next() {
Could this be the problem?
I need to make the background image in div tag and it has to change automatically, I already put the array of images inside the javascript, but the images is not showing when i'm run the site.The background should behind the menu header.
This is the div
<div style="min-height:1000px;position:relative;" id="home">
below of the div is containing the logo, menu and nav part.
<div class="container">
<div class="fixed-header">
<!--logo-->
<div class="logo" >
<a href="index.html">
<img src="images/logo.png" alt="logo mazmida" height="142" width="242">
</a>
</div>
<!--//logo-->
This is the javascript
<script>
var imgArray = [
'images/1.jpg',
'images/2.jpg',
'images/3.jpg'],
curIndex = 0;
imgDuration = 2000;
function slideShow() {
document.getElementID('home').src = imgArray[curIndex];
curIndex++;
if (curIndex == imgArray.length) { curIndex = 0; }
setTimeout("slideShow()", imgDuration);
}
slideShow();
You have a few issues with your script. I've made a live JSbin example here:
https://jsbin.com/welifusomi/edit?html,output
<script>
var imgArray = [
'https://upload.wikimedia.org/wikipedia/en/thumb/0/02/Homer_Simpson_2006.png/220px-Homer_Simpson_2006.png',
'https://upload.wikimedia.org/wikipedia/en/thumb/0/0b/Marge_Simpson.png/220px-Marge_Simpson.png',
'https://upload.wikimedia.org/wikipedia/en/a/aa/Bart_Simpson_200px.png'
];
var curIndex = 0;
var imgDuration = 1000;
var el = document.getElementById('home');
function slideShow() {
el.style.backgroundImage = 'url(' + imgArray[curIndex % 3] + ')';
curIndex++;
setTimeout("slideShow()", imgDuration);
}
slideShow();
</script>
There are a few issues with your script:
On the element since it's a div not an img, you need to set style.backgroundImage instead of src. Look at https://developer.mozilla.org/en-US/docs/Web/CSS/background for other attributes to related to background image CSS
Also it's document.getElementById
Optimizations
And you can use mod % trick to avoid zero reset
Use setInterval instead of setTimeout
Further optimzations
Use requestAnimationFrame instead of setTimeout/setInterval
I suggest getting familiar with your browser debugging tools which would help identify many of the issues you face.
document.getElementID('home').src = imgArray[curIndex]
You are targeting a div with an ID of home, but this is not an Image element (ie ,
But since you want to alter the background colour of the DIV, then you use querySelector using javascript and store it in a variable, then you can target the background property of this div (ie Background colour).
I hope this helps.
You are trying to change the src property of a div, but divs do not have such property.
Try this:
document.getElementById('home').style.backgroundImage = "url('" + imgArray[curIndex] + "')"
This changes the style of the target div, more precisely the image to be used as background.
As you want to change the background image of the div, instead of document.getElementID('home').src = imgArray[curIndex] use
document.getElementById("#home").style.backgroundImage = "url('imageArray[curIndex]')";
in JavaScript or
$('#home').css('background-image', 'url("' + imageArray[curIndex] + '")'); in jquery.
To achieve expected result, use below option of using setInterval
Please correct below syntax errors
document.getElementID to document.getElementById
.src attribute is not available on div tags
Create img element and add src to it
Finally use setInterval instead of setTimeout outside slideShow function
var imgArray = [
'http://www.w3schools.com/w3css/img_avatar3.png',
'https://tse2.mm.bing.net/th?id=OIP.ySEgAgJIlDQsIQTu_MeoLwHaHa&pid=15.1&P=0&w=300&h=300',
'https://tse4.mm.bing.net/th?id=OIP.wBAPnR04OfXaHuFI9Ny2bgHaE8&pid=15.1&P=0&w=243&h=163'],
curIndex = 0;
imgDuration = 2000;
var home = document.getElementById('home')
var image = document.createElement('img')
function slideShow() {
if(curIndex != imgArray.length-1) {
image.src = imgArray[curIndex];
home.appendChild(image)
curIndex++;
}else{
curIndex = 0;
}
}
setInterval(slideShow,2000)
<div style="position:relative;" id="home"></div>
code sample - https://codepen.io/nagasai/pen/JLKvME
FOr some reason my code is not executing properly. i am trying to program a slideshow with javascript. Im using a for loop to pull and populate the src files from a created array and change the pic every 3 seconds. THe page loads and the first pic is present but when the interval occurs the first pic dissapears and nothing falls in its place. What am I doing wrong?
<img name="mainSlide" id="mainSlide" src="images/mainPagePhotos/facebook-20131027-180258.png" alt="">
var mainSlidePics = ("facebook-20131027-180258.png","IMG_9694116683469.jpg","IMG_28452769990897.jpg");
window.onload = setInterval("mainSlide();", 3000);
function mainSlide() {
for(i=0; i<mainSlidePics.length; i++ ) {
document.images.mainSlide.src = "images/mainPagePhotos/" + mainSlidePics[i];
}
}
Have you tried getting the Id first?
var mainSlide = document.getElementById("mainSlide");
mainSlide.src = "images/mainPagePhotos/" + mainSlidePics[i];
also a forloop is a loop that finishes its loops even in one call.
try
var i = 0;
window.onload = setInterval("mainSlide(i);", 3000);
mainSlide(int j){
mainSlide.src = "images/mainPagePhotos/" + mainSlidePics[i];
setInterval("mainSlide(j++);", 3000);
}
First you have to correctly declare the array.
Then you have to move the counter variable outside the function triggered by setInterval.
Then pass the reference of the function to setInterval.
<img name="mainSlide" id="mainSlide" src="images/mainPagePhotos/facebook-20131027-180258.png" alt="">
<script type="text/javascript">
var mainSlidePics = ["facebook-20131027-180258.png","IMG_9694116683469.jpg","IMG_28452769990897.jpg"];
var position = 0;
function changePic() {
position = (position+1) % mainSlidePics.length;
document.images.mainSlide.src = "images/mainPagePhotos/" + mainSlidePics[position];
}
window.onload = function() {
setInterval(changePic, 3000);
};
</script>
I have 3 divs in a html page, 2 divs should be hiddent always but theire content should be displayed in another div and this content should be changed every x seconds. Hows that possible using jquery/javascript?
<div id="contentA">
<!-- Some contents goes here, and it should be hidden -->
</div>
<div id="contentB">
<!-- Some contents goes here, and it should be hidden -->
</div>
<div id="displayArea">
<!-- switch between contentA and contentB on a timer say every 5 seconds -->
</div>
Do not use the .html() function to copy content from one place to another. HTML is a serialisation format designed to carry DOM structures from a server to a client. Once the page is in a DOM structure you should manipulate that DOM structure directly using DOM methods. Using .html() to serialise a DOM node and then recreate it somewhere else risks losing things like event handlers, other hidden data, etc.
On that basis, to copy the current contents of a div into another:
var $contents = $('#contentA').contents().clone(); // copy the source element's contents
$('#displayArea').empty().append($contents); // drop them into the destination
In full:
(function() {
var delay = 3000;
var state = 0;
(function next() {
state = 1 - state;
var src = state ? '#contentA' : '#contentB';
var $contents = $(src).contents().clone();
$('#displayArea').empty().append($contents);
setTimeout(next, delay);
})();
})();
Try this :)
<div id='a' style='display: none;'>this is a</div>
<div id='b' style='display: none;'>this is b</div>
<div id='show'></div>
<script>
$(document).ready(function(){
var count = 0;
var content = '';
var j = setInterval(function () {
count++;
if(count%2===0){
content = $('#a').html();
}else{
content = $('#b').html();
}
$('#show').html(content);
}, 5000);
});
</script>
Try this:
var toggle = false;
$("#displayArea").html($("#contentA").html());
setInterval(function() {
$("#displayArea").html(toggle ? $("#contentA").html() : $("#contentB").html());
toggle = !toggle;
}, 5000);
Working DEMO
I don't know if this is what you need but this script should work:
check = true;
$(document).ready(function(){
setInterval(function(){
if(check) {
check = false;
$('#displayArea').html("a");
}
else {
check = true
$('#displayArea').html("b");
}
}, 5000);
});
function doSlides() {
var msg = messages.shift();
messages.push(msg);
$('#displayArea').html(msg);
};
var messages = [
$('#contentA').find('p').html(),
$('#contentB').find('p').html()
];
Demo:
http://jsfiddle.net/8Ux3L/
Here's one way to do it using setInterval():
var divs = $('div[id^="content"]').hide(),
i = 0;
function cycle() {
$("#displayArea").html(divs.eq(i).html());
i = ++i % divs.length; // increment i, and reset to 0 when it equals divs.length
}
setInterval(cycle, 2000); //Cycle every 2 seconds
Wrapping in a self executing function:
(function cycle() {
$("#displayArea").html(divs.eq(i).html());
i = ++i % divs.length; // increment i, and reset to 0 when it equals divs.length
setTimeout(cycle, 2000);
})();
DEMO
Try following code
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>
<script>
var divSelected = "A";
function switch1()
{
if (divSelected == "A")
{
$("#displayArea").text($("#contentA").text());
divSelected = "B";
}
else
{
$("#displayArea").text($("#contentB").text());
divSelected = "A";
}
}
$(document).ready(function()
{
var test = setInterval( "switch1()" , 5000);
});
</script>
</head>
<body>
<div id="contentA" style = "display:none;">
Contect A
</div>
<div id="contentB" style = "display:none;">
Content B
</div>
<div id="displayArea">
</div>
</body>
</html>
Use an interval to trigger a function every x seconds, then jQuery replaceWith to swap the divs. If you don't want to replace the actual node but just the contents, then .html() is probably the way to go.
I'm attempting to run multiple animations (slideshows of sorts) on one page, but the code is only working for one of the (in my case) 3 slideshows that are actually present.
The issue is not with the animation but with the actual initialisation and running of functions (explained better below by looking at the code):
The HTML:
<div class="someclass1" rel="slideshow" type="fade" duration=8500>
<div class="wrapper">...</div>
<div class="wrapper">...</div>
</div>
<div class="someclass2" rel="slideshow" type="slide" duration=4000>
<div class="wrapper">...</div>
<div class="wrapper">...</div>
</div>
<div class="someclass3" rel="slideshow" type="fade" duration=5000>
<div class="wrapper">...</div>
<div class="wrapper">...</div>
</div>
jQuery:
$(function() {
var plays = [];
var duration = 0;
var targets = [];
var t = "";
var $obs = $('div[rel="slideshow"]')
for(var x = 0; x < $obs.length; x++){
$obs.eq(x).children('.wrapper').eq(0).addClass('active');
$obs.eq(x).children('.wrapper').css({opacity: 0.0});
$obs.eq(x).children('.active').css({opacity: 1.0});
$obs.eq(x).children('.navigation a.slide-buttons').eq(0).addClass('current');
// Set duration
duration = $obs.eq(x).attr('duration');
// Set target
targets = $obs.eq(x).attr('class').split(' ');
t = '';
for(var i=0; i<targets.length; i++){
t += '.' + targets[i];
}
if($obs.eq(x).attr('type')==='fade'){
plays[x] = setInterval(function(){fadeSwitch(t);}, duration);
}
else if($obs.eq(x).attr('type')==='slide'){
plays[x] = setInterval(function(){slideSwitch(t);}, duration);
}
}
});
Through testing, I have shown that the loop runs successfully and passes the appropriate target and duration to either fadeSwitch or slideSwitch for all 3 runs of the loop.
fadeSwitch and slideSwitch are identical except for the animation part, for example:
function fadeSwitch(target) {
var $active = $(target+' .active');
if ( $active.length === 0 ){ $active = $(target+' .wrapper:first');}
var $next = $active.next('.wrapper').length ? $active.next('.wrapper')
: $(target+' .wrapper:first');
// FADE ANIMATIONS
$active.animate({opacity : 0.0}, 500, function() {
$active.addClass('last-active');
});
$next.animate({opacity: 1.0}, 500, function() {
$active.removeClass('active last-active');
$next.addClass('active');
});
}
However this function will run only using the last found target (i.e t = '.someClass3'). Even though by placing console.log alerts in the setInterval functions I know that it is applying the correct variables.
e.g.
plays[0] = setInterval(function(){fadeSwitch('.someclass1');}, 8500);
plays[1] = setInterval(function(){fadeSwitch('.someclass2');}, 4000);
plays[2] = setInterval(function(){fadeSwitch('.someclass3');}, 5000);
Yet as I have tried to (badly) explain, if I place a console.log inside of fadeSwitch to test what is being passed as the target when it runs (remember it is set to run after an interval, so by the time the .someClass1 function runs for the first time, the plays[] array is full and finished) the log shows that the target is always .someClass3 and it never succesfully runs for anything else but that last entered target.
Any suggestions or help is greatly appreciated.
Thank you.
The value of t is being "closed over" by your anonymous functions when you call setInterval. For every iteration of your loop you create a new anonymous function, and like you said, at the time t has the right value.
The problem is that by the time each function executes t's value has changed (it will hold the last value of the loops), and all three anonymous functions refer to the same t variable (that is the nature of a closure and the lexical scoping of javascript). The quick fix is to give each anonymous function the right value and not a reference to t:
Change this:
plays[x] = setInterval(function(){fadeSwitch(t);}, duration);
to this:
plays[x] = setInterval((function(t2){ return function(){ fadeSwitch(t2); }; })(t), duration);
And obviously the same for the same line with slideSwitch.
Another thing I felt I should point out: You're using invalid attributes in your html, consider finding an alternative, like hidden embedded markup (e.g. <div class="duration" style="display:none">5000</div>), or class names, or html5 data attributes, instead of <div duration=5000>