How to test for and count dynamically numbered classnames with JavaScript - javascript

I have my object like so:
var text = document.getElementsByClassName('decode-text')[0];
It is a list of html elements that look like:
<div class="decode-text">
<div class="cycleText">
<div class="cycle-0">
<div class="text-animation">hey</div>
</div>
<div class="cycle-1">
<div class="text-animation">you</div>
</div>
<div class="cycle-2">
<div class="text-animation">guys</div>
</div>
</div>
</div>
I will just use indexof but want to understand why .contains returns false?
text.classList.contains('cycleText'); = false // why
Also any recommendations on getting the number of 'cycle-*' class names in this node list?

You can achieve this using css attribute selectors. The ^ means "starts with":
document.querySelectorAll('[class^="cycle-"]');

classList is a list of classes assigned to the current DOM element, and does not include the classes of its children.
The only entry of the list is decode-text.

Related

document.querySelectorAll - How to avoid getting nested elements with the given parameter?

I'm fetching one web and I need to get list of all elements with the given class name. The problem is that my array also contains nested elements (fetched from the parent) which also have the same class name.
Example:
<div class="someClass"></div>
<div class="someClass"></div>
<div class="someClass"></div>
<div class="someClass"></div>
<div class="someClass"></div>
In this case I'm gonna receive 5 elements instead of 4 - I want to avoid getting the nested one. Is there any solution to achieve what I'm looking for ?
Find all the elements that are members of the class
Convert the result to an array to get access to the filter method
Filter out any which match the selector "Descended from that class"
const allSomeClass = document.querySelectorAll(".someClass");
const filtered = Array.from(allSomeClass).filter(
element => !element.matches(".someClass .someClass")
);
console.log(filtered)
<div id=1 class="someClass"></div>
<div id=2 class="someClass">
<div id=3 class="someClass"></div>
</div>
<div id=4 class="someClass"></div>
<div id=5 class="someClass"></div>
See the documentation for matches if you need a polyfill to support very old browsers.
There aren't any nested divs in your example, but I think you meant this:
var divs = document.querySelectorAll("body > .someClass");
console.log(divs);
<div class="someClass"></div>
<div class="someClass">
<div class="someClass"></div>
</div>
<div class="someClass"></div>
<div class="someClass"></div>
You can target direct children of the body tag(or whatever container you're using) by using the child combinator >

How to get nested DOM

How to get nested DOM.
I want to get the nested DOM by Jquery.
For example.
<div id="red">
<div id="member">A</div>
</div>
<div id="blue">
<div id="member">B</div>
</div>
<div id="yellow">
<div id="member">C</div>
</div>
Is it possible to get the each memver id like, yellow.member
I want to do like this.
$("#yellow.member").removeClass("myclass");
The way you wanted to access the child element of #yellow was real close to be correct.
$("#yellow .member").removeClass("myclass");
Notice the added space. The space means to look for another matching element in the descendant tree of the element matched by the previous selector.
Now it's your markup that is wrong. You just cannot use the same id more than once. The concept of id comes from long before the computer age... An "identification" is unique per definition!
Here is how your markup should look like... in a working example where the interval is just for fun:
$(document).ready(function(){
setInterval(function(){
$("#yellow .member").toggleClass("myclass");
},1000);
});
.myclass{
background-color:yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="red">
<div class="member">A</div>
</div>
<div id="blue">
<div class="member">B</div>
</div>
<div id="yellow">
<div class="member">C</div>
</div>
You can use nested selectors with jQuery:
$('#yellow #member').removeClass('myclass');
Removes .myclass from the #member element inside #yellow.
Also, your HTML isn't valid. You can use an ID only once per document, so change all <div id="member"> ... </div> to <div class="member"> ... </div>. Then the selector passed to jQuery changes to
$('#yellow .member')
What you're after is the .find() method.
$("#yellow").find('#member').removeClass("myclass");
Or children()
$("#yellow").children('#member').removeClass("myclass");
or
$('#yellow>#member'),removeClass("myClass");
EDIT: Also don't have duplicate id's. Use class attribute instead.

Select children of specific classes

I have this:
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-6">
</div>
<div class="col-md-8">
</div>
<div class="col-md-12">
</div>
<div class="A">
</div>
<div class="B">
</div>
</div>
I want to select children of row class whose classes are col-md-4,6,8,12. Is there any good way to select all at once?
There can be multiple row divs and I am going to use wrapAll to wrap every row div's children in some other div. So if I use wrapAll, it just shifts all content of other row divs to the first row div. If I put the selector query inside loop, it just keeps wrapping the children times the number of row divs. I don't want to let this happen.
Are you understanding guys?
if You have other child elements with col-md-* and you do not want to target them. Then can use descendant child selector or .find():
$('.row .col-md-4,.row .col-md-6 ')
or
$('.row').find('.col-md-4,.col-md-6,.col-md-8,.col-md-12')
Otherwise you can use attribute contains selector:
$('.row [class*="col-md-"]')
Yeah you can use native 'querySelectorAll' function.
Like that :
document.querySelectorAll('.row [class*="col-md"]')
[class*="col-md"] means "All classes containing 'col-md"
A non-javascript solution
Try selecting them with the ^ or with the * selector. For example like:
[class^="col-md-"] {}
That will select elements with a class that starts with col-md-, thus, making the number at the end irrelevant.
or
[class*="col-md-"] {}
That will select elements with a class that contain col-md-.
Here's what the MDN says:
[attr^=value]
Represents an element with an attribute name of attr the
value of which is prefixed by "value".
[attr*=value]
Represents an element with an attribute name of attr the value of which contains at least one occurrence of string "value" as substring.
Demo:
.row [class^="col-md-"] {
color: red;
}
<div class="row">
<div class="col-md-4">
foo bar
</div>
<div class="col-md-6">
foo bar
</div>
<div class="col-md-8">
foo bar
</div>
<div class="col-md-12">
foo bar
</div>
<div class="A">
foo bar
</div>
<div class="B">
foo bar
</div>
</div>
$('.row>[class|="col-md"]')
.row is a class selector
> is a children selector
[] is a attribute selector
|= means prefix is
The code means that select the children of those with class "row", whose value of attribute class have a prefix "col-md".
Note1: according to the recommended rules, the value part of the attribute select (no matter it is a equals relation, prefix equals or other kinds of equals), the part after =, should be a string. Since the select has already been a string in '', you need to use "" to describe a string.
But if you use "" make the selector string, inside you need to use '' as a string.
Note 2: I just tried |="col-md-" but it does not work.

using document.querySelector with complex CSS selectors

In JavaScript I want to use document.querySelector to "grab" the last div (<div class="widget-footer">) in below HTML. However after many tries, I still can't figure out the correct CSS selector syntax to use.
The following code does not work:
document.querySelector (".skin-grid-widgets.ui-sortable.gridWidgetTemplatePositie.AgendaStandaard.disablesorting.hoogte-1-knoppen-0.breedte-1.widget-footer")
Here is the HTML I am working with
<div class="skin-grid enkeleKolom" id="Infobalk">
<div class="skin-grid-widgets ui-sortable">
<div class="gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1">
<div class="widget-header">
here comes the header text
</div>
<div class="widget-body">
some body text
</div>
<div class="widget-footer">
here comes the footer text
</div>
</div>
</div>
</div>
I've surfed everywhere to find example of complex CSS selectors used with querySelector, but to no avail. Any help would be really appreciated.
Your issue is you need a space in between each child element you are trying to select. If you do not have spaces in between your class selectors, by CSS specification, it will look for both classes on the same element.
Change your selector to look like the following:
var footer = document.querySelector(".skin-grid-widgets.ui-sortable .gridWidgetTemplatePositie.AgendaStandaard.disablesorting.hoogte-1-knoppen-0.breedte-1 .widget-footer");
footer.classList.add("highlight");
.highlight {
background-color: yellow;
}
<div class="skin-grid enkeleKolom" id="Infobalk">
<div class="skin-grid-widgets ui-sortable">
<div class="gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1">
<div class="widget-header">
here comes the header text
</div>
<div class="widget-body">
some body text
</div>
<div class="widget-footer">
here comes the footer text
</div>
</div>
</div>
</div>
try this:
<script>
document.querySelector (".skin-grid-widgets .gridWidgetTemplatePositie .widget-footer");
</script>
You don't need to add adjacent classes like "skin-grid-widgets ui-sortable" in querySelector, if you do so then query selector assumes that "skin-grid-widgets" is parent of "ui-sortable". Use just one of the classes at one DOM level.
The selector ain't complex, your thoughts are.
Listen to yourself, to the description you provide of what you want to select:
"grab" the last div in below HTML
Not grab the node with the class widget-footer inside of a node that has all these classes: gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1, inside a node ...
//a utility, because DRY.
//and because it's nicer to work with Arrays than with NodeLists or HTMLCollections.
function $$(selector, ctx=document){
return Array.from(ctx.querySelectorAll(selector));
}
//and the last div in this document:
var target = $$('div').pop();
or
"grab" <div class="widget-footer"> in below HTML
var target = document.querySelector("div.widget-footer");
or the combination: grab the last div.widget-footer in the HTML
var target = $$('div.widget-footer').pop();

How to manipulate certain class inside in a parent tag, getting the ID in jquery?

I want manipulate a certain class, selecting a ID like a parent, this way a want manipulate the class without define a ID in each class. In this example I want manipulate the class 3, but only the class inside on the div with ID b.
<div id="a">
<div class="1">
<div class="2">
<div class="3">
<div class="4">
</div>
<div id="b">
<div class="1">
<div class="2">
<div class="3"> // This tag is the selected to change
<div class="4">
</div>
<div id="c">
<div class="1">
<div class="2">
<div class="3">
<div class="4">
</div>
do
$("#b .3")
or if you wanna specifically get direct child of the parent
$("#b > .3")
Something like this should do the job:
var a = document.getElementById('b');
var b = a.getElementsByClassName('3');
alert (b[0].className)
SIDENOTE:
Why does it make sense to use javascript over jQuery?
CODE ops / sec
document.getElementById('b'); 12,137,211
$('#b'); 350,557
Vanilla JS is way faster...
You can enumerate selectors from the oldest parent to the deepest child, for your case:
$("#b .3)
Or easier to understand version:
$("#b).find(".3")
It first select elements with id b, then, from its children, it selects elements with class 3
If you have the ID in jQuery you should be able to just use $('#' + myId + ' .3') to select the desired element dynamically. In the given example myId would of course be 'b'. If its always the same element you want to access and all you need is the corresponding selector, then of course the static $('#b .3') or $('#b > .3') for a direct parent-child relationship suffice.

Categories