case, setinterval and listing only selected arrays - javascript

I'm trying to make interval function, which will change selected div every 10seconds. When i'm on first page, i want it to show items from first array, when im on second i want array 2, etc. this is what i got so far:
var timedFunc = '';
var index= new Array(20)
index[0]="index1";
index[1]="index2.";
..
var indextwo= new Array(20)
indextwo[0]="index1";
indextwo[1]="index2";
var tmp = 0;
function display_index(nameofarray) {
if (tmp < 0) { tmp = nameofarray.length-1; }
if (tmp > nameofarray.length-1) { return false; }
document.getElementById('robot').innerHTML = nameofarray[tmp];
tmp = tmp + 1;
}
function indexInterval(m) {
switch(m) {
case 1: timeFunc = setInterval("display_index(index)",1000);
case 2: timeFunc = setInterval("display_index(indextwo)",1000);
case 3: timeFunc = setInterval("display_index(indexthree)",1000);
case 4: timeFunc = setInterval("display_index(indexfour)",1000);
}
}

To cycle through an array on an interval timer, you can pass the desired array to a function and then use that function to cycle through the array on an interval timer like this:
var index0 = ["text1", "text2", "text3"];
var index1 = ["text1", "text2", "text3"];
function startMyInterval(array) {
var index = 0;
var item = document.getElementById('robot');
setInterval(function() {
// if we reached the end of the array, start back at beginning
if (index >= array.length) {
index = 0;
}
item.innerHTML = array[index];
++index;
}, 10000);
}
// figure out which array of text values you want to use
// for this particular page index0 or index1
// and pass that array to startMyInterval()
startMyInterval(x);
This type of implementation avoids the switch statement and avoids passing text to setInterval(). It also uses a function closure to keep track of the state that the setInterval() callback needs.

Related

Pick random index and change till all unique are done then restart

I have image gallery with 6 image slot and i have a array with n no of image object like this
"src" : {
"1x" : "/clients/Logo-1.png",
"2x" : "/clients/Logo-1#2x.png",
"3x" : "/clients/tLogo-1#3x.png"
},
"alt" : "xyz"
}
what i want is to show random 6 image from array and then every 5 sec randomly one slot need to be change and get update with a new unique image which must not be in first 6 slot and then after finishing all it should continue the 5 sec change with a new unique image which must not be in those 6 slot.
what i have tried
let randomList = this.shuffleArray(this.LogosListObj);
let FirstSixImg = randomList.slice(0, 6);
let LeftAllImg = randomList.slice(6 + 1);
let RandomIndex = this.randomNoRepeats([0,1,2,3,4,5])
let RandomSecoundImg = this.randomNoRepeats(Array.apply(null, new Array(LeftAllImg.length)).map(function(el, i) {return i}))
let RandomFirstImg = this.randomNoRepeats(Array.apply(null, new Array(FirstSixImg.length)).map(function(el, i) {return i}))
this.ImageToShowList = [...FirstSixImg];
let checkArr = [];
let checkArr2 = [];
let flag = false;
let index,secndIndex,thirdIndex;
const LogoChange = (arr) =>{
if(!flag) {
secndIndex = RandomSecoundImg();
console.log('1st',secndIndex)
if(checkArr.indexOf(secndIndex) == -1) {
index = RandomIndex();
checkArr.push(secndIndex)
ctl.ImageToShowList[index] = {};
ctl.ImageToShowList[index] = LeftAllImg[secndIndex];
Vue.set(ctl.ImageToShowList, index, LeftAllImg[secndIndex])
ctl.PreviousImgObj = {...LeftAllImg[secndIndex]};
} else {
flag = true;
checkArr = [];
}
}
if(flag) {
thirdIndex = RandomFirstImg();
console.log('2nd',thirdIndex)
if(checkArr2.indexOf(thirdIndex) == -1) {
checkArr2.push(thirdIndex)
ctl.ImageToShowList[thirdIndex] = {};
ctl.ImageToShowList[thirdIndex] = FirstSixImg[thirdIndex];
Vue.set(ctl.ImageToShowList, thirdIndex, FirstSixImg[thirdIndex])
ctl.PreviousImgObj = {...FirstSixImg[thirdIndex]};
}else {
flag = false;
checkArr2 = [];
LogoChange();
}
}
}
setInterval(()=>{
LogoChange();
}, 1000);
where randomNoRepeats is
randomNoRepeats : (array) => {
var copy = array.slice(0);
return function() {
if (copy.length < 1) { copy = array.slice(0); }
var index = Math.floor(Math.random() * copy.length);
var item = copy[index];
copy.splice(index, 1);
return item;
};
and shuffleArray is
shuffleArray : (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
},
this.ImageToShowList is used in html part to display
Any help with logic or change will be appreciate.
I have my example fiddle here, but this is the breakdown:
Your data would look something like this:
let galleryPool = [
{
"src" : {
"1x" : "/clients/Logo-1.png",
"2x" : "/clients/Logo-1#2x.png",
"3x" : "/clients/tLogo-1#3x.png"
},
"alt" : "xyz",
"color": "red"
},
...
]
(I added a color property so you could see the changes since I don't actually have any images.)
The first thing I do is drop in my handy-dandy Fisher–Yates shuffle, since this is a great way to get a random element out of an array.
Array.prototype.shuffle = function() {
let currentIndex = this.length, randomIndex;
while (currentIndex != 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[this[currentIndex], this[randomIndex]] = [this[randomIndex], this[currentIndex]];
}
return this;
}
I initialize the gallery first, and set up the 5-second timeout to change images in the gallery.
let displayedGallery = []
initialGallerySetup();
function initialGallerySetup() {
let galleryContainer = document.getElementById("gallery-container")
galleryPool.shuffle()
displayedGallery = galleryPool.splice(0, 6)
for(let index = 0; index < displayedGallery.length; index++) {
let data = displayedGallery[index]
galleryContainer.appendChild(generateGalleryItem(data))
}
galleryTickUpdate()
}
this function makes an img dom element I can then add to the container. I'm using your src here but you can change whatever values in here to alter how all of the images in the gallery are displayed.
function generateGalleryItem(data) {
let item = document.createElement("img")
item.style.backgroundColor = data.color
item.src = data.src[0]
item.className = "gallery-item"
return item
}
This function calls itself every 5 seconds, and will pick a random item from the gallery to swap with another item not currently displayed.
function galleryTickUpdate() {
setTimeout(() => {
let randomIndex = Math.floor(displayedGallery.length * Math.random())
swapItemAtIndex(randomIndex)
galleryTickUpdate()
},5000)
}
Here's the magic. I grab the randomly chosen item out of the displayed gallery items, pick a new item from the unused gallery pool items, put the old one back in the pool and the new one gets pushed back into the gallery display in the same spot.
function swapItemAtIndex(index) {
let galleryContainer = document.getElementById("gallery-container")
let displaySlot = galleryContainer.children[index]
let returning = displayedGallery[index]
galleryPool.shuffle()
let newDisplay = galleryPool.pop();
displayedGallery[index] = newDisplay
galleryPool.push(returning)
galleryContainer.insertBefore(generateGalleryItem(newDisplay), displaySlot)
galleryContainer.removeChild(displaySlot)
}
If you want to enforce running through the whole array, just check when the galleryPool array is empty, then repopulate it and re-run the init function. Otherwise, this will happily run forever.
here is a simple script. you will need the following
pool this will contain all possible values you would like
single function to update the show array
Test Here
I've tried to put as much comments as possible
// Pool with all possible images (you may use any type of text as long as each value is unique)
const pool = [
"1.png",
"2.png",
"3.png",
"4.png",
"5.png",
"6.png",
"7.png",
"8.png",
"9.png",
"10.png",
];
// this will store the "6" unique elements which you will be displaying
let show = [];
// get the first 6 random but unique elements. we will monitor the length of the `show` array
while(show.length < 6){
// randomly sort the pool and get the first element of the sorted array and store it into a `pooled` variable.
let pooled = pool.sort(() => 0.5 - Math.random())[0];
// check if the pooled value exists in the `show` array if it doesnt then add it and repeat the loop till all 6 slots are filled with unique values
if(!show.includes(pooled)){
// add `pooled` item to the `show` array
show.push(pooled);
}
}
// do the same as the above with a slight change, of only replacing one till all are unique.
function after5Mins(){
// get a new random item from the pool
let newPoolItem = pool.sort(() => 0.5 - Math.random())[0];
// using a while loop check if the new `pool item` is in the show array, if not then skip and add it
while(show.includes(newPoolItem)){
newPoolItem = pool.sort(() => 0.5 - Math.random())[0]; // set the pool item to a random one, then loop and check, follow previous comment
}
// once a new un used item is found, then assign it to a random position
show[Math.floor(Math.random()*show.length)] = newPoolItem;
}
// call the after 5 mintes using
setTimeout(()=>{
after5Mins();
}, 300000);

Do something within a JavaScript array for loop

I am trying to figure out a way of how to loop through an array, do something with that array[index] pause function for x seconds and move to next index in that array.
That is what I achieved so far. It prints out the whole array, but I need it to print out only one value, do something with it, then proceed to the next one and so on.
var destinations = ['Greece', 'Maldives', 'Croatia', 'Spain'];
var index = 0;
for (index = 0; index < destinations.length; index++){
console.log(destinations[index]);
};
You could take the iteration protocols with an implementation of Symbol.iterator in Array#[##iterator]() and iterate until no more elements are available.
var destinations = ['Greece', 'Maldives', 'Croatia', 'Spain'],
gen = destinations[Symbol.iterator]();
interval = setInterval(function () {
var g = gen.next();
if (g.done) {
clearInterval(interval);
return;
}
console.log(g.value);
}, 1000);
You can use setTimeout to do this.
var time_between_steps = 1000
var destinations = ['Greece', 'Maldives', 'Croatia', 'Spain']
var index = 0
function nextItem(){
// do things here with destinations[index]
console.log(destinations[index])
index++
// if we have not yet reached the end of the array, run nextItem again after time_between_steps
if(index<=destinations.length-1)
setTimeout(nextItem,time_between_steps)
}
nextItem()
setTimeout can be used here:
Basically, you can define a method processItem and call it with the current parameter. Also the delay can be set with a variable.
After the delay, the method is called with a parameter.
var delay = 1000; // 1 sec
var destinations = ['Greece', 'Maldives', 'Croatia', 'Spain'];
var index = 0;
function processItem(item){
console.log("Item " + item);
// do stuff
}
function iterate(index){
processItem(destinations[index]);
index++;
if (index < destinations.length){
setTimeout(iterate, delay, index);
}
}
iterate(index);

Iterating through object array and changing values of multiple

I have a function where I am sending in an object, wholesaler. There is an array of objects, wholesalers which contains multiple wholesaler objects.
I need the order number of the wholesaler that just came in to be increased by 1 and then find the wholesaler object that has a current ORDER of the new value and subtract 1.
$scope.wholesalers = [];
$scope.downWholesaler = function (wholesaler) {
if (wholesaler.id > 0) {
var orderNumber = wholesaler.ORDER;
var orderBelowNumber = orderNumber + 1;
angular.forEach($scope.wholesalers, function (myWholesaler) {
if (myWholesaler.ORDER === orderNumber) {
// raise current order +1
var add = orderNumber + 1
myWholesaler.ORDER = add;
}
//setting it
if (myWholesaler.ORDER === orderBelowNumber) {
//lower one with order below number -1
var subtract = orderNumber - 1;
myWholesaler.ORDER = subtract;
}
});
console.log($scope.wholesalers);
}
};
Above I am working on doing this. I go through $scope.wholesalers and increase the current objects ORDER number and then reduce the one next to it (ORDER +1) down one.
But the ORDER is going down and the next object is not changing at all. What am I doing wrong and how do I fix it?
edit: didn't have lastest code
Fix:
$scope.downWholesaler = function (wholesaler) {
if (wholesaler.id > 0) {
var add = parseInt(wholesaler.ORDER) + 1
angular.forEach($scope.wholesalers, function (myWholesaler) {
if (myWholesaler.ORDER == add) {
myWholesaler.ORDER = parseInt(myWholesaler.ORDER) - 1;
}
});
wholesaler.ORDER = add;
console.log($scope.wholesalers);
}
};

How do I write a for loop that stops at every third index item, and continues inserting items to a new (carousel) page?

I have the following code:
page.listSuccess = function (data, status, xhr) {
console.log(data);
if (data && data.items) {
var itemsQty = Math.ceil(data.items.length / 3);
for (var index = 0; index < itemsQty; index++) {
var itemData = {};
var itemClone = page.insertItemDOM(itemData);
if (index == 0) {
itemClone.addClass("active");
console.log(itemClone);
}
}
}
for (var index = 0; index < data.items.length; index++) {
var testimonialData = {}
testimonialData.title = data.items[index].title;
testimonialData.body = data.items[index].body;
testimonialData.starRating = data.items[index].starRating;
testimonialData.id = data.items[index].id;
page.insertTestimonialDOM(testimonialData);
}
}
At the moment, this code inserts all(5) my testimonials on one page. I need three per page, but I'm unsure as to how to go about it.
itemClone = a page on the carousel
testimonialData = a testimonial
insertItemDOM function =
page.insertItemDOM = function (itemData) {
var newItem = $($("#itemTemplate").html()).clone();
var targetLoc = $('.carousel-inner');
targetLoc.attr("data-target", "true");
targetLoc.append(newItem);
return newItem;
}
insertTestimonialDOM function =
page.insertTestimonialDOM = function (testimonialData) {
var newTemplate = $($("#testimonialTemplate").html()).clone();
newTemplate.find('.title').html(testimonialData.title);
newTemplate.find('.body').html(testimonialData.body);
newTemplate.find('.starRating').html(testimonialData.starRating);
var targetLoc = $('.carousel-inner');
targetLoc.attr("data-target", "true");
targetLoc.append(newTemplate);
}
Let me explain the concept for you. What you want is after every 3 loop execution the loop shall work it again and enter details in a new page.
Let's make two function.
var index;
var theinitial = function(z)
{
index = z
var counter = 1;
insertionfunction();
}
var insertionfunction = function()
{
for (var zzz = index; zzz < data.items.length; zzz++) {
if (counter <= 3)
{
itemClone = page.insertItemDOM(itemData);
}
else
{
theinitial(zzz);
}
}
Here the first request you make to 'theinitial function' with 1 as value of z then the function will call the insertion function and now the loop will run for 3 times then after three times the value of zzz is used to call the initial function again. Now your index is 4, hence the loop will start from 4th element and run for 3 more times as counter is reinitialized to 1.
I don't really know how your page insertion thing works therefore I am explaining the concept to you.

setInterval delays

I'm trying to execute a rotating banner (Calling it through an array). I set an interval but the image only shows after 10 seconds (10000) and only then begins the rotation. I removed the cluttered HTML of the array, but here's the rest of it:
var current = 0;
var banners = new Array();
banners[0]=;
banners[1]=;
banners[2]=;
banners[3]=;
var myTimeout = setInterval("rotater()",10000);
function rotater() {
document.getElementById("placeholderlayer").innerHTML=banners[current];
if(current==banners.length-1){
current = 1;
}else{
current += 1;
}
}
window.onload = rotater();
window.onload = rotater;
is the correct syntax. You don't want to call the function. However, the bulletproof solution is rather this:
onload = function() {
rotater();
window.myTimeout = setInterval(rotater, 10000); // Never pass a string to `setInterval`.
};
ProTip™: Don't use new Array(), use an array literal. For example, this:
var arr = new Array();
arr[0] = 'Hello';
arr[1] = 'world!';
Should be written as:
var arr = ['Hello', 'world!'];
Just a comment:
Instead of:
if(current==banners.length-1) {
current = 1;
} else {
current += 1;
}
you can do:
current = ++current % banners.length;

Categories