can't change "class" by using attr() - javascript

var allp = $("div p");
for (var i = 0; i < allp.length; i++) {
allp.attr("class", function(i, n) {
n += 1;
return n;
});
console.log(allp[i]);
}
<script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
<div>
<p class="1">1</p>
<p class="2">2</p>
<p class="3">3</p>
<p class="4">4</p>
<p class="5">5</p>
</div>
i means index, n means the current value of "class". Just wanted to make each classname +1,but failed to do that.And the console.log is :
<p class="11111">1</p>
<p class="21111">2</p>
<p class="31111">3</p>
<p class="41111">4</p>
<p class="51111">5</p>
Expected output:
<p class="2">1</p>
<p class="3">2</p>
<p class="4">3</p>
<p class="5">4</p>
<p class="6">5</p>

Simply ignore for loop:
var allp=$("div p");
allp.attr("class",(i,n)=>Number(n)+1);
console.log(allp)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p class="1">1</p>
<p class="2">2</p>
<p class="3">3</p>
<p class="4">4</p>
<p class="5">5</p>
</div>

Maybe:
var allp = $("div p");
for (var i = 0; i < allp.length; i++) {
allp.attr("class", function (i, n) {
const n2 = Number(n) + 1;
return n2;
});
console.log(allp[i]);
}

You just need to get the class attribute value of each p element increment it after converting it to a Number and then assign this value to the same element as the new text value.
var allp=$("div p");
for(var i=0;i<allp.length;i++){
$(allp[i]).text(Number($(allp[i]).attr("class")) + 1);
console.log(allp[i]);
}
<script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
<div>
<p class="1">1</p>
<p class="2">2</p>
<p class="3">3</p>
<p class="4">4</p>
<p class="5">5</p>
</div>

Use jQuery.each() to iterate through each element in $allp, then .attr() to set the new class name.
var $allp = $("div p")
$.each($allp, (index, el) => {
const $newEl = $(el).attr('class', `newClass-${index + 2}`)
console.log($newEl[0])
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div>
<p class="1">1</p>
<p class="2">2</p>
<p class="3">3</p>
<p class="4">4</p>
<p class="5">5</p>
</div>
Codepen

You can use jquery. Get the class, parse it to int and increment. It'll throw an error if you have none numeric characters in your class though so may want to do a check !isNaN.
$('div p').each(function(){
console.log(parseInt($(this).attr('class')) + 1);
});

Related

change the text of every element in a class javascript

How do I change the text of all elements in a class
If the element is in a division do I need to do anything else?
P.S. I hardly know js so plz help.
enter image description here
You can use querySelectorAll and with a foreach set the new text:
const examples = document.querySelectorAll('.example');
examples.forEach(example => {
example.innerHTML = 'new text';
});
<div class="example">
text 1
</div>
<div class="example">
text 2
</div>
I hope these examples can help you
function myFunction()
{
x=document.getElementsByClassName("infoblock"); // Find the elements
for(var i = 0; i < x.length; i++){
x[i].innerText="text changed!"; // Change the content
}
}
function myFunction2()
{
x=document.getElementsByClassName("notationgrade"); // Find the first span elements
y=document.getElementsByClassName("percentgrade"); // Find the second span elements
for(var i = 0; i < x.length; i++){
x[i].innerText="text 1 changed!"; // Change the content
}
for(var i = 0; i < y.length; i++){
y[i].innerText="text 2 changed!"; // Change the content
}
}
<body>
<div class="class-stats fsClassStatsAverage">
<p><span class="infoblock notationgrade">old text 1 </span></p>
<p> <span class="infoblock percentgrade">old text 2</span></p>
</div>
<button type="button" onclick="myFunction()">Change All Spans</button>
<button type="button" onclick="myFunction2()">Change Each Span</button>
</body>

childNode unexpected behaviour

Scenario
I would like to get all child nodes of my div and change it color.
Code:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Error:
This is not working. It seems tha in my collection i have all nodes. h2 p text buton. I Expeceted just p h2 and buton.
EDIT
Explanation
Note: Whitespace inside elements is considered as text, and text is considered as nodes. Comments are also considered as nodes.
So we need to check if node is element node, or use querySelectorAll.
Examples in answers below. Thanks for your help.
Text nodes do not have style attributes. If you want to use childNodes, check that the nodeType is 1 (an Element node) first:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
if (myCollection[i].nodeType === 1) myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
But I would prefer using querySelectorAll and forEach here:
function myFunction() {
document.querySelectorAll('#divv > *')
.forEach(child => child.style.color = "red");
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
(or, you could simply set #divv's style.color to red)
You could use the children property to access the children of a given node:
The ParentNode property children is a read-only property that returns a live HTMLCollection which contains all of the child elements of the node upon which it was called.
- MDN web docs
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.children;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Another way to do with ES6 would be to spread the child nodes into an array and loop through them with a .forEach:
const myFunction = () => {
[...document.querySelector('#divv').children].forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>
Alternatively, you could use the .forEach from the NodeList class directly but the previous method gives you more freedom to work with Array's method such as .reduce, .map, etc...
const myFunction = () => {
document.querySelectorAll('#divv > *').forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>

Adding string to child elements of div class

I have the following script, which is not doing what I want it to do:
<html>
<body>
<div class="test">
<div class="one">sdas</div >
<div class="two">adsa</div >
<div class="three">sad</div >
<div class="four">sada</div >
</div>
<br /><br /><br />
<div id="DIV2">
</div>
<p>Click the button to change the text of the first list item (index 0).</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
var MyDiv2 = document.getElementById('DIV2');
var doc = document.getElementsByClassName("test");
var str = 'str';
for (var i = 0; i < doc.length; i++) {
MyDiv2.innerHTML = doc[i].innerHTML + str;
}
}
</script>
</body>
</html>
Once the button is pushed, it outputs this:
sdas
adsa
sad
sada
sdas
adsa
sad
sada
str
However, I would like to have the following output:
sdas
adsa
sad
sada
sdas
str
adsa
str
sad
str
sada
str
So for each child class, str should be added. How can I achieve this?
I suggest you to change the doc variable selector using querySelectorAll like that:
function myFunction() {
// ...
var doc = document.querySelectorAll(".test span");
var str = 'str';
for (var i = 0; i < doc.length; i++) {
MyDiv2.innerHTML += doc[i].innerHTML + ' ' + str + ' ';
}
}
Update
You changed from span to div, so you can use doc = document.querySelectorAll(".test div") if you only want the divs.
To get all children in general, you can use doc = document.querySelector(".test").children.
Use querySlectorAll & target the div and its child spans. In your code doc[i].innerHTML will give the child span elements, but the variable str is suppose to add to the textContent
function myFunction() {
// a new variable which will be concatenation of all the text
var newString = ''
var MyDiv2 = document.getElementById('DIV2');
var doc = document.querySelectorAll(".test span");
var str = 'testString';
for (var i = 0; i < doc.length; i++) {
// trim is used to remove any white space
newString += doc[i].textContent.trim() + str + ' ';
}
MyDiv2.innerHTML = newString
}
<div class="test">
<span class="one">sdas</span>
<span class="two">adsa</span>
<span class="three">sad</span>
<span class="four">sada</span>
</div>
<br /><br /><br />
<div id="DIV2">
</div>
<p>Click the button to change the text of the first list item (index 0).</p>
<button onclick="myFunction()">Try it</button>
Here you go.
Take a new variable i.e. output, push the results into this array while looping. Once done with loop, join the array. Please note that I am using id selector on div now.
<body>
<div class="test" id="test">
<div class="one">sdas</div >
<div class="two">adsa</div >
<div class="three">sad</div >
<div class="four">sada</div >
</div>
<br /><br /><br />
<div id="DIV2">
</div>
<p>Click the button to change the text of the first list item (index 0).</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
var MyDiv2 = document.getElementById('DIV2');
var items = document.getElementById("test").children;
var str = 'str';
var output = [];
for (var i = 0; i < items.length; i++) {
output.push(`${items[i].innerHTML} <br /> ${str} <br />`);
}
MyDiv2.innerHTML = output.join("");
}
</script>
</body>

Javascript increment through elements within div?

Ok, so I have the following HTML:
<div class="calculator-section">
<p class="x"></p>
<p class="y"></p>
</div>
<div class="calculator-section">
<p class="z"></p>
<p class="a"></p>
</div>
<div class="calculator-section">
<p class="b"></p>
<p class="c"></p>
</div>
I need to increment through each of these divs and compare classes that each <p> has.
How would I go about doing this?
Currently I have this:
$('.calculator-section').each(function(i, obj) {
$(this).$('p').each(function(i, obj) { //This bit doesn't work
//Check classes for $(this) here?
});
});
But I'm not sure what to do for that inner loop. Any ideas?
Add p to your initial each loop and use the className property within the loop
$('.calculator-section p').each(function(i, obj) {
if(this.className == "x") {
$(this).css('background', 'green')
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="calculator-section">
<p class="x">x</p>
<p class="y">y</p>
</div>
Alternatively, if you are using the multiple loops for a reason:
Select p within the iteration of specific section with $('p', this) or $(this).children('p') etc
$('.calculator-section').each(function(i, obj) {
// $(this) = section
$('p', this).each(function(i, obj) {
// $(this) = p within above section
});
});
Use single each() instead of double each(). Example here..
$('.calculator-section p').each(function(i, obj) {
var className = $(this).attr('class');
if(className == 'expected value'){
//do something
//return false;
}
});
You're going to get too many results. <p class="x"><p> should be <p class="x"></p> (with a forward slash to indicate closing the paragraph.
<div class="calculator-section">
<p class="x"></p>
<p class="y"></p>
</div>
<div class="calculator-section">
<p class="z"></p>
<p class="a"></p>
</div>
<div class="calculator-section">
<p class="b"></p>
<p class="c"></p>
</div>
Once that's fixed,
//you can grab the class couples this way
var results = $('.calculator-section').map(function(i, obj) {
return $(obj).find('p').map(function(i, obj) {
return obj.className;
});
});
//and then do what you want with them later
results.each(function(i, obj) {
console.log(obj[0] + ',' + obj[1]);
});
>> x,y
>> z,a
>> b,c

How can I loop through all of the P tags and then write their innerHTML to the document at the end of the page?

I want to loop through all of the p tags on my web page and then write them to the end of the web page. I thought that this for loop would work but so far it is giving me an error.
How would I be able to do this and then append the text that is in the tag to the end of the page?
function forLoopTest() {
var i; //indexing tag for looping through all of the array elements
//for loop to loop through the pp array starting at index of zero
for (i = 0; i < pp.length;i++)
{
document.writeln("<br>" + pp[i].innerHTML); //write to the end of the page of each element
}
}
HTML Code:
<!DOCTYPE html>
<html>
<body>
<div id="main">
<p id="AA">A</p>
<p id="BB">B</p>
<p id="CC">C</p>
<p id="DD">D</p>
<p id="EE">E</p>
</div>
<p id="demo"></p>
<script>
var x = document.getElementById("main");
var pp = x.getElementsByTagName("p"); //creates an array of p elements
document.getElementById("demo").innerHTML = 'The first paragraph inside "main" is ' + pp[1].innerHTML;
function forLoopTest() {
var i;
for (i = 0; i < pp.length;i++) {
document.writeln("<br>" + pp[i].innerHTML;
}
}
forLoopTest();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<div id="main">
<div id="main">
<p id="AA">A</p>
<p id="BB">B</p>
<p id="CC">C</p>
<p id="DD">D</p>
<p id="EE">E</p>
</div>
<p id="demo"></p>
<p style="color:blue;margin-left:20px;">This is a paragraph.</p>
<p id="A">A</p>
<p id="B">B</p>
<p id="C">C</p>
<p id="D">D</p>
<p id="E">E</p>
<div>Test</div>
</div>
<p id="demo"></p>
<script>
var x = document.getElementById("main");
var pp = x.getElementsByTagName("p"); //creates an array of p elements
var divTag = x.getElementsByTagName("div"); //creates an array of div elements
document.getElementById("demo").innerHTML = 'The first paragraph inside "main" is ' + pp[1].innerHTML;
function forLoopTest() {
var i;
for (i = 0; i < pp.length;i++) {
document.writeln("<br>" + pp[i].innerHTML;
}
}
var fragment = document.createDocumentFragment();
Array.prototype.forEach.call(document.getElementsByTagName('p'), function (element) {
Array.prototype.forEach.call(element.childNodes, function (childNode) {
fragment.appendChild(childNode.cloneNode(true));
});
});
document.body.appendChild(fragment);
</script>
</body>
</html>
if you read the error it tells you you have a syntax problem and are misisng a ).
You didn't close write()
document.writeln("<br>" + pp[i].innerHTML;
Should be
document.writeln("<br>" + pp[i].innerHTML);
DEMO
There are numerous way to do it, one solution might be.
HTML
<div id="main">
<p id="AA">A</p>
<p id="BB">B</p>
<p id="CC">C</p>
<p id="DD">D</p>
<p id="EE">E</p>
</div>
<p id="demo"></p>
Javascript
var fragment = document.createDocumentFragment();
Array.prototype.forEach.call(document.getElementsByTagName('p'), function (element) {
Array.prototype.forEach.call(element.childNodes, function (childNode) {
fragment.appendChild(childNode.cloneNode(true));
});
});
document.body.appendChild(fragment);
HTML after
<div id="main">
<p id="AA">A</p>
<p id="BB">B</p>
<p id="CC">C</p>
<p id="DD">D</p>
<p id="EE">E</p>
</div>
<p id="demo"></p>
ABCDE
On jsFiddle
Warning: cloneNode() may lead to duplicate element IDs in a
document.
This is also true if blindly copying the innerHTML of the elements.

Categories

Resources