How do I use the querySelector? - javascript

So I got this code:
Function9() {
x = document.getElementById('BakjeRood');
x.style.opacity=1;
y = document.querySelectorAll("#BakjeBlauw, #BakjeGeel, #BakjePaars, #BakjeRoze, #BakjeWit");
y.style. opacity = 0;
}
If you click the button with function9() the image 'BakjeRood' gets an opacity of 1, but the other images (BakjeBlauw etc.) should then get an opacity of 0 (this structure is the same for all the functions I have on my site. How do I get this second part to work?

In your example, you've illustrated a knowledge of getElementById, which by nature returns a single HTMLElement instance or derivative, whereas querySelectorAll returns an enumerable, list/array-like object, containing all HTMLElement instances that match the query.
var elems = document.querySelectorAll("#x, #z, #z");
for(var index = 0; index < elems.length; index++) {
elems[index].style.opacity = 0;
elems[index].canDoOtherStuffToo();
}

You need to iterate over the results of querySelectorAll - it returns an array-like object (a list of nodes), not a single node.

Related

Using array to store elements doesn't let you change the properties

const divArr = [];
for (let i = 0; i < 5; i++) {
document.getElementById("h").innerHTML += `<div id=${i}>hello</div>`;
divArr.push(document.getElementById(`${i}`));
}
console.log(divArr);
let divArrIndex = 0;
setInterval(() => {
document.getElementById(`${divArrIndex}`).style.backgroundColor = 'green';
if (divArrIndex > 4) {
divArrIndex = 0;
}
divArrIndex += 1;
}, 1000 / 1);
<div id="h">alsdjf;lkajsdf</div>
The code above successfully turns all the divs green.
But, when I use
divArr[divArrIndex].style.backgroundColor = "green"
instead of
document.getElementById(`${divArrIndex}`).style.backgroundColor='green';
I only get the last div green.
Why?
codepen: https://codepen.io/sai-nallani/pen/KKopOXZ?editors=1111
By reassignment to innerHTML, you are destroying and recreating the contents of #h in each iteration of the loop. You create #0, then discard it and create #0 and #1, then discard those and create #0, #1, #2... So the elements you push into the array don't exist any more in your document (though references to them in divArr still keep the garbage collector from destroying them outright).
When you change the colour of divArr[0], you are changing the colour of an element that only exists in memory, but is not in DOM any more. However, #4 is still the original #4, it has not been discarded, since you have performed no further assignments to innerHTML.
One solution is to gather all the divs after you have constructed them all. You can use another loop, but the easiest way would be:
const divArr = Array.from(document.querySelectorAll('#h > div'));
(Depending on what you are doing with it next, you may not need Array.from since NodeList should suffice for many purposes.)
Another solution is to construct elements in their own right, not by changing the parent's innerHTML:
const hEl = document.querySelector('#h');
for (let i = 0; i < 5; i++) {
const divEl = document.createElement('div');
divEl.textContent = 'Hello';
divEl.id = i;
hEl.appendChild(divEl);
divArr.push(divEl);
}
This way, every element is created and added to #h without affecting any other elements already there.

Change all ID values by same Class name

I am using the "Autofill" extention on Google Chrome which runs javascript codes. I want to change all ID's ctl01_ctl00_Main_Main_wtWeighted_txtWeight_xxxxx numeric values from 0 to 100 by same Class name weightBox Numeric.
My best guess was the code below but nothing.
document.getElementsByClassName('weightBox Numeric').value = "100";
getElementsByClassName() returns a live collection. In other words, it's a sort of array. So you have to loop through each value to change them. Also you can use querySelectorAll here:
var elements = document.querySelectorAll(".weightBox.Numeric");
for (var i = 0; i < elements.length; i++) {
elements[i].id = i + 1;
}

replace all elements belonging to a specific class

I was trying to develop an embedded widget. User would include an anchor tag and a javascript in their page, and it would render the content. Similar to embedded tweets.
<a href="http://localhost:3000/user/13"
target="_blank"
class="my-widget"
data-widget-type="profile"
data-widget-identifier="id"
data-identifier-value="13"
>Sayantan Das</a>
</div>
<script src="//localhost/my-widget/js/widget.js" async ></script>
And from widget.js, i would get all the elements with class="my-widget" and replace with an iframe.
widgets.js
!function(global, document) {
global.MyWidgets = global.MyWidgets || {};
for(let widgets = document.getElementsByClassName('my-widget'), i = 0; i < widgets.length; i++) {
console.log(widgets)
let element = widgets[i];
let span = document.createElement('span');
span.innerHTML = "Changed from widget " + i;
element.parentNode.appendChild(span);
element.parentNode.removeChild(element);
}
}(window, document);
The problem is , when I remove the element the loop also runs for a shorter number. for example, if there are two elements with class my-widget, after first time the loop runs and one element is removed and the loop runs only once. How do I replace all the elements?
That's because getElementsByClassName returns a live HTMLCollection; when you remove the class="my-widget" element from the DOM, it's also removed from the collection.
Either work backward through the collection (so you're removing from the end, which doesn't affect the ones before it), or use querySelectorAll(".my-widget") instead, which returns a snapshot NodeList, not a live HTMLCollection.
Working backward:
for(let widgets = document.getElementsByClassName('my-widget'), i = widgets.length - 1; i >= 0; i--) {
Using qSA instead:
for(let widgets = document.querySelectorAll('.my-widget'), i = 0; i < widgets.length; i++) {
or if you don't need i (you seem only to be using it to get the element and for demo purposes), you can use for-of with NodeLists now (on most platforms; this answer has a polyfill for others):
for (const element of document.querySelectorAll('.my-widget')) {
// ...and remove the `let element = ...` line
use document.querySelectorAll to the length of the widgets

Beginner JavaScript for loop

I was wondering if anyone knows the reason for [i-1] in the fourth line when you also have i++ in the second line? Thank you for any help! (It's from the book "JavaScript" by Vodnik and Gosselin.)
if (figureCount === 3) {
for (var i = 1; i < 4; i++) {
filename = "images/IMG_0" + photoOrder[i] + "sm.jpg";
currentFig = document.getElementsByTagName("img")[i - 1];
currentFig.src = filename;
}//end of for loop
It because document.getElementsByTagName returns an HTMLCollection(similar to array) hence. So accessing the 1st(and subsequent) img tag on the page are done through setting i-1
document.getElementsByTagName return a HTMLCollection which is not an array but an array like object. So to access any element from that collection you can pass the index.
document.getElementsByTagName("img")[i - 1] is creating a collection of all the img tags & it is accessing specific element in that collection by passing the index [i-1]
In the below example [1] is trying to access the second element from the collection
var getAllDiv = document.getElementsByTagName('div');
console.log(getAllDiv[1].innerHTML)
<div>1</div>
<div>2</div>
Some developers get confused with the for loop operators logic instead of doing it correctly:
for (var i = 0; i < 3; i++) {
they decided to add some extra processing to the mix ( which isn't that big of a deal ) but iv'e fired developers for less.
CurrentFig is using i - 1 because it appears there is a prepended img element so the developer also chose to select it as well instead of selecting the exact elements that he needs.

Javascript getElemtsByClass select [all]

I want to select all elements with the css class
.arrow-down
Sorry but i simply dont find the correct answer, for my problem!
I have an javascript code:
document.getElementsByClassName("arrow-down")[0].style.borderTopColor=""+blu+"";
so how do i select not the first but [all] or is there a way to [1;2;3;]??
getElementsByClassName("arrow-down")[all]
getElementsByClassName("arrow-down")[1;2...]
I tried many things but simply dont get it!
Greetings from germany!
You need to iterate over the list of returned results.
var elements = document.getElementsByClassName("arrow-down");
for (var i = 0, len = elements.length; i < len; i++){
elements[i].style.borderTopColor = blu;
}
If you want to only do a specific subset based on the index, then you can add a condition that checks the value of i. I'm also assuming that blu here is a variable you have defined somewhere?
for (var i = 0, len = elements.length; i < len; i++){
if (i === 1 || i === 2 || i === 3){
elements[i].style.borderTopColor = blu;
}
}
Unfortunately, JavaScript does not have a shorthand for accessing a specific subset of array values, or for applying changes to multiple elements at once. That is something that jQuery does automatically for you. For instance, with jQuery you could write this as:
$('.arrow-down').css('borderTopColor', blu);
document.getElementsByClassName("arrow-down") does select all of such elements.
These are returned in a node list (which can be treated as an array), which is why using [0] on that returns the first element.
Loop over the different elements that the expression returns and act on them:
var elements = document.getElementsByClassName("arrow-down");
var elementsNum = elements.length)
for(var i = 0; i < elementsNum; i++)
{
var anElement = elements[i];
// do something with anElement
}

Categories