Selecting multiple second instances of a queryselectorAll element? - javascript

I am using Chartist and I need to send some data to the repeated second occurrence of an element. For example, there are two "ct-bar" elements inside every "ct-series" element. I need to select the second "ct-bar" element that is contained in each of the "ct-series" elements. I have tried doing this with a for loop and some other ways to no avail. How can I achieve this?
JS
const series = xChart.querySelectorAll('.ct-series .ct-bar')
for (var i = 0; i < series.length; i++) {
this.element = series[i];
var seriesNext = series[1]
}

Use the :nth-child() selector to get the 2nd child of each series.
const bars = xChart.querySelectorAll('.ct-series > .ct-bar:nth-child(2)');

You can use the :nth-child(2) css selector to just grab the 2nd ct-bar child under each ct-series. See below for how this would work.
const series = document.querySelectorAll('.ct-series > .ct-bar:nth-child(2)')
for (var i = 0; i < series.length; i++) {
console.log(series[i].textContent);
}
<div class="ct-series">
<span class="ct-bar">foo 1</span>
<span class="ct-bar">bar 1</span>
</div>
<div class="ct-series">
<span class="ct-bar">foo 2</span>
<span class="ct-bar">bar 2</span>
</div>

Related

Using css selector, how to grab nth child of of element using it's class

After getting the number of elements with a specific class, how do I iterate through them?
I am using webdriver to automate some tests. I can grab the number of elements with a specific class using
<div>
<tr class="test"></tr>
<tr class="test"></tr>
<tr class="test"></tr>
<tr class="test"></tr>
</div>
let trNum = (await client.elements("div > tr.test")).value.length;
trNum will equal 4 in this case. I want to iterate through each of the elements, preferably using nth-child. How can I do this?
I've tried
"div > tr.test:nth-child(1)"
but it didn't work
Use querySelectorAll to select the unknown amount of .test classes. After that, loop throught this list with querySelector because you know for sure the item exists.
<div>
<div class="test">item 1</div>
<div class="test">item 2</div>
<div class="test">item 3</div>
<div class="test">item 4</div>
</div>
<script>
// nodelist (in example node 0 - 3)
let divs = document.querySelectorAll(".test");
// How many nodes (in example 4)
let divCount = divs.length;
// loop through nth-child(1) - nth-child(4) <=== not 0 - 3
var i, selector, divItem;
for (i = 1; i <= divCount; i++) {
selector = ".test:nth-child(" + i + ")";
divItem = document.querySelector(selector);
console.log(divItem.innerHTML);
}
</script>
For explanation I did not put lines together.

Looping through html elements with the same class and finding the order of elements

I have created an image slider that has 3 images and 3 dots, each dot runs a function that loads an image, the first dot the first image etc.
Now what I'm asking is how can I create a loop for the javascript to do the same result instead of repeating myself for each button?
<span class="kcslider-dot" id="dot-1"></span>
<span class="kcslider-dot" id="dot-2"></span>
<span class="kcslider-dot" id="dot-3"></span>
$("#dot-1").click(function(){
currentSlide(1);
})
$("#dot-2").click(function(){
currentSlide(2);
})
$("#dot-3").click(function(){
currentSlide(3);
})
Another option is to use jQuery Data
<span class="kcslider-dot" data-slide-id="1" id="dot-1"></span>
<span class="kcslider-dot" data-slide-id="2" id="dot-2"></span>
<span class="kcslider-dot" data-slide-id="3" id="dot-3"></span>
$(".kcslider-dot").click(function(){
var slideId = $(this).data('slide-id');
currentSlide(slideId);
});
You can use [id^='dot-'] selector to select all the elements with id value starting with dot- then inside the click function get the numeric part after hyphen by doing split() on the idvalue:
USING jQuery
$("[id^='dot-']").click(function(){
var idNumber = this.id.split('-')[1];
currentSlide(idNumber);
});
function currentSlide(num){
console.log(num);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="kcslider-dot" id="dot-1">1</span>
<span class="kcslider-dot" id="dot-2">2</span>
<span class="kcslider-dot" id="dot-3">3</span>
USING JavaScript
var elem = document.querySelectorAll("[id^='dot-']");
for(var i=0; i<elem.length; i++){
elem[i].addEventListener('click', function(){
var idNumber = this.id.split('-')[1];
currentSlide(idNumber);
});
}
function currentSlide(num){
console.log(num);
}
<span class="kcslider-dot" id="dot-1">1</span>
<span class="kcslider-dot" id="dot-2">2</span>
<span class="kcslider-dot" id="dot-3">3</span>
You should use your class in the selector of jquery and then loop with the function "each". You can use a var that acts as counter o use an attribute in the html for get the parameter of the function "currentSlide"
var i = 1
$('span.kcslider-dot').each(function(){
currentSlide(i);
i++;
})
As long as all of your slides belong to the same class you can use class-selector instead of id. When you select all slides the output of the selection will be an array and the order will be the same as in the DOM. So after the selection you just may loop through that array and add listener to each element separately specifying certain slide using index:
let sliders = $(".kcslider-dot");
for(let i = 0; i < sliders.length; i++) {
sliders[i].click( () => {
currentSlide(i+1);
})
}
Cheers.
If the span elements are the only children of their parent you could use the jQuery .index() function to load the corresponding image.
Also you can attach the click event to the class instead of the id. That way you only need a single event handler.
e.g.
function currentSlide(index) {
console.log(index);
}
$(".kcslider-dot").click(function() {
currentSlide($(this).index() + 1);
});
.kcslider-dot {
display: inline-block;
width: 15px;
height: 15px;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="kcslider-dot" id="dot-1"></span>
<span class="kcslider-dot" id="dot-2"></span>
<span class="kcslider-dot" id="dot-3"></span>
</div>
You can use .each() of jQuery, it takes index as param. Then you just pass the index to the currentSlide() into the clicked context.
$('.kcslider-dot').each(function(index) {
$(this).click(function() {
currentSlide(index + 1);
})
})

Select nested elements by name attribute javascript(no jquery)

So I have this HTML code and I need to select the elements by their name attribute. The problem is I have multiple elements with the same structure and I need to go throw them with a loop.
<div class="res">
<h4 name="title">title</h4>
<span name="span1"></span>
<span name="span2"></span>
<p name="p1"></p>
<p name="p2"></p>
</div>
I need to select each one of the elements inside the .res div element by their name(or if there's a better solution I'd like to you).
document.getElementsByName("res");
document.getElementsByName("title");
document.getElementsByName("span");
or you can loop through the elements if you don't want to hard-code the name.
You could use .querySelector() like :
document.querySelector('[name="xxxxxx"]');
If you want to loop through all the res containers you could use .querySelctorAll() like :
var containers = document.querySelectorAll('.res');
for( var i = 0; i < containers.length; i++) {
console.log( containers[i].querySelector('[name="title"]').textContent );
}
You can use the DOM Element.children attribute in pure javascript
var children = res.children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
// Do stuff
}
You can use querySelectorAll and inside loop handle every element.
const elements = document.querySelectorAll(".res > *");
elements.forEach(element => {
console.log(element);
});
<div class="res">
<h4 name="title">title</h4>
<span name="span1"></span>
<span name="span2"></span>
<p name="p1"></p>
<p name="p2"></p>
</div>

Why wont my onclick not remove any of my classes?

I have a huge problem here.
I can't get my onclick to work as I want .. So I hope someone here can help me.
#NiceToKnow
<div id="cards" class="nice"></div>
<div id="cards" class="nice"></div>
<div id="cards" class="nice"></div>
<div id="cards" class="video"></div>
I want it to display: none; every of my class="nice", so you only can see class="video", but nothing happens at all.
You are selecting the elements of the class not the class itself. So you will have to loop through the elements as javascript can only edit what is in the DOM not the CSS classes that effect your elements. So getElementsByClassName returns an array of nodes in which we must loop through and hide each one. Click runsnippet below to see this work
function changeNice(){
//ASSIGN ELEMENTS TO ARRAY
elementsofClass=document.getElementsByClassName('nice');
for(i=0; i<elementsofClass.length; i++){
//HIDE SELECTED ELEMENT
elementsofClass[i].style.display='none';
}}
#NiceToKnow
<div id="cards1" class="nice">TEST 1</div>
<div id="cards2" class="nice">TEST 2</div>
<div id="cards3" class="nice">TEST 3</div>
<div id="cards4" class="video">I don't HIDE</div>
Also don't use duplicate ID. This will cause errors later when trying to select your elements.
The getElementsByClassName will return an array, so we need to iterate through the array and hide one by one.
So it is better to declare a function and define the logic inside that. Please see the example below.
window.hideAllniceClass = function () {
var elems = document.getElementsByClassName('nice');
for (var i = 0; i != elems.length; ++i) {
elems[i].style.display = "none"; // hidden has to be a string
}
}
#NiceToKnow
<div id="cards1" class="nice">Test Content</div>
<div id="cards2" class="nice">Test Content</div>
<div id="cards3" class="nice">Test Content</div>
<div id="cards4" class="video">Test Video Content</div>
DEMO
Change your code to something like that:
var elems = document.getElementsByClassName('nice');
for(var i = 0; i < elems.length; i++) {
elems[i].style.display = 'none'
}
You have to iterate on the results returned by getElementsByClassName.
jsfiddle
You can create a loop that will loop through all the nice elements and then display none like this: https://jsfiddle.net/7vf9pz8u/
<script>
function hide(){
for(ct=0; ct < 3; ct++){
document.getElementsByClassName('nice')[ct].style.display='none'
}
}
</script>
getElementsByClassName returns array of all the match elements so you will have to provide index or loop through all of them to change their property.
Change your code to this
document.getElementsByClassName('nice')[0].style.display='none'
//For every element
var e = document.getElementsByClassName('nice');
for (i = 0; i < e.length; i++) {
e[i].style.display = "none";
}
As your divs do not have unique names they are in an array cards[].
So to access a particular div you need to reference the the array to that particular div. The quoted solution should work.

JavaScript - how to delete elements that do not have a specific class?

I want to delete all elements that do not have the class 'stay'
For example:
<div class="stay">Stay</div>
<div class="stay">Stay</div>
<div class="go">Go</div>
<div class="element">Stay</div>
<div class="Sel">classy</div>
I would like some javascript that would delete the elements that do not have the class stay and Sel, without having to list the classes go and element
I have used:
var els = document.querySelectorAll('#parent :not(.stay)');
for (var i = 0; i < els.length; i++) {
els[i].parentNode.removeChild(els[i])
}
from the first answer, but am unsure of how to keep the class 'Sel'.
Also, I DO NOT want any Jquery.
When you are doing such an operation should need to target a particular parent element, else it could also remove elements like html/body etc.
So assuming you have a parent node, you can use querySelectorAll in conjunction with :not() selector
<div id="parent">
<div class="stay">Stay</div>
<div class="stay">Stay</div>
<div class="go">Go</div>
<div class="element">element</div>
</div>
then
var els = document.querySelectorAll('#parent :not(.stay)');
for (var i = 0; i < els.length; i++) {
els[i].parentNode.removeChild(els[i])
}
Demo: Fiddle

Categories

Resources