Adding increased count to the DOM for every pass - javascript

what I'm hoping to achieve is to increase a count and then append that to the DOM on every pass through using each(). What I have at the moment is the final count added at the end. For example.
Say I have 100 divs, for every pass through it should add the new count as it counts it, like so 1,2,3,4,5,6,7... and so on. But at the moment it counts all the objects and just appends 100 at the end. Please can someone point me in the direction to where I'm going wrong?
I've added a very basic version of what I'm hoping to achieve below... also here is a JSbin (I tried jsfiddle but it seems to be down for me) .
$(".toCount").each(function(i){
$("#count").text(i + 1);
});

$('input').on('click',function () {
var len = $(".toCount").length;
var arr = [];
for (var i = 0; i < len; i++ ) {
arr.push(i+1);
}
$('#count').text(arr.join());
});
I don't know what you mean by 1, 2, 3 ... in case that you want to count the elements step by step you can use setInterval function:
$('input').on('click',function () {
var l = $(".toCount").length,
$c = $('#count'),
i = 0;
var t = setInterval(function() {
i++;
$c.text(i);
if (i === l) clearInterval(t);
}, 10);
});
http://jsbin.com/eronel/17/edit

use append();
Insert content, specified by the parameter, to the end of each element in the set of matched elements.
in your case text() is replacing your div's text so u get 100 at the end ..
$("#count").append(i + 1);

Use append
$("#count").append(i + 1);

Related

How can you dynamically slice an array in Javascript/jQuery?

I have a photo gallery that includes images that will be continuously uploaded. The PHP array has been converted/encoded to a JSON array so that I can manipulate the data with JavaScript.
Ideally, I would like to click a button ("Next Set" in the CodePen example) and load the next set (of 2) thumbnail images. This is in an effort to not load all of the images at once, which could be hundreds.
Problem: I cannot figure out how to dynamically slice the array on click (next 5 images). I can of course load, say, 2 at a time:
myArray.slice(0,2);
myArray.slice(3,5);
However, this will not work because images will be continuously added to the gallery. Furthermore, I would have to have too many sets of the above to keep slicing 5 out at a time.
I have tried:
Splitting the array into smaller arrays
for loops and $.each loops
I essentially need to be able to move the start and end index of the slice by (for example) 2 on click. Right now it just keeps slicing the same two images because the slicing is not dynamic.
Here is my CodePen
I don't think there's a way to do exactly what you want, but you can just keep track of where you were in the array and do a slice from there, like this:
var nextSet = myArray.slice(lastIndex, lastIndex + 2);
Replace your existing click() with this (including the declaration of lastIndex) to try it:
var lastIndex = 0
$('.button').click(function() {
var nextSet = myArray.slice(lastIndex, lastIndex + 2);
lastIndex += 2;
for (var i = 0; i < 2; i++) {
var li = $('<li/>').attr('role', 'menuitem').appendTo('.myList').append('<img src=' + nextSet[i] + '>');
}
});
Note that I've moved the slice() line outside the for loop. There's no need to slice a new array for every iteration.
Here's a CodePen using .slice().
An alternate method is to use to shift() to peel off the first item in the array with each iteration:
var nextItem = myArray.shift()
This is destructive though (it removes the item from the original array), so you'll need to make a copy of the original array first if you want to use it for anything else. Replace your click() with:
$('.button').click(function() {
for (var i = 0; i < 2; i++) {
var nextItem = myArray.shift();
var li = $('<li/>').attr('role', 'menuitem').appendTo('.myList').append('<img src=' + nextItem + '>');
}
});
Here's a CodePen using .shift().
your problem is simple i think. you do a slice and allways get back the same array
var array = [0,1,2,3,4,5];
let newArray1 = array.slice(0,2); // returns a new array
let newArray2 = array.slice(0,2); // returns the same new array
for(var i = 0; i < 2; i = i+2) {
result = array.slice(i, i+2);
console.log(result);
}

Why first image in Array doesn't loop the first time around?

I am making a simple animation using javascript. Of course I could use the CSS keyframes, but that would not work for what I need this for, so no CSS solution please. I threw in a status div just so you see what I mean without actually having to see the images. JSfiddle below.
Anyway here is the HTML.
<div id="zero-walking"><img src="#" id="zeroImage"></div>
<div id="statusDiv"></div>
Here is the javascript
var index = 0;
var zero = document.getElementById("zeroImage");
var zeroArray = ["images/1.png", "images/2.png", "images/3.png", "images/4.png", "images/5.png", "images/6.png", "images/7.png", "images/8.png", "images/9.png", "images/10.png", "images/11.png"];
zeroAnimate();
function zeroAnimate() {
zero.setAttribute('src', zeroArray[index]);
index += 1;
if (index == zeroArray.length) {
index = 0;
}
var statusDiv = document.getElementById('statusDiv');
statusDiv.innerHTML = zeroArray[index];
}
setInterval(zeroAnimate, 700);
http://jsfiddle.net/r9zfg3jp/
This block:
index += 1;
if (index == zeroArray.length) {
index = 0;
}
Should be at the very end of the function.
Your problem is index += 1 is happening before you ever do statusDiv.innerHTML = zeroArray[index]; so it's 1 (not 0) the first time you get there...
Try moving the index assignment operator to the end of your method here. As it is, you are FIRST increment the index, then doing work, meaning you are skipping the 0 frame...
Sometimes I ask myself why I help. If you just want to loop over those images it's like:
function loopImages(elem, imgs, interval, loop){
var i = 0, loopy = setInterval(function(){
elem.src = imgs[i++];
if(i === imgs.length){
loop ? i = 0 : clearInterval(loopy);
}
}, interval);
}
loopImages(document.getElementById('zeroImage'), zeroArray, 700, true); // loops forever

Multiply an element by a number and insert using jQuery

I'm wondering if you can multiply an element using jQuery a number of times and insert it using .html()?
I am building my own slider which might help put things in context...
I am getting a number of times an element is used, which is stored in a var called eachSlideCount. So for example, this might output 10.
Then what I want to do is create a <span></span> for each of these (so 10 spans) and insert this into a div to generate a pager.
$this.next('.project-slider-count').html('<span></span>')
Is there anyway to muliply this span by the eachSlideCount number and then add to the .project-slider-count element?
I got this far... but clearly missing something...
var eachSlideCount = $this.find('.other-slides').length;
var eachSlideTotal = ($this.next('.project-slider-count').html('<span></span>')) * eachSlideCount;
$('.project-slider-count').html(eachSlideTotal);
Thanks in advance
Multiplication can only be done on numbers. If you want to repeat something, write a loop:
var span = '';
for (var i = 0; i < eachSlideCount; i++) {
span += '<span></span>';
}
$this.next('.projectslider-count').html(span);
In JavaScript, you can execute a for loop. For example, in the following:
var count = 10;
for (var i=0; i<count; i++) {
// Code
}
The body of the loop would be executed 10 times.
In jQuery, you can append a new HTML element inside an existing element using the append() method. For example, the following will add <span> elements in a loop:
var container = $("#container");
var count = 10;
for (var i=0; i<count; i++) {
container.append("<span>");
}
This is illustrated in a jsFiddle.

Loop through colours array with jQuery

I'm trying to give each div a different background colour. Here is my current code:
http://jsfiddle.net/Uy2FX/2/
var imgColours = ['#FCCF94', '#C4C9E5', '#ADE3D6'];
for (i=0; i < imgColours; i++) {
$('.img').css({backgroundColor: imgColours[0]});
}
However, I'm not quite sure where this is going wrong. I understand that's probably too simple to work, but in my mind it makes sense. Could someone point me in the right direction?
There are some relevant errors in your code.
This is probably what you wanted to do:
// V1 : Basic
var imgColours = ['#FCCF94', '#C4C9E5', '#ADE3D6'];
for (var i=0; i < imgColours.length; i++) {
$('.img:eq('+i+')').css({backgroundColor: imgColours[i]});
}
But if you want to get a random color from your array, for any number of divs, and also optimise your jQuery code a bit for better performance:
// V2 : random colors
var $imgs = $('#boxes1').find('.box'),
imgsCount = $imgs.length,
coloursCount = imgColours.length;
for (var i=0; i < imgsCount; i++) {
var rnd = Math.floor(Math.random() * coloursCount),
color = imgColours[rnd];
$imgs.eq(i).css({backgroundColor: color});
}
Or, if you want to loop through the colours following the order of the array, just change the loop:
// V3 : sequential colors
// Add V2 variables here
for (var i=0; i < imgsCount; i++) {
var color = imgColours[i%coloursCount];
$imgs.eq(i).css({backgroundColor: color});
}
UPDATED FIDDLE: http://jsfiddle.net/Uy2FX/12/
For some very basic tips on jQuery selectors performance: http://www.sitepoint.com/efficient-jquery-selectors/
You are always assigning imgColours[0] to EVERY div. I think what you are looking for is imgColours[i]
You will also need to use imgColours.length to tell your loop how long the array is.
You are also grabbing all HTML elements with the class of img, so this will change all of them each time.
To grab each element separately, you can use the CSS nth-of-type selector. Basically you can just do something like
$(".img:nth-of-type(" + i + ")")
You need to use imgColours.length
The for loop has no idea how long the array is otherwise
Edit: What's the point in this for loop if you end up using imgColours[0] anyways? If you want to loop each color, use i instead of 0.
And either way, this will not achieve a different background per div.
Try selecting by className (I'm going to use vanilla.js because it's simple)
var elements = document.getElementsByClassName("img");
for (var i = 0; i<elements.length; i++) {
var color = imgColours[Math.floor(Math.random()*imgColours.length)]; //get a RANDOM color change me if needed
elements[i].style.backgroundColor = color;
}
How about this?
var ec = 0;
var i = 0;
for(ec; ec < elements.length; ec++, i++) {
elements[ec].style.backgroundColor = imgColours[i];
if(i == (imgColours.length - 1)) i = -1;
}
http://jsfiddle.net/y2dq3/

Inserting html elements while DOM is changing

My code should insert HTML content in all divs that have a predefined class name, without using jQuery and at least compatible with IE8 (so no getElementsbyClass).
The html:
<div class="target">1</div>
<div class="target">2</div>
<div class="target">3</div>
<div class="target">4</div>
The javascript:
var elems = document.getElementsByTagName('*'), i;
for (wwi in elems) {
if((' ' + elems[wwi].className + ' ').indexOf(' ' + "target" + ' ') > -1) {
elems[wwi].innerHTML = "YES";
//elems[wwi].innerHTML = "<div>YES!</div>";
}
}
You can try it here.
As you can see inside each div the word YES is printed. Well the if you comment elems[wwi].innerHTML = "YES"; and replace that for elems[wwi].innerHTML = "<div>YES!</div>" the code fails. I suppose is because inserting div elements modify the DOM and in consequence the FOR cycle fails. Am i right?
Well i can solve this pretty ugly by recalling the for cycle each time i make an innerHTML, and when i insert the code i can add a class (like data-codeAlreadyInserted=1) to ignore the next time the FOR pass in that div. But again, this is pretty much a very bad solution since for an average site with many tags I can even freeze the user browser.
What do you think? lets suppose i dont know the amount of tags i insert on each innerHTML call.
"I suppose is because inserting div elements modify the DOM and in consequence the FOR cycle fails. Am i right?"
Pretty much. Your elems list is a live list that is updated when the DOM changes. Because you're adding a new div on every iteration, the list keeps growing and so you never get to the end.
To avoid this, you can either do a reverse iteration,
for (var i = elems.length-1; i > -1; i--) {
// your code
}
or convert the list to an Array.
var arr = [];
for (var i = 0, len = list.length; i < len; i++) {
arr.push(elems[i]);
}
for (i = 0; i < len; i++) {
// your code
}
Another way is to use replaceChild instead of innerHTML. It works better and it's way faster:
var newEl = elem[wwi].cloneNode(false);
newEl.innerHTML = html;
elem[wwi].parentNode.replaceChild(newEl, elem[wwi]);
You can take a copy of the live node list:
var nodes = [];
for (var i = 0, n = elems.length; i < n; ++i) {
nodes.push(elems[i]);
}
and then use a proper for loop, not for ... in to iterate over the array:
for (var i = 0, n = nodes.length; i < n; ++i) {
...
}
for ... in should only be used on objects, not arrays.

Categories

Resources