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.
Related
Insert this structure inside the body tag without using innerHTML and use a FOR loop for the 3 li elements :
<div id="divEx1">
<p>Langages basés sur ECMAScript :</p>
<ul>
<li>JavaScript</li>
<li>JScript</li>
<li>ActionScript</li>
</ul>
</div>
I already created the elements with is text node and the ul element, but I have trouble with the li elements. I added a document.createElement("li") in a variable named eLi, then I created a loop for (i = 0; i < 3; i++) with a document.querySelector("ul").appenChild(eLi), a switch for putting the appropriate document.createTextNode() in a varaible named texteLi and finally a document.querySelector("li").appendChild(texteLi)
var eLi = document.createElement("li");
for (i = 0; i < 3; i++) {
document.querySelector("ul").appendChild(eLi);
switch (i) {
case 1:
texteLi = document.createTextNode("Javascript");
case 2:
texteLi = document.createTextNode("JScript");
case 3:
texteLi = document.createTextNode("Actionscript");
document.querySelector("li").appendChild(texteLi);
}
}
Here is my result :
https://ibb.co/Kj5PGKF
I don't understand why there is a CSS pseudo-class ::marker
Let's start first with breaks. I think you need to put break; at the end of every case, i have had problems with not putting it in the past, plus it helps in making reading your code logic for debugging.
Next, if I am correct, This code will always only create one node because document.querySelector("li").appendChild(texteLi) is placed in case:3
Last I think you should start your cases at 0 and not 1 because you have i < 3 instead of i <= 3 and I dont see how case 3 is executing
I dont think I have really answered the question you asked but I think these might be some of the problems
To set the content of a node without using innerHTML node.textContent = text
You have the correct approach, but you are not creating 3 <li> elements in your code above, rather only one. Also, you are querying the <ul> in each iteration of the loop, which you don't need to do. Further, using a switch statement here might seem handy, but your syntax is wrong and there is a better way. Since you are already using a for-loop, let's just iterate over an array of your desired text content and use the index to inject our text. Keeping with your code-style, the resulting code might look something like this:
var textArray = ["Javascript","JScript","Actionscript"]
var eU = document.querySelector("ul")
for (i = 0; i < 3; i++) {
var eLi = document.createElement("li")
var textNode = document.createTextNode(textArray[i]);
eLi.appendChild(textNode)
eU.appendChild(eLi)
}
Try it out in your console but creating the <ul> instead of selecting it, and you will see your desired result:
var textArray = ["Javascript","JScript","Actionscript"]
var eU = document.createElement("ul")
for (i = 0; i < 3; i++) {
var eLi = document.createElement("li")
var textNode = document.createTextNode(textArray[i]);
eLi.appendChild(textNode)
eU.appendChild(eLi)
}
console.log(eU)
I am working on a project that requires a form be built. The form has a function that sums up the columns as well as the rows. I am strictly using HTML and JavaScript. I am unable to get the JavaScript function called twice, once for the row and once for the column (I will actually be calling it 3 times as I need to do section totals as well). I have created different classes for the column controls that will need summed up and a different class for the row controls that will need to be summed up, hence the two different classes in the input control. I also believe that it could be in the for loop as I commented it out and put used an alert statement and it seemed to work perfectly. See the following code:
JavaScript:
<script type="text/JavaScript">
function CalcSum(displayIn, calcClass){
var sum = 0;
var displayCell = displayIn;
className = calcClass;
var divs = document.getElementsByClassName(className);
var args = [];
for (var i = 0; i <=divs.length; i++){
args.push(divs[i].value);
val = divs[i].value;
sum += val*1;
document.getElementById(displayCell).value = sum;
dollarAmount("Form1", displayCell);
}
}
HTML Control:
<input type="text" name="ctl_001" value="" id="ctl_001" class="col4txrev col4" onchange="CalcSum('T1_TOT_C4_TXREV','col4txrev');CalcSum('T1_TOT_C4','col4');" style= "width: 100%">
You have multiple errors in your script technically and functionally based on my understanding of your question.
I have corrected the errors and can see the console printing the log twice when they called.
Note: Anyways, don't call the function twice from the inline attribute. Create another function which will do the same and call it from the onchange event (or) create the onchange listener programmatically.
When looping the elements, condition should be i < divs.length and
not i <= divs.length
To find a text inside the div, it should be innerHTML as below
and not value. value can be used for the form input elements
which values can be changed by the end users.
To calculate the sum, the value should be converted to a number
using either parseInt or parseFloat since the text/value of
the element is generally a text.
If you have to assign the final value of the sum to another div
element and call another method, it should be outside the for
loop. But if you really need this to set/call for each loop, then it
can be inside the for loop.
function CalcSum(displayIn, calcClass){
var sum = 0;
var displayCell = displayIn;
var className = calcClass;
console.log('called');
var divs = document.getElementsByClassName(className);
var args = [];
for (var i = 0; i < divs.length; i++){
//args.push(divs[i].value);
var val = divs[i].innerHTML;
args.push(val);
sum += parseInt(val) * 1; // It can be parseFloat
}
document.getElementById(displayCell).value = sum;
dollarAmount("Form1", displayCell);
}
// dummy function
function dollarAmount(form, elm){
}
<input type="text" name="ctl_001" value="" id="ctl_001" class="col4txrev col4" onchange="CalcSum('T1_TOT_C4_TXREV','col4txrev');CalcSum('T1_TOT_C4','col4');" style= "width: 100%">
<div class="col4txrev">10</div>
<div id="T1_TOT_C4_TXREV"></div>
<div class="col4">20</div>
<div id="T1_TOT_C4"></div>
i tried to do some artistic stuff with javascript and maths and for this i need some Random html elements in my page.
I create div#mainStage manually in HTML, I want to add div.box 10 times and I want to add 5 divs with different name into each div.box.
I copy my codes sample in here, i just try this loop with create element method but I can not make it work.
outerloop:
for (i = 1; i < maxboxNum;) {
var createBox = document.createElement("span");
document.querySelector("#mainStage").appendChild(createBox);
innerloop:
for (var j = 0; j < 5; j++) {
document.querySelector("span").innerHTML = j;
}
i++
}
My HTML Output is;
<div id="mainStage">
<span>4</span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
Try this:
var maxboxNum = 10;
var mainStage = document.querySelector('#mainStage');
for (var i = 1; i <= maxboxNum;) {
var createBox = document.createElement('span');
createBox.appendChild(document.createTextNode(i <= 5 ? 'Span #' + i : ''));
mainStage.appendChild(createBox);
i++
}
When you call the internal for loop, you're not done appending elements to the parent so it runs 5 times (0 + 5 = 4, technically 0 counts as 1 so yeah arrays are weird), so you always get 4 and it will always append to the first element.
The code:
createBox.appendChild(document.createTextNode(i <= 5 ? i : ''));
Will add a text node to the span you created, and if the count is less than or equal to it will add the number, else it will just output a blank string.
Try this...
for (var i = 1; i < 10; i++) {
var createBox = document.createElement("span");
createBox.innerText = i;
document.querySelector("#mainStage").appendChild(createBox);
}
I've moved the i++ into the loop and removed the inner loop altogether and just set the text when creating the span.
Your code above will create 1 span on first loop, then the inner loop runs 5 times populating the same div with 0-4 (hence the 4 there at the end).
The problem with your code is that document.querySelector("span").innerHTML = j; will always select the first element, as the doc specifies . If you want to select the n-th span element, you either have to use a CSS selector that does that like :nth-child or use the querySelectorAll function.
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/
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.