For example, I have
<div class="stick active"></div>
<div class="stick"></div>
<div class="stick"></div>
<div class="stick"></div>
<div class="stick"></div>
I need to find out all the indexes from the stick classes so that I can refer to each of them further [0],[1],[2]...
I tried to convert them to an array via [...] and via Array.prototype.slice.call
but when I try to interact with them, I get "undefined"
use this I think it will help you:
for first index:
var x = document.querySelectorAll(".stick");
console.log(x[0])
for all:
var x = document.querySelectorAll(".stick");
console.log(x)
Use Document.querySelectorAll() to create a NodeList.
querySelectorAll():
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
NodeList:
https://developer.mozilla.org/en-US/docs/Web/API/NodeList
const highlightedItems = document.querySelectorAll(".stick");
// access the second node:
console.log(highlightedItems[2].textContent);
// loop through all nodes
for (let i = 0; i < highlightedItems.length; i++) {
let item = highlightedItems[i];
console.log( item.id );
}
<div class="stick active"></div>
<div class="stick" id="1">A</div>
<div class="stick" id="2">B</div>
<div class="stick" id="3">C</div>
<div class="stick" id="4">D</div>
I think you want to hanle it via getElementsByClassName. This returns an HTML collection, not an array, thus you cannot use indexOf on it.
Iterating over the elements is the way to go, iterating over className, which is a string containing your node's class name, like this:
let stick = document.getElementsByClassName('stick');
for(let i=0; i < stick.length; i++){
console.log(stick[i]);
}
Related
I am trying to retrieve a DOM element from an array, and I want to set it as a variable to use outside its scope. Right now, my variable future_devices returns one object as expected. But my other variable future_device returns the object when the current DOM should have returned [] due to my last if statement. I originally tried to declare my variables as var due to scope but that did not help. Here is my code:
var future_devices = $('.hardware .future-hardware')
if (future_devices.length) {
let future_device = $(future_devices)
.each(function() {
let device = this
let device_work_order = $(device)
.data(
'work-order'
)
if (device_work_order == data['new_host']['work_order']) {
return device
}
})
I can tell you on the said DOM, the two variables I am using to compare have the following values:
device_work_order = 3MOD0
data['new_host']['work_order'] = 3MOD9
So since future_devices returns only one object and my last if statement is not true, I should get [], right?
$(...) is returning the jQuery collection and always will regardless. So an assignment statement using .each() is the wrong approach.
Solution: Assign the return of .filter() instead. Filter is designed to accomplish your goal. Reference
NOTE: You should realize that if there is more than one match, it will return the entire collection of matches. In the code below I show only the first match, but since there are two matches (for demonstration), you'll see that both matches are returned.
const future_devices = $('.hardware .future-hardware');
const data = {new_host: {work_order: 333}};
const future_device = $(future_devices)
.filter(function(idx, el) {
let device_work_order = $(el).data('work-order');
if (device_work_order == data['new_host']['work_order']) {
return true;
} else {
return false;
}
})
console.log("First match only: ", future_device[0]); // First match
console.log("Collection: ",future_device); // All matches
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hardware">
<div class="future-hardware" data-work-order="111">111</div>
</div>
<div class="hardware">
<div class="future-hardware" data-work-order="333">First Match</div>
</div>
<div class="hardware">
<div class="future-hardware" data-work-order="111">111</div>
</div>
<div class="hardware">
<div class="future-hardware" data-work-order="333">Second Match</div>
</div>
<div class="hardware">
<div class="future-hardware" data-work-order="111">111</div>
</div>
<div class="hardware">
<div class="future-hardware" data-work-order="111">111</div>
</div>
lets say i have a parent-div. And in this div-container, i want to display 5 elements which have all the same structure. For example:
<div class="element">
<p class="name">
</p>
<div class="logo">
</div>
</div>
Is there a way to make an object or prototype out of it, so i dont have to generate every single HTML Element with their classes and src values with the appendChild-function and Dot-Notations in a for-loop?
Im thinking of something like:
for(let i = 0; i<=5;i++){
var element = new element(class,src1,src2 ...);
}
And the "element" is defined in a external class file or something familiar.
Im a beginner, so please show mercy :)
You'll need to clone the node from the template's content. For example:
const templateElement = document.querySelector("#someTemplate")
.content
.querySelector(".element");
// create an Array of nodes (so in memory)
const fiveNodes = [];
for (let i = 0; i < 5; i += 1) {
const nwNode = templateElement.cloneNode(true);
// ^ clone the whole tree
nwNode.querySelector("p.name").textContent += ` #${i + 1}`;
fiveNodes.push(nwNode);
}
// append the nodes to document.body
// this is faster than appending every element in the loop
fiveNodes.forEach(el => document.body.append(el));
<template id="someTemplate">
<div class="element">
<p class="name">I am node</p>
<div class="logo"></div>
</div>
</template>
I can't access HTMLCollection Type When I use getElementsByClassName.
I wanna get the length but I can't get that
var documentHeader = parent.document.all['header'];
var motionClass = documentHeader.getElementsByClassName('motion');
this is a result of motionClass
HTMLCollection []
0: div.motion
length: 1
__proto__ : HTMLColletion
If I access length result is 0
How can I result This Issue?
NOTE: Here we execute the code safely when the DOM is ready. Ensure you are doing that.
document.addEventListener('DOMContentLoaded', function() {
let motionArray = document.getElementsByClassName('motion');
console.log(motionArray.length);
});
<div class='motion'>test</div>
<div class='motion'>test</div>
<div class='motion'>test</div>
<div class='motion'>test</div>
<div class='motion'>test</div>
<div class='motion'>test</div>
<div class='motion'>test</div>
To give a more modern approach - use documentQuerySelectorAll() to get the collection - this can then be iterated over to give each item - or can give the length of the collection.
let motions = document.querySelectorAll('.motion');
console.log(motions.length); // gives 5
console.log(motions[2].textContent); // gives "3" - the text content of that element
<div class='motion'>1</div>
<div class='motion'>2</div>
<div class='motion'>3</div>
<div class='motion'>4</div>
<div class='motion'>5</div>
I am trying to convert an HTMLCollection of 4 divs into an array, but every method I try seems to result in the array being emptied.
<div class="container">
<div class="shape" id="one"></div>
<div class="shape" id="two"></div>
<div class="shape" id="three"></div>
<div class="shape" id="four"></div>
</div>
Methods I've attempted - as per this previous question:
var shapesHC = document.getElementsByClassName('shape');
//gives HTMLCollection
var shapesArrCall = [].slice.call(shapesHC);
// returns empty array
var shapesArrHC = Array.from(shapesHC);
// returns empty array
var shapesArrHCSpread = [...shapesHC];
// returns empty array
I'd really appreciate if anyone can point out where I'm going wrong here.
Thanks.
Try using this:
setTimeout(() => {
this.convertToArray();
});
convertToArray() {
const shapesHC = document.getElementsByClassName('shape');
const shapesArrHCSpread = [...(shapesHC as any)];
console.log(shapesArrHCSpread);
}
With the following code, I'm getting the values of "id"(almost 35), and then add 1 to each "id", so 1 will be 2 and so on. Where I'm stock, it is on how to replace that id number in the html.
This is the code that use to get the values of each id, then I push them into an array, then I run another "for loop" to add 1 to each value, but I don't how to return them to the html.
var x = document.getElementsByClassName('p-divs');
var portfolio = new Array;
for (var i = 0; i < x.length; i++)
{
var y = document.getElementsByClassName('p-divs')[i].getAttribute('id');
portfolio.push(y);
}
console.log(portfolio);
var portfolio2 = new Array;
for (var i = 0; i<portfolio.length; i++)
{
var newId;
newId = parseInt(portfolio[i]) + 1;
portfolio2.push(newId);
}
console.log(portfolio2);
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12 p-divs" id="1">
<div class="portfolio">
<center>
<img src="images/pace.png" width="230" height="190" alt="" class="img-responsive">
</center>
</div>
</div>
Since you're using jQuery library the code could be simple than what you've so far using .each() method :
$('.p-divs').each(function(){
$(this).attr('id', Number(this.id) + 1);
});
Or shorter using using .attr() method callback like :
$('.p-divs').attr('id', function(){
return Number(this.id) + 1;
});
The more clear version could be :
$('.p-divs').each(function(){
var current_id = Number(this.id); //Get current id
var new_id = current_id + 1; //Increment to define the new one
$(this).attr('id', new_id); //Set the new_id to the current element 'id'
});
Hope this helps.
$(function(){
$('.p-divs').attr('id', function(){
return Number(this.id) + 1;
});
//Just for Debug
console.log( $('body').html() );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="p-divs" id="1">
<div class="portfolio">
<center>Image 1</center>
</div>
</div>
<div class="p-divs" id="2">
<div class="portfolio">
<center>Image 2</center>
</div>
</div>
<div class="p-divs" id="3">
<div class="portfolio">
<center>Image 3</center>
</div>
</div>
<div class="p-divs" id="4">
<div class="portfolio">
<center>Image 4</center>
</div>
</div>
Using native javascript, just use getattribute's opposite: setAttribute
for (var i = 0; i < x.length; i++)
{
var y = document.getElementsByClassName('p-divs')[i].getAttribute('id');
y++;
document.getElementsByClassName('p-divs')[i].setAttribute("id",y);
}
var j = document.getElementsByClassName('p-divs');
for (var i = 0; i < x.length; i++) {
j[i].id = portfolio2[i];
}
Add this to the end of your code. Vanilla JS.
j will be an array of your divs, i will keep count of which div we're on, and we are simply accessing the "id" of each element in the "j" array and updating it to the corresponding value in your pre-populated "portfolio2" array.
Hope this helps!
P.S.- I would also recommend that instead of using 'new Array' to instantiate your arrays, you use the array literal notation '[]'. This is more concise and also avoids needing to put (); after Array.
I'd suggest, assuming I'm not missing something, and that you're able to us ES6 methods:
// converting the NodeList returned from document.querySelectorAll()
// into an Array, and iterating over that Array using
// Array.prototype.forEach():
Array.from( document.querySelectorAll('.p-divs') ).forEach(
// using an Arrow function to work with the current element
// (divElement) of the Array of elements,
// here we use parseInt() to convert the id of the current
// element into a number (with no sanity checking), adding 1
// and assigning that result to be the new id:
divElement => divElement.id = parseInt( divElement.id, 10 ) + 1
);
Note that updating, changing or otherwise modifying an id shouldn't be necessary in most circumstances, and having a purely numeric id may present problems for CSS selecting those elements (it's valid, but only in HTML 5, but will still be problematic).
for(i=0;i<$('.p-divs').length;i++){
newId= parseInt($($('.p-divs')[i]).attr('id'))+1;
$($('.p-divs')[i]).attr('id',newId)
}
Using Jquery attr