JQuery text rotator - javascript

I am trying to create a simple jquery text rotator:
I have a span in which text should fade in and out.
There are similar questions here on stackoverflow but I can't apply their solutions to my situation
Here is what I wrote so far and I was wondering why this code doesn't work:
var i=0;
function rotate(spanid,w1,w2,w3){
var myspan = "#"+spanid;
var words = [w1,w2,w3];
$(words[i]).appendTo(myspan).fadeIn(2000).delay(2000).fadeOut(2000);
i==words.length? i=0:i++;
rotate(spanid,w1,w2,w3);
}
Is the approach to the problem correct? Why isn't this code working?
Thank you all in advance!
EDIT
The code isn't working as nothing is showing up.
Here is the html section relative to the function:
<p>Blah blah blah <span id="rotate"></span> blah blah blah </p>
<script>
$(rotate("rotate","word1","word2","word3"));
</script>

Okay, i've had a quick play and expanded it a little for you..
JS Fiddle: http://jsfiddle.net/4k3zfv5f/
function rotate(sID,aWords, iIndex){
$("#"+sID).html(aWords[iIndex]).fadeIn(1000, function() {
iIndex==(aWords.length-1)? iIndex=0:iIndex++;
$("#"+sID).fadeOut(1000, function() {
rotate(sID,aWords,iIndex);
});
});
}
rotate("test1",["Hello", "World", "Foo"], 0);
rotate("test3",["John", "Bob", "Billy", "Mike", "Larry"], 0);
EDIT - UPDATE
Basically there were a few corrections i had to make, so instead of going over each one.. Will just let you compare the changes.. Part of it is that the fade functions did not wait til they completed, the Delay command only applies to the jquery object and the append i reversed just for my visual sake.
Also the last part as you mentioned in the comments, was to swap appendTo with html.
Just as an extra bonus, a shuffle example:
JS Fiddle Showing With Shuffle Example: http://jsfiddle.net/ye3rjy2v/1/

The logic of the append > fade > delay > fade wasn't really working. I've added a Timeout and a callback function to the fadeout to make it working nicely. Also made it easier to write the call function so you have only one extra parameter. EXAMPLE
var i = 0;
function rotate(spanid, words) {
var arrWords = words.split(',');
var myspan = $('#' + spanid);
i == arrWords.length-1 ? i = 0 : i++;
myspan.text(arrWords[i]);
myspan.fadeIn();
setTimeout(function(){
myspan.fadeOut(400, function() {
rotate(spanid, words);
});
}, 2000);
}
rotate('rotate', 'word1,word2,word3');

$(function () {
function rotate(spanid, arrayOfWords) {
var $mySpan = $("#" + spanid);
(function repeatRotate(index) {
var i = index || 0;
$mySpan.text(arrayOfWords[i]).fadeIn(1000).fadeOut(1000, function () {
i = (i === arrayOfWords.length - 1) ? 0 : ++i;
repeatRotate(i);
});
})();
}
rotate("rotate", ["word1", "word2", "word3"]);
});
JSBIN DEMO
The above code will rotate the words defined in array after particular time interval.

Related

Refresh a DIV content after faded it out

I got X DIV (TopRowRight1, TopRowRight2, TopRowRight3...) , each containing a different Google Geochart generated by a php page : GeochartPerProvince.php?template=X.
function getResult(template){
jQuery.post("GeochartPerProvince.php?template="+template,function( data ) {
jQuery("#TopRowRight"+template).html(data);
});
}
jQuery().ready(function(){
getResult(1);
setInterval("getResult(1)",10000);
getResult(2);
setInterval("getResult(2)",10000);
getResult(3);
setInterval("getResult(3)",10000);
});
jQuery(function () {
var $els = $('div[id^=TopRowRight]'),
i = 0,
len = $els.length;
$els.slice(1).hide();
setInterval(function () {
$els.eq(i).fadeOut(function () {
i = (i + 1) % len
$els.eq(i).fadeIn();
})
}, 5000)
});
Every 5 seconds, i fade out one and fade in the next one. This works perfectly.
For now, the php page in the DIV is refreshed every 10 seconds. This works too.
But what i dream about is that the php page in the DIV is reloaded AFTER the DIV is faded out instead of every 10 seconds. How to do it?
Solved. How it works properly:
function getResult(template){
jQuery.post("GeochartPerProvince.php?template="+template,function( data ) {
jQuery("#TopRowRight"+template).html(data);
});
}
$(document).ready(function(){
getResult(0);
getResult(1);
getResult(2);
//setInterval("getResult(2)",10000); <== keep this piece of code in case of need.
});
$(document).ready(function () {
var $els = $('div[id^=TopRowRight]'),
i = 0,
len = $els.length;
$els.slice(1).hide();
setInterval(function () {
$els.eq(i).fadeOut(function () {
i = (i + 1) % len
getResult(i);
$els.eq(i).fadeIn();
})
}, 10000)
});
You're already using a callback function after the element has been faded out. So why not call your getResult function inside it?
$el.fadeOut(function(){
// stuff
getResult(i)
})
I have a few suggestions and an example code for you to achieve what you need :
Use $ instead of jQuery for easier reading / writing
$(document).ready is the proper start point for dom related functions
If only one div is visible at a time, do not use too many divs. Most of the time one div is enough for alternating / refreshing content. If there is in/out animation or cross-fading, two divs would be needed. (Example below uses two divs)
Avoid using setInterval except you really really need. Logics with setTimeout better handles unexpected delays such $.post may cause.
start with html code something like this:
...
<div class="top-row-right" style="display:block"></div>
<div class="top-row-right" style="display:none"></div>
...
js:
$(document).ready( function() {
var len = 4; // 'I got X DIV..' This is where we put the value of X.
var template = -1;
function refreshChart() {
template = (template + 1) % len;
$.post("GeochartPerProvince.php?template="+template, function(data) {
var offscreenDiv = ('.top-row-right:hidden');
var onscreenDiv = ('.top-row-right:visible');
offScreenDiv.html(data);
onScreenDiv.fadeOut('slow', function() {
offScreenDiv.fadeIn();
setTimeout(refreshChart, 10000);
});
});
}
refreshChart();
});

Array image looping in JavaScript

I have been trying to loop traffic light images in JavaScript. I'm not sure what to do, can someone give advice.
A slight modification to your code. Here is a working sample.
I removed the dvi.count counter as it creates more confusion, We need to maintain the counters outside the function. I changed the logic to pass around the index of the image in the array starting from 0.
var image = new Array("red.jpg", "redamber.jpg", "green.jpg", "amber.jpg");
var timeout;
function stopIt() {
clearTimeout(timeout);
}
function changeimage (images, index) {
var dvi = document.getElementById(images);
if(image.length <= index)
index = 0;
dvi.src = image[index];
dvi.alt = image[index];
timeout = setTimeout('changeimage("' + images + '",' + (index + 1) + ')', 1000);
}
<body onload="changeimage('changer',0)">
<div>
<img src="t1" alt="test1" id="changer" />
</div>
</body>
I have made 3 changes to your code
Fixed the typeo div.count to dvi.count
Corrected the indenting and braces round the if statement (Not strictly necessary, but makes the code way more readable)
Replaced your nasty use of a string parameter in setTimeout to be a function reference
function changeimage(images){
var dvi=document.getElementById(images);
if(!dvi.count || dvi.count == image.length ){
dvi.count=0;
}
dvi.src=image[dvi.count];
dvi.alt=image[dvi.count];
dvi.count=dvi.count+1;
timeout=setTimeout(function(){
changeimage(images);
},3500);
}
Live example: https://jsfiddle.net/Lofug2hf/1/

setTimeout not working, other methods of queuing in a for loop?

Code below (the divs are shaded in my real example, I want to sequentially decrease their opacity to 0 so each disappears, in order.
I tried to doing this without using setTimeout, but all of the divs disappeared simultaneously - its good to know that the part of the code that changes the opacity works, but I cant seem to get them to work sequentially.
When I try to use setTimeout (which I presume I am implementing incorrectly),nothing happens!
Any help would be really appreciated with this, I'm fairly new to JavaScript and haven't touched it in a while and tutorials haven't been able to help me.
<body>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
<script type="text/javascript">
// the divs that we want to cycle through are named here.
var divs = ["#div1", "#div2", "#div3", "#div4"];
var divsLength = divs.length;
for (var i = 0; i < divsLength; i++) {
setTimeout(function(){
$(divs[i]).fadeTo(1000, 0, function() {
});
},1500);
};
</script>
</body>
Here's a way you should be able to do this without setTimeout:
function doFade(items, index) {
$(items[index]).fadeTo(1000, 0, function() {
doFade(items, index + 1);
});
}
doFade(divs, 0);
If you're targetting browsers that support ES5 (most modern versions do), then you can further simplify doFade:
function doFade(items, index) {
$(items[index]).fadeTo(1000, 0, doFade.bind(this, items, index + 1));
}
working jsfiddle
You can use a recursive function to do that kind of thing, something like that :
function seqFade($el){
$el.first().fadeOut(500, function(){ //Take the first element and fade it out
seqFade($el.slice(1)); //Recall the function when complete with the same set of element minus the first one.
})
}
seqFade($('div')); //Call the function
http://jsfiddle.net/L2fvdfy2/
In your code, it could look like that :
function seqFade($el){
$el.first().fadeOut(500, function(){
seqFade($el.slice(1));
})
}
seqFade($('#div1, #div2, #div3, #div4'));
It's because when the timeout finally fires the variable "i" only has the last index value. Also the loop will start all the timeouts at almost the same time.
There are other ways to accomplish it but this might work with minimal changes to your code.
Try this:
<script type="text/javascript">
var divs = ["#div1", "#div2", "#div3", "#div4"];
var divsLength = divs.length;
for (var i = 0; i < divsLength; i++) {
setTimeout((function(index) {
return function(){
$(divs[index]).fadeTo(1000, 0, function() { });
}
)(i)),1500 + (i * 1500));
};
</script>
</body>
This will create an instance of the function with it's own copy of the index when it was called. Also increasing the timeout of each timeout will have them execute sequentially.
try this:
// the divs that we want to cycle through are named here.
var divs = ["#div1", "#div2", "#div3", "#div4"];
(function fade(i) {
$(divs[i]).fadeTo(1000, 0, function() {
setTimeout(function() {fade(++i);}, 500);
});
})(0);
for (var i = 1; i <= divsLength; i++) {
setTimeout(function(){
$(divs[i]).fadeTo(1000, 0, function() {
});
},1000*i);
lets try this

Help me simplify this JS code

I'm a beginner in JS and want to know a way to simplify this code. There are 7 different divs with iframes, and also 7 different links. I have shown 1 div with iframe and 1 link. I have no idea where to start. Any help would be greatly appreciated.
NOTE: The code works to my needs, but I just need to simplify it (less js code in html, and more in js file).
JavaScript in .js file:
function show_visibility(){
for(var i = 0,e = arguments.length;i < e;i++){
var myDiv = document.getElementById(arguments[i]).style;
myDiv.display = "block";}
}
function hide_visibility(){
for(var i = 0,e = arguments.length;i < e;i++){
var myDiv = document.getElementById(arguments[i]).style;
myDiv.display = "none";}
}
function refFrame() {
for(var i = 0,e = arguments.length;i < e;i++){
document.getElementById(arguments[i]).src = document.getElementById(arguments[i]).src;
}
}
Div/iframe to be modified:
<div id="r1-box">
<iframe id="frame-box1" class="work" src="youtubelink" width="720" height="405" frameborder="0"></iframe>
</div>
Link to execute JS:
<a id="r1" href="javascript:refFrame('frame-box2','frame-box3','frame-box4','frame-box5','frame-box6','frame-box7');show_visibility('r1-box');hide_visibility('r2-box','r3-box', 'r4-box','r5-box','r6-box','r7-box');">
</a>
As a beginner you shouldn't start using jQuery until you understand Javascript more.
There are a few ways you could simplify this, the most immediate one would be to get the Javascript out of the link and into a Javascript file, or at the top of the page:
window.onload = function() {
document.getElementById('#r1').onclick = function() {
refFrame('frame-box2','frame-box3','frame-box4','frame-box5','frame-box6','frame-box7');
show_visibility('r1-box');
hide_visibility('r2-box','r3-box', 'r4-box','r5-box','r6-box','r7-box');
};
// more...
};
window.onload is an event which fires once the page has - you guessed it - finished loading. There are better ways of doing this, but this is about as basic as it gets. I'd advise you look at javascript domready?
After looking at your code a bit more, I realised all your seven links will do essentially the same thing. You can simply this by using a single function:
function refClick(id) {
var i = 7,
frames = [],
boxes = [];
while(i--) {
if(i != id) {
frames.push('frame-box' + i);
boxes.push('r' + i + '-box');
}
}
refFrame.apply(null, frames);
hide_visibility.apply(null, boxes);
show_visibility('r' + id + '-box');
}
What I'm doing here is looping through 7 times, and building an array of arguments for the refFrame and hide_visibility functions. The id variable tells the loop not to put in that id into the arrays.
Using the .apply method, I can apply an array as the arguments and call it normally.
For each of your links, you can apply the following function
document.getElementById('#r1').onclick = function() {
refClick(1);
};
document.getElementById('#r2').onclick = function() {
refClick(2);
};
//.....
You could start using jQuery.
http://jquery.com/

Help with JQuery Callback

As per my previous question, I have a working animation which fades in and out each element within the div slideshow. The problem is that I want this animation to continue from the beginning once it has reached the last element. I figured that was easy and that I'd just place an infinite loop inside my JQuery function, but for some reason if I insert an infinite loop, no animation displays and the page hangs. I also cannot find anything in the documentation about how properly place a callback. How can I get this code to restart from the beginning of the animation once it finishes iterating over each object and why is an infinite loop not the right way to go about this?
<div id="slideshow">
<p>Text1</p>
<p>Text2</p>
<p>Test3</p>
<p>Text4</p>
</div>
<script>
$(document).ready(function() {
var delay = 0;
$('#slideshow p').each(
function (index, item)
{
$(this).delay(delay).fadeIn('slow').delay(800).fadeOut('slow');
delay += 2200;
}
);
});
</script>
You could do something like this:
$(function() {
var d = 2200;
function loopMe() {
var c = $('#slideshow p').each(function (i) {
$(this).delay(d*i).fadeIn('slow').delay(800).fadeOut('slow');
}).length;
setTimeout(loopMe, c * d);
}
loopMe();
});
You can give it a try here.
Instead of keeping up with a delay, you can just multiple it by the current index in the loop...since the first index is 0, the first one won't be delayed at all, then 2200ms times the amount of elements later, do the loop again. In the above code d is the delay, so it's easily adjustable, and c is the count of elements.
This solution is in my opinion more elegant, also more natural, it is easier to control, to correctly edit values of delays etc. I hope you'll like it.
$(document).ready(function () {
var elementsList = $('#slideshow p');
function animationFactory(i) {
var element = $(elementsList[i % elementsList.length]);
return function () {
element.delay(200).fadeIn('slow').delay(800).fadeOut('slow', animationFactory(i + 1));
};
}
animationFactory(0)();
});

Categories

Resources