Why does my document.getElementsByClassName("obj").innerHTML doesn't work? - javascript

I want to replace HTML in document with .innerHTML but for some reason it doesn't work:
HTML
<div class="specs">
<div class="wrapp">
<p class="line">Content</p>
</div>
</div>
JS
document.getElementsByClassName("specs").innerHTML = "<p>Lorem ipsum</p>";

getElementsByClassName returns a collection. Not a single item.
There are multiple ways to do this:
You can run a for loop over the returned items.
let specs = document.getElementsByClassName("specs");
for(let i = 0 ; i < specs.length;i++){
specs[i].innerHTML = "<p>Lorem ipsum</p>";
}
If you have only item, you can use querySelector which returns the first matched element.
document.querySelector(".specs").innerHTML = "<p>Lorem ipsum</p>";

In a concise way this is how you'd do it
const targets = document.getElementsByClassName("specs")
if (targets.length)
for (spec in targets)
targets[spec].innerHTML = "<p>Lorem ipsum</p>";
<div class="specs">
<div class="wrapp">
<p class="line">Content</p>
</div>
</div>

I found your mistake.
document.getElementsByClassName returns an array of elements with the given class name. so try this.
document.getElementsByClassName("specs")[0].innerHTML = "<p>Lorem ipsum</p>";
For example if you have two elements with the same class name it returns an array containing both the elements, so you have to get the element using the specified index from the array. 👍

Related

sort div's through sort(); [duplicate]

This question already has answers here:
Easiest way to sort DOM nodes?
(9 answers)
Closed last month.
I have list and this list must be sort to a => b throught like btn (example click SORT and we have list to a -> b)
<div class = "list">
<div id = "products"> Sugar </div>
<div id = "products"> Banana </div>
<div id = "products"> Apple </div>
</div>
sorted to for button =>
<div class = "list">
<div id = "products"> Apple </div>
<div id = "products"> Banana </div>
<div id = "products"> Sugar </div>
</div>
Idk how did that with like btn :(
I tried something like that =>
// For the HTML //
<button class = 'sortBtn' onclick = 'sort()'>Sort</button>
<script>
const sort = document.quertSelector('.sortBtn');
sort.addEventListenet('click', function sort(a, b){
$parent.sort();
})
</script>
I would be grateful for help :) <3
There's a few issues in your code.
Typo: quertSelector -> querySelector
Typo: addEventListenet -> addEventListener
The repeated id in your HTML are invalid, convert them to class instead.
The function you provide to addEventListener should be anonymous in this case. Giving it a name here serves no purpose other than to waste bytes.
Avoid using inline event handlers, such as onclick, in your HTML code. It's outdated and no longer good practice. Use unobtrusive event handlers instead, such as addEventListener(), which you already use elsewhere in your code.
sort() should compare the a and b arguments and return an integer depending on which way to sort them. In this case, as you're comparing strings you can use localeCompare() on the textContent property of the elements.
After the sort() has completed you need to update the DOM to respect the new order of the elements. To do this you can call append() on the parent element, supplying the children as the argument.
Here's a working example with these issues addressed:
const sortButton = document.querySelector('.sortBtn');
const list = document.querySelector('.list');
const products = list.querySelectorAll('.products');
sortButton.addEventListener('click', () => {
const sortedElements = Array.from(products).sort((a, b) => a.textContent.localeCompare(b.textContent));
list.append(...sortedElements);
})
<div class="list">
<div class="products">Sugar</div>
<div class="products">Banana</div>
<div class="products">Apple</div>
</div>
<button type="button" class="sortBtn">Sort</button>
Convert the children of the parent element to an array. Then you can use the array sort() method to sort it, then append the children back to the parent in that order.
document.querySelector(".sortBtn").addEventListener("click", () => sortDiv(document.querySelector(".list")));
function sortDiv(parent) {
let children = [...parent.children];
children.sort((a, b) => a.innerText.localeCompare(b.innerText));
parent.innerHTML = '';
children.forEach(child => parent.appendChild(child));
}
<div class="list">
<div class="products"> Sugar </div>
<div class="products"> Banana </div>
<div class="products"> Apple </div>
</div>
<button class='sortBtn'>Sort</button>

Create list from each

I am looping through elements using jQuery like this:
$(".myelement").each(function() {
$element = $(this).closest(".panel").attr("id");
console.log($element);
});
This is working correctly and I am seeing each of the elements it finds in my console log. I am now trying to get a string containing each element that looks like this:
#element1, #element2, #element3
What is the easiest way to do this? Does anybody have an example they can point me at?
You could use map() to build an array of the id then join() it, something like this:
var ids = $(".myelement").map(function() {
return '#' + $(this).closest(".panel").prop("id");
}).get().join(', ');
console.log(ids);
You could use an array to store them by adding the # in every iteration, then after the loop end join them using join() method like :
var ids = [];
$(".myelement").each(function() {
ids.push('#' + $(this).closest(".panel").attr("id"));
});
console.log(ids.join(', '));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="element1" class="panel">
<span class="myelement">My element 1</span>
</div>
<div id="element2" class="panel">
<span class="myelement">My element 2</span>
</div>
<div id="element3" class="panel">
<span class="myelement">My element 3</span>
</div>
Try with map()
The .map() method is particularly useful for getting or setting the value of a collection of elements.
As the return value is a jQuery object, which contains an array, it's very common to call .get() on the result to work with a basic array.
You can use map(), get() and join()
in the following way:
var $element = $(".myelement").map(function(){
return $(this).closest(".panel").attr("id");
}).get().join(', ');
console.log($element);

How to add to all cloned elements an eventlistener?

I have this template:
<template id="a">
<div class="b">
<h1 class="placeholder1"></h1>
<div class="info hide">
<p class="p1"></p>
</div>
</div>
I am cloning it with:
fetch("json/countries.json").then(res => res.json()).then(list => show(list));
function show(list) {
list.forEach(function (list) {
const clone = template.cloneNode(true);
clone.querySelector(".placeholder1").textContent = list.country;
})}
I am trying to add an event listener to each cloned object, but the result is that it only adds it to the first cloned element, not the rest.
clone.querySelector(".placeholder1").addEventListener('click', fx_button1);
function fx_button1(){
document.querySelector(".info").classList.toggle("hide");
}
querySelector MDN only selects the first match found from the given selector. You need to use querySelectorAll MDN and then iterate the results.
var cloneSet = clone.querySelectorAll(".placeholder1");
for(var i = 0; i < cloneSet.length; i++){
cloneSet[i].addEventListener('click', fx_button1);
}

Looping through values in different div's

I'm trying to loop through different divs. I've got product arrays, but they are displayed in different div's. Is there a way to loop through them? I would like to put the available products (array.length) in an Array. The code is as followed:
<div id=Googletagsholderdiv data-gtm-ecommerce.purchase.actionField.id="x"
data-gtm-ecommerce.purchase.actionField.affiliation="x"
data-gtm-ecommerce.purchase.actionField.revenue="x"
data-gtm-ecommerce.purchase.actionField.tax="x"
data-gtm-ecommerce.purchase.actionField.shipping="x"
data-gtm-ecommerce.purchase.actionField.coupon="x">
<div data-gtm-ecommerce.purchase.products[0].name="x"
data-gtm-ecommerce.purchase.products[0].id="x"
data-gtm-ecommerce.purchase.products[0].price="x"
data-gtm-ecommerce.purchase.products[0].brand="x"
data-gtm-ecommerce.purchase.products[0].category="x"
data-gtm-ecommerce.purchase.products[0].variant="x"
data-gtm-ecommerce.purchase.products[0].quantity="x"
data-gtm-ecommerce.purchase.products[0].coupon="x"
data-gtm-ecommerce.purchase.products[0].dimensionX="x">
</div>
<div data-gtm-ecommerce.purchase.products[1].name="x"
data-gtm-ecommerce.purchase.products[1].id="x"
data-gtm-ecommerce.purchase.products[1].price="x"
data-gtm-ecommerce.purchase.products[1].brand="x"
data-gtm-ecommerce.purchase.products[1].category="x"
data-gtm-ecommerce.purchase.products[1].variant="x"
data-gtm-ecommerce.purchase.products[1].quantity="x"
data-gtm-ecommerce.purchase.products[1].coupon="x"
data-gtm-ecommerce.purchase.products[1].dimensionX="x">
</div>
<div data-gtm-ecommerce.purchase.products[2].name=""
data-gtm-ecommerce.purchase.products[2].id="x"
data-gtm-ecommerce.purchase.products[2].price="x"
data-gtm-ecommerce.purchase.products[2].brand="x"
data-gtm-ecommerce.purchase.products[2].category=""
data-gtm-ecommerce.purchase.products[2].variant="x"
data-gtm-ecommerce.purchase.products[2].quantity="x"
data-gtm-ecommerce.purchase.products[2].coupon="x"
data-gtm-ecommerce.purchase.products[2].dimensionX="x">
</div>
</div>
I think you should had a class to all your div with your desired data, and after, get all of them with jQuery.
You can select the parent element with any selector you like and get it's children with the children array.
Yoi can loop through this array using the for..of loop:
var Googletagsholderdiv = document.getElementById("Googletagsholderdiv");
for (var div of Googletagsholderdiv.children) {
console.log(div);
}
<div id=Googletagsholderdiv data-gtm-ecommerce.purchase.actionField.id="x" data-gtm-ecommerce.purchase.actionField.affiliation="x" data-gtm-ecommerce.purchase.actionField.revenue="x" data-gtm-ecommerce.purchase.actionField.tax="x" data-gtm-ecommerce.purchase.actionField.shipping="x"
data-gtm-ecommerce.purchase.actionField.coupon="x">
<div data-gtm-ecommerce.purchase.products[0].name="x" data-gtm-ecommerce.purchase.products[0].id="x" data-gtm-ecommerce.purchase.products[0].price="x" data-gtm-ecommerce.purchase.products[0].brand="x" data-gtm-ecommerce.purchase.products[0].category="x"
data-gtm-ecommerce.purchase.products[0].variant="x" data-gtm-ecommerce.purchase.products[0].quantity="x" data-gtm-ecommerce.purchase.products[0].coupon="x" data-gtm-ecommerce.purchase.products[0].dimensionX="x"></div>
<div data-gtm-ecommerce.purchase.products[1].name="x" data-gtm-ecommerce.purchase.products[1].id="x" data-gtm-ecommerce.purchase.products[1].price="x" data-gtm-ecommerce.purchase.products[1].brand="x" data-gtm-ecommerce.purchase.products[1].category="x"
data-gtm-ecommerce.purchase.products[1].variant="x" data-gtm-ecommerce.purchase.products[1].quantity="x" data-gtm-ecommerce.purchase.products[1].coupon="x" data-gtm-ecommerce.purchase.products[1].dimensionX="x"></div>
<div data-gtm-ecommerce.purchase.products[2].name="" data-gtm-ecommerce.purchase.products[2].id="x" data-gtm-ecommerce.purchase.products[2].price="x" data-gtm-ecommerce.purchase.products[2].brand="x" data-gtm-ecommerce.purchase.products[2].category=""
data-gtm-ecommerce.purchase.products[2].variant="x" data-gtm-ecommerce.purchase.products[2].quantity="x" data-gtm-ecommerce.purchase.products[2].coupon="x" data-gtm-ecommerce.purchase.products[2].dimensionX="x"></div>

Get concatenated text of elements using JavaScript

I tried it with getElementById and it worked. But now I want the same with multiple div's so I have to use classes. So I changed the method to getElementsByClassName and now it says undefined.
(The function is called when a option in a select changes. This works correctly)
HTML:
<div class="item_content">
<h3 class="filmnaam">22 jump street</h3>
</div>
<div class="item_content">
<h3 class="filmnaam">rio 2</h3>
</div>
Javascript:
function sorting(sortingway) {
alert(sortingway.value);
var titelfilms = document.getElementsByClassName("filmnaam");
var titels = titelfilms.innerHTML;
console.log(titels[0]);
}
Is there a way to do this without jQuery?
getElementsByClassName returns a collection, so loop that!
var titelfilms = document.getElementsByClassName("filmnaam");
for (var i = 0; i < titelfilms.length; i++) {
var titels = titelfilms[i].innerHTML;
console.log(titels);
}
titelfilms is a node list, you can't get the innerHTML of a node list as a whole, it contains multiple references to elements which each have their own individual property.
You could loop through and concatenate each innerHTML onto a variable, or you could map() the innerHTML of your returned elements to an array and then join() them up:
function sorting(sortingway) {
var titelfilms = document.getElementsByClassName("filmnaam");
var titels = Array.prototype.map.call(titelfilms, function (el) {
return el.innerHTML;
}).join(' ');
console.log(titels);
}
sorting();
<div class="item_content">
<h3 class="filmnaam">22 jump street</h3>
</div>
<div class="item_content">
<h3 class="filmnaam">rio 2</h3>
</div>

Categories

Resources