Create infinite loop with moving divs using javascript or jQuery - javascript

I need to simulate a band that moves from left to right continuously, carrying 15 divs on it and moving them in a circle, like a carousel. When they reach the right margin to appear from the left.
I have the code that works for 1 div(more or less), but Im having troubles making the loop that includes all 15 divs.
What am I missing?
Here's what I have so far:
HTML
<body>
<div id="fooObject0">1</div>
<div id="fooObject1">2</div>
....
<div id="fooObject13">14</div>
<div id="fooObject14">15</div>
</body>
CSS
body {
font:76% normal verdana,arial,tahoma;
width:600px;
height:600px;
position:relative;
margin:0 auto;
border:1px solid;
}
div {
position:absolute;
left:0px;
top:8em;
width:55px;
height:70px;
line-height:3em;
background:#99ccff;
border:1px solid #003366;
white-space:nowrap;
padding:0.5em;
}
javascript
var foo = null; // object
function doMove(id) {
foo = document.getElementById(id);
foo.style.left = parseInt(foo.style.left)+1+'px';
setTimeout(doMove(id),20); // call doMove in 20msec
if(foo.style.left == "600px") {
foo.style.left = 0;
}
}
function init() {
for(i=0;i<15;i++){
var foo = document.getElementById('fooObject' + i); // get the "foo" object
foo.style.left = -i*55+'px'; // set its initial position to 0px
doMove('fooObject' + i); // start animating
console.log('fooObject' + i);
}
}
window.onload = init;
Thank you in advance!

It call an invalid function setTimeout(doMove(id), 20);.
doMove(id) return undefined, or you use "shared var" (Orientad Object) or doMove need return other function.
Note: var foo = null; // object this variable causes conflict when using setTimeout or setInterval
Try this (read my comments in code):
function doMove(id) {
return function() {
var foo = document.getElementById(id);//Global variable causes conflict when using `setTimeout` or `setInterval`
foo.style.left = parseInt(foo.style.left)+1+'px';
setTimeout(doMove(id),20); //setTimeout need an valid function
if(foo.style.left == "600px") {
foo.style.left = 0;
}
}
}
function init() {
for(i=0;i<15;i++){
var foo = document.getElementById('fooObject' + i);
foo.style.left = -i*55+'px';
doMove('fooObject' + i)(); //doMove need "()", because not run "direct"
console.log('fooObject' + i);
}
}
I modified the code for effect "carousel" and fix the problem with "left" (In 1 to 5 div):
function carrousel() {
var numberOfItems = 15; //Change this if needed
var delay = 1; //Change delay time if needed
var limitArea = 599; //Size limit your carousel area (600px, used 599 for limit with `>`)
var sizeObject = 58; //Width size of objects
//Don't change
var index = 0; //Current index
var allItems = []; //Indexed objects
//Get and index all objects
for(index = 0; index < numberOfItems; index++){//user var
allItems[index] = document.getElementById("fooObject" + index);
}
//Convert position left for int and detect "NaN"
var getPosition = function(pos) {
pos = parseInt(pos);
if (isNaN(pos)) {
return parseInt(-(index * sizeObject));
} else {
return parseInt(pos + 1);
}
};
var doMoveAll = function() {
var foo, post;
for(index = 0; index < numberOfItems; index++){//user var
foo = allItems[index];//Current object
pos = getPosition(foo.style.left);//Get position
//Detect if object are in out area
if(pos > limitArea) {
var beforeItem;
//Get before object for effect carousel
switch(index + 1) {
case 1:
beforeItem = "fooObject" + (numberOfItems - 1);
break;
default:
beforeItem = "fooObject" + (index - 1);
}
//Get position again, but used before object
pos = (
getPosition(document.getElementById(beforeItem).style.left) - sizeObject
);
foo.style.left = pos + "px";
} else {
foo.style.left = pos + "px";
}
}
//Timeout delay
window.setTimeout(doMoveAll, delay);
};
doMoveAll();//Init
};
window.onload = carrousel;

Related

Why my Javascript progress bar doesn't work in IE11?

I have a long running script that broke down in a progress bar:
HTML
<div id="progressbar-wrapper">
<div id="progressbar-outer" style="display: table;margin: 0 auto;background-color: #FFFFFF;border: 5px solid #000000;width: 50%;height: 30px;opacity: 1;z-index: 9998">
<div id="progressbar" style="float:left;width: 0;height: 30px;background-color:#000000;border: 0;opacity: 1;z-index: 99999">
</div>
</div>
<div id="loading-animation" style="position: fixed;top: 150px;left: 0;height: 120px;width: 100%;font-size: 100px;line-height: 120px;text-align: center;color: #000000;z-index: 9999;">
...SAVING...<br /><small>Saving Lines</small>
</div>
</div>
JavaScript
var uiprogressbar = {};
$(function () {
uiprogressbar = {
/** initial progress */
progress: 0,
/** maximum width of progressbar */
progress_max: 0,
/** The inner element of the progressbar (filled box). */
$progress_bar: $('#progressbar'),
/** Method to set the progressbar.
*/
set: function (num) {
if (this.progress_max && num) {
this.progress = num / this.progress_max * 100;
console.log('percent: ' + this.progress + '% - ' + num + '/' + this.progress_max);
this.$progress_bar.width(String(this.progress) + '%');
}
},
fn_wrap: function (num) {
setTimeout(function () {
this.set(num);
}, 0);
}
};
});
//PROGRESS BAR ================================================
//max progress bar
uiprogressbar.progress_max = iterations;
var mainGrid = $("#mainGrid").data("kendoGrid");
var i = 0; //partition #
var j = 0; //line #
var linesUpdated = 0; //update complete #
//make the progress bar visable before updating
$("#progressbar-wrapper").css("display", "block");
//then loop through update grid methods
(function innerloop() {
try {
//If end
var testPart = (partitions[i].length - 1); //30 but starts at 0
} catch (err) {
//exit loop
return;
}
//Get the length of the partition
var thisPartitionLength = (partitions[i].length - 1); //30 but starts at 0
if (thisPartitionLength >= j && successComplete === 2) {
$.each(mainGrid.dataSource.data(),
function () {
if (this.RowSelected === true) {
//get id
var row = mainGrid.dataSource.getByUid(this.uid);
//unselect and turn off dirty
row.set("RowSelected", "false");
row.set("dirty", "false");
linesUpdated++;
}
});
//update line #
j++;
//update progressbar
uiprogressbar.set(linesUpdated);
}
if (j <= thisPartitionLength) {
//loop if not complete with partition
setTimeout(innerloop, 0);
} else {
if (j > thisPartitionLength) {
//if end of partition reset the line # and increase partition # and continue loop
i++;
j = 0;
setTimeout(innerloop, 0);
}
//on complete
if (linesUpdated === iterations) {
//Success message
alert("Saved");
}
}
})();
Which works perfectly in chrome. But doesn't appear AT ALL in IE11 (which is what my clients use). When i run it in IE it even gives and error
...not responding due to a long-running script.
which was the exact reason i implemented a progress bar. Is there something I'm missing that IE has that Chrome does not? How can i change this to make it work in IE?
OK so IE waits till the function is complete to make changes. I has to strip out the progress bar method into a separate function and wrap it in a timeout:
function updateProgressBar(){
//PROGRESS BAR ================================================
//max progress bar
uiprogressbar.progress_max = iterations;
var mainGrid = $("#mainGrid").data("kendoGrid");
var i = 0; //partition #
var j = 0; //line #
var linesUpdated = 0; //update complete #
//make the progress bar visable before updating
$("#progressbar-wrapper").css("display", "block");
//then loop through update grid methods
(function innerloop() {
try {
//If end
var testPart = (partitions[i].length - 1); //30 but starts at 0
} catch (err) {
//exit loop
return;
}
//Get the length of the partition
var thisPartitionLength = (partitions[i].length - 1); //30 but starts at 0
if (thisPartitionLength >= j && successComplete === 2) {
$.each(mainGrid.dataSource.data(),
function () {
if (this.RowSelected === true) {
//get id
var row = mainGrid.dataSource.getByUid(this.uid);
//unselect and turn off dirty
row.set("RowSelected", "false");
row.set("dirty", "false");
linesUpdated++;
}
});
//update line #
j++;
//update progressbar
uiprogressbar.set(linesUpdated);
}
if (j <= thisPartitionLength) {
//loop if not complete with partition
setTimeout(innerloop, 0);
} else {
if (j > thisPartitionLength) {
//if end of partition reset the line # and increase partition # and continue loop
i++;
j = 0;
setTimeout(innerloop, 0);
}
//on complete
if (linesUpdated === iterations) {
//Success message
alert("Saved");
}
}
})();
}
then call it using:
setTimeout(function() {
updateProgressBar();
}, 0);

jQuery animation works with only one element

I need to make it working for all my elements under Which nothing should fade (images).
Currently works only for the div.logo tag
I guess at the moment the reason mine <h1> element is now allowing animations underneath is that when I am getting the .top(), .left() and so on, you are doing it for the last element in the list.
I need to get the borders of each element in the resulting list.
Any help would be much appreciated
Demo: http://jsfiddle.net/z9b8S/
JS:
function displayThese(selectorString) {
var $heading = $(selectorString);
var h1top = $heading.position().top;
var h1bottom = h1top + $heading.height();
var h1left = $heading.position().left;
var h1right = h1top + $heading.width();
var divs = $('li').filter(function () {
var $e = $(this);
var top = $e.position().top;
var bottom = top + $e.height();
var left = $e.position().left;
var right = left + $e.width();
return top > h1bottom || bottom < h1top || left > h1right || right < h1left;
});
return divs;
}
(function fadeInDiv() {
var divsToChange = displayThese('h1, div.logo');
var elem = divsToChange.eq(Math.floor(Math.random() * divsToChange.length));
if (!elem.is(':visible')) {
elem.prev().remove();
elem.animate({
opacity: 1
}, Math.floor(Math.random() * 1000), fadeInDiv);
} else {
elem.animate({
opacity: (Math.random() * 1)
}, Math.floor(Math.random() * 1000), function () {
window.setTimeout(fadeInDiv);
});
}
})();
$(window).resize(function () {
// Get items that do not change
var divs = $('li').not(displayThese());
divs.css({
opacity: 0.3
});
});

Adding an increase / decrease speed button to slideshow

I need to make a slideshow that has an 'increase speed', 'decrease speed' button as well as pause/play. Im having a hard time and getting confused with the timeout/interval usage.
script:
// creates array and holds images
var imageArray = ['img/br1.jpg', 'img/br2.jpg', 'img/br3.png', 'img/br4.gif', 'img/br5.jpeg', 'img/br6.jpeg', 'img/br7.jpeg'];
// set the array to start at 0
var i = 0;
// create function 'slideShow'
function slideShow() {
// creates variable 'div' to load images into a div selected using 'getElementById'
var div = document.getElementById('slideshowdiv');
div.innerHTML = '<img src="' + imageArray[i] + '" />';
//increment i by 1
i++;
// checks if i is greater than or equal to the length
if(i >= imageArray.length) {
// if true, resets value to 0
i = 0;
};
// every 2 seconds change image
timer = setTimeout('slideShow()', 2000);
};
function stopShow() {
clearTimeout(timer);
};
function playShow() {
timer = setTimeout('slideShow()', 2000);
};
function increase() {
};
function decrease() {
};
html:
<body onload="slideShow();">
<div id="slideshowdiv"></div>
<div class="change">
<button onclick="stopShow()">Stop</button>
<button onclick="playShow()">Play</button>
<button onclick="increase()">Speed up slideshow</button>
<button onclick="decrease()">Slow down slideshow</button>
</div>
you could try to change the fixed value with a var:
// creates array and holds images
var imageArray = ['img/br1.jpg', 'img/br2.jpg', 'img/br3.png', 'img/br4.gif', 'img/br5.jpeg', 'img/br6.jpeg', 'img/br7.jpeg'];
// set the array to start at 0
var i = 0;
var speed = 2000;
var minSpeed = 3000;
var maxSpeed = 0;
// create function 'slideShow'
function slideShow() {
// creates variable 'div' to load images into a div selected using 'getElementById'
var div = document.getElementById('slideshowdiv');
div.innerHTML = '<img src="' + imageArray[i] + '" />';
//increment i by 1
i++;
// checks if i is greater than or equal to the length
if(i >= imageArray.length) {
// if true, resets value to 0
i = 0;
};
// every 2 seconds change image
timer = setTimeout('slideShow()', speed);
};
function stopShow() {
clearTimeout(timer);
};
function playShow() {
timer = setTimeout('slideShow()', speed);
};
function increase() {
if(speed -100 > maxSpeed )
speed -= 100;
};
function decrease() {
if(speed +100 <= minSpeed)
speed += 100;
};
What about something like this?
function playShow(playspeed) {
timer = setTimeout('slideShow()', playspeed);
};
function increase() {
var increase_to=10000;
playshow(increase_to);
};
function decrease() {
var decrease_to=100;
playshow(decrease_to);
}

How to dynamically add elements via jQuery

The script below creates a slider widget the takes a definition list and turns it into a slide deck. Each dt element is rotated via css to become the "spine", which is used to reveal that dt's sibling dd element.
What I'm trying to do is to enhance it so that I can have the option to remove the spines from the layout and just use forward and back buttons on either side of the slide deck. To do that, I set the dt's to display:none via CSS and use the code under the "Remove spine layout" comment to test for visible.
This works fine to remove the spines, now I need to dynamically create 2 absolutely positioned divs to hold the left and right arrow images, as well as attach a click handler to them.
My first problem is that my attempt to create the divs is not working.
Any help much appreciated.
jQuery.noConflict();
(function(jQuery) {
if (typeof jQuery == 'undefined') return;
jQuery.fn.easyAccordion = function(options) {
var defaults = {
slideNum: true,
autoStart: false,
pauseOnHover: true,
slideInterval: 5000
};
this.each(function() {
var settings = jQuery.extend(defaults, options);
jQuery(this).find('dl').addClass('easy-accordion');
// -------- Set the variables ------------------------------------------------------------------------------
jQuery.fn.setVariables = function() {
dlWidth = jQuery(this).width()-1;
dlHeight = jQuery(this).height();
if (!jQuery(this).find('dt').is(':visible')){
dtWidth = 0;
dtHeight = 0;
slideTotal = 0;
// Add an element to rewind to previous slide
var slidePrev = document.createElement('div');
slidePrev.className = 'slideAdv prev';
jQuery(this).append(slidePrev);
jQuery('.slideAdv.prev').css('background':'red','width':'50px','height':'50px');
// Add an element to advance to the next slide
var slideNext = document.createElement('div');
slideNext.className = 'slideAdv next';
jQuery(this).append(slideNext);
jQuery('.slideAdv.next').css('background':'green','width':'50px','height':'50px');
}
else
{
dtWidth = jQuery(this).find('dt').outerHeight();
if (jQuery.browser.msie){ dtWidth = jQuery(this).find('dt').outerWidth();}
dtHeight = dlHeight - (jQuery(this).find('dt').outerWidth()-jQuery(this).find('dt').width());
slideTotal = jQuery(this).find('dt').size();
}
ddWidth = dlWidth - (dtWidth*slideTotal) - (jQuery(this).find('dd').outerWidth(true)-jQuery(this).find('dd').width());
ddHeight = dlHeight - (jQuery(this).find('dd').outerHeight(true)-jQuery(this).find('dd').height());
};
jQuery(this).setVariables();
// -------- Fix some weird cross-browser issues due to the CSS rotation -------------------------------------
if (jQuery.browser.safari){ var dtTop = (dlHeight-dtWidth)/2; var dtOffset = -dtTop; /* Safari and Chrome */ }
if (jQuery.browser.mozilla){ var dtTop = dlHeight - 20; var dtOffset = - 20; /* FF */ }
if (jQuery.browser.msie){ var dtTop = 0; var dtOffset = 0; /* IE */ }
if (jQuery.browser.opera){ var dtTop = (dlHeight-dtWidth)/2; var dtOffset = -dtTop; } /* Opera */
// -------- Getting things ready ------------------------------------------------------------------------------
var f = 1;
var paused = false;
jQuery(this).find('dt').each(function(){
jQuery(this).css({'width':dtHeight,'top':dtTop,'margin-left':dtOffset});
// add unique id to each tab
jQuery(this).addClass('spine_' + f);
// add active corner
var corner = document.createElement('div');
corner.className = 'activeCorner spine_' + f;
jQuery(this).append(corner);
if(settings.slideNum == true){
jQuery('<span class="slide-number">'+f+'</span>').appendTo(this);
if(jQuery.browser.msie){
var slideNumLeft = parseInt(jQuery(this).find('.slide-number').css('left'));
if(jQuery.browser.version == 6.0 || jQuery.browser.version == 7.0){
jQuery(this).find('.slide-number').css({'bottom':'auto'});
slideNumLeft = slideNumLeft - 14;
jQuery(this).find('.slide-number').css({'left': slideNumLeft})
}
if(jQuery.browser.version == 8.0 || jQuery.browser.version == 9.0){
var slideNumTop = jQuery(this).find('.slide-number').css('bottom');
var slideNumTopVal = parseInt(slideNumTop) + parseInt(jQuery(this).css('padding-top')) - 20;
jQuery(this).find('.slide-number').css({'bottom': slideNumTopVal});
slideNumLeft = slideNumLeft - 10;
jQuery(this).find('.slide-number').css({'left': slideNumLeft})
jQuery(this).find('.slide-number').css({'marginTop': 10});
}
} else {
var slideNumTop = jQuery(this).find('.slide-number').css('bottom');
var slideNumTopVal = parseInt(slideNumTop) + parseInt(jQuery(this).css('padding-top'));
jQuery(this).find('.slide-number').css({'bottom': slideNumTopVal});
}
}
f = f + 1;
});
if(jQuery(this).find('.active').size()) {
jQuery(this).find('.active').next('dd').addClass('active');
} else {
jQuery(this).find('dt:first').addClass('active').next('dd').addClass('active');
}
jQuery(this).find('dt:first').css({'left':'0'}).next().css({'left':dtWidth});
jQuery(this).find('dd').css({'width':ddWidth,'height':ddHeight});
// -------- Functions ------------------------------------------------------------------------------
jQuery.fn.findActiveSlide = function() {
var i = 1;
this.find('dt').each(function(){
if(jQuery(this).hasClass('active')){
activeID = i; // Active slide
} else if (jQuery(this).hasClass('no-more-active')){
noMoreActiveID = i; // No more active slide
}
i = i + 1;
});
};
jQuery.fn.calculateSlidePos = function() {
var u = 2;
jQuery(this).find('dt').not(':first').each(function(){
var activeDtPos = dtWidth*activeID;
if(u <= activeID){
var leftDtPos = dtWidth*(u-1);
jQuery(this).animate({'left': leftDtPos});
if(u < activeID){ // If the item sits to the left of the active element
jQuery(this).next().css({'left':leftDtPos+dtWidth});
} else{ // If the item is the active one
jQuery(this).next().animate({'left':activeDtPos});
}
} else {
var rightDtPos = dlWidth-(dtWidth*(slideTotal-u+1));
jQuery(this).animate({'left': rightDtPos});
var rightDdPos = rightDtPos+dtWidth;
jQuery(this).next().animate({'left':rightDdPos});
}
u = u+ 1;
});
setTimeout( function() {
jQuery('.easy-accordion').find('dd').not('.active').each(function(){
jQuery(this).css({'display':'none'});
});
}, 400);
};
jQuery.fn.activateSlide = function() {
this.parent('dl').setVariables();
this.parent('dl').find('dd').css({'display':'block'});
this.parent('dl').find('dd.plus').removeClass('plus');
this.parent('dl').find('.no-more-active').removeClass('no-more-active');
this.parent('dl').find('.active').removeClass('active').addClass('no-more-active');
this.addClass('active').next().addClass('active');
this.parent('dl').findActiveSlide();
if(activeID < noMoreActiveID){
this.parent('dl').find('dd.no-more-active').addClass('plus');
}
this.parent('dl').calculateSlidePos();
};
jQuery.fn.rotateSlides = function(slideInterval, timerInstance) {
var accordianInstance = jQuery(this);
timerInstance.value = setTimeout(function(){accordianInstance.rotateSlides(slideInterval, timerInstance);}, slideInterval);
if (paused == false){
jQuery(this).findActiveSlide();
var totalSlides = jQuery(this).find('dt').size();
var activeSlide = activeID;
var newSlide = activeSlide + 1;
if (newSlide > totalSlides) {newSlide = 1; paused = true;}
jQuery(this).find('dt:eq(' + (newSlide-1) + ')').activateSlide(); // activate the new slide
}
}
// -------- Let's do it! ------------------------------------------------------------------------------
function trackerObject() {this.value = null}
var timerInstance = new trackerObject();
jQuery(this).findActiveSlide();
jQuery(this).calculateSlidePos();
if (settings.autoStart == true){
var accordianInstance = jQuery(this);
var interval = parseInt(settings.slideInterval);
timerInstance.value = setTimeout(function(){
accordianInstance.rotateSlides(interval, timerInstance);
}, interval);
}
jQuery(this).find('dt').not('active').click(function(){
var accordianInstance = jQuery(this); //JSB to fix bug with IE < 9
jQuery(this).activateSlide();
clearTimeout(timerInstance.value);
timerInstance.value = setTimeout(function(){
accordianInstance.rotateSlides(interval, timerInstance);
}, interval);
});
if (!(jQuery.browser.msie && jQuery.browser.version == 6.0)){
jQuery('dt').hover(function(){
jQuery(this).addClass('hover');
}, function(){
jQuery(this).removeClass('hover');
});
}
if (settings.pauseOnHover == true){
jQuery('dd').hover(function(){
paused = true;
}, function(){
paused = false;
});
}
});
};
})(jQuery);
Creating elements in jQuery is easy:
$newDiv = $('<div />');
$newDiv.css({
'position': 'absolute',
'top': '10px',
'left': '10px'
});
$newDiv.on('click', function() {
alert('You have clicked me');
});
$('#your_container').append($newDiv);

show and hide several random divs using jquery

i am developing a jquery application. I have 10 divs with quotes. I am trying to create a function that takes a number and randomly displays that number of quotes from the 10 divs for 10 seconds and hide the divs. Then repeat the process again. I have not been able to do it please help me out. here is my code:
$(document).ready(function(){
var div_number = 4;
var used_numbers = new Array();
var todo = setInterval(showQuotes(),3000);
function showQuotes(){
used_numbers.splice(0,used_numbers.length);
$('.quotes').hide();
for(var inc = 0; inc<div_number; inc++) {
var random = get_random_number();
$('.quotes:eq('+random+')').show();
}
$('.quotes').fadeOut(3000);
}
function get_random_number(){
var number = randomFromTo(0,9);
if($.inArray(number, used_numbers) != -1) {
get_random_number();
}
else {
used_numbers.push(number);
return number;
}
}
function randomFromTo(from, to){
return Math.floor(Math.random() * (to - from + 1) + from);
}
});
Changes I made:
hide the .quotes on launch via a stylesheet
run showQuotes() once before setInterval(showQuotes,10000), and
add a .delay() before fading the quotes out
Py's 'return' added to get_random_number
http://jsfiddle.net/cMQdj/1/
the changed JavaScript:
$(document).ready(function () {
var div_number = 4;
var used_numbers = new Array();
showQuotes();
var todo = setInterval(showQuotes, 10000);
function showQuotes() {
used_numbers.splice(0, used_numbers.length);
$('.quotes').hide();
for (var inc = 0; inc < div_number; inc++) {
var random = get_random_number();
$('.quotes:eq(' + random + ')').show();
}
$('.quotes').delay(6000).fadeOut(3000);
}
function get_random_number() {
var number = randomFromTo(0, 9);
if ($.inArray(number, used_numbers) != -1) {
return get_random_number();
} else {
used_numbers.push(number);
return number;
}
}
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
});
and add to your stylesheet:
.quotes {display:none}
I didn't test everything, but i already see one point that might block you, the get_random_number does not always return a number. To do so, it should be
function get_random_number(){
var number = randomFromTo(0,9);
if($.inArray(number, used_numbers) != -1)
{
return get_random_number();
}
else
{
used_numbers.push(number);
return number;
}
}
Hope that helps.

Categories