Accessing items at deeper levels using children() in jQuery - javascript

I want to access a simple button in an unknown nested level of a container.
Using container.children('button') allows me to access buttons in the first level, I.E.:
<div>
<button>test</button>
</div>
Trying to use the same with the following construct:
<div>
<div>
<button>test</button>
</div>
</div>
Fails, because the button is not a direct children. I could use element.children().children('button') but the depth of the button can change and this feels too strange.
I can also write my own function to iterate though all children to find what I need, but I guess jQuery does already have selectors for this.
So the question is:
How can I access children in an unknown depth using jQuery selectors?

How about
container.find('button');

by using .find()

Related

videoJS: mouseTimeDisplay $(selector, contextopt) method example

Looking at the documentation for videoJS for the mouseTimedDisplay and trying to understand it better.
How to I use the $ selector?
(Thinking I then can avoid using document.querySelector to get elements/components.)
It's a wrapper around querySelector that will search the component's element by default, unless a different starting element is given as a starting element.
Given the standard controls, player.controlBar.progressControl.seekBar.mouseTimeDisplay.$('div') would return the inner div (with the vjs-time-tooltip class) of the MouseTimeDisplay component.
<div class="vjs-mouse-display">
<div class="vjs-time-tooltip" aria-hidden="true"></div>
</div>
If you wanted the component's element (with vjs-mouse-display), you just use el().
You'd mostly use it when creating/extending custom player components.

ScrollIntoView in React without refs?

I have a big list of items / divs that I need to create programmatically, and I need to implement scrollIntoView buttons for each them. I know how to do it with refs.
Whether there is an alternative to refs that might be more performant?
I believe something like this will work:
onScrollClick(ev) {
ev.target.scrollIntoView();
}
render() {
return (
... <button onClick={this.onScrollClick}>Scroll This Element Into View</button>
)
}
That assumes you want to scroll the button itself into view. If that's not what you want, you'll have to be specific.
[edit] if it's not the element itself, but one of the elements parents, you can also find a parent with javascript apis, element.parentElement -- you can use that as many times as you need to find the relevant element.

Do HTML elements have 'hidden indexes' for the DOM?

For example, document.getElementsByClassName("whatever") returns a list of elements, and each element has an index (so the element x is the [3] in that list, for example).Do HTML elements save that index inside the element, somehow? Or they're 'unaware' of their position?
Example of the usage I'd do with that property:
You click an element with class "People", using event.target when onclick. So you want to know which position it has, in the 'People' list. Let's say it's event.target.classNameIndex. So once you know the index, you can do things in JavaScript.
Obviously the simple alternative I can think of this is simply picking event.target and searching it inside the getElementsByClassName list. Or simply giving IDs to all elements. But avoiding that would be nice.
Hope you understand my question. :)
No
The elements are generated either dynamically or statically and are independent from everything done with them after being displayed. There are pure javascript ways of obtaining the index of an element in a array-like structure but they will most likely depend on the use of a element.onClick function and pairing them with other elements via some sort of selector.
No, for lots of reasons.
First of all, you are doing a query on the internal DOM structure, and the DOM tree itself might change immediately after your query. Elements can be added, moved or removed.
Furthermore, two very different queries might have overlapping results. E.g. query 1 might return:
[ <div id="a">, <div id="b"> ]
While query 2 could return:
[ <div id="b">, <div id="c"> ]
(for simplicity I am representing the results as arrays)
In the above, how would the element <div id="b"> know its unique and unchanging "index", given the truly infinite amount of possible queries, not the mention the possibly variable DOM again?

jquery select child through random generated divs

I have a bunch of generated divs that I'd like to grab a specific child of.
Each one is roughly set up like this:
<div id="generated-row-N>
<div class="seriously-generated-crap">
<div id="still-seriously-generated-crap-N">
<input name="child-to-select-N">
</div>
</div>
</div>
Where N is a counter
I'm not well versed in all the different kinds of jQuery selectors, what I've attempted is a combination of the "begins with" selector and the "child" selector.
$("div[id^=generated-row-] > input[name^=child-to-select-]").each(function(){
// stuff I'm going to do to each input child
});
I assume my error is it's thinking the child is a direct child of the parent with no elements in between. Is there a way to get through the two other divs and grab a child regardless of how many levels deep it is?
note: I'm not listing the other childs because the generated class and id names are not reliable to use.
Thanks in advance. I haven't had much luck finding similar topics on SO, if this is a duplicate, please let me know.
> is the immediate children selector, just omit it.
And also wrap the values of your attributes with single quotes ''
$("div[id^='generated-row-'] input[name^='child-to-select-']")
You need to use descendant selector instead of child selector
$("div[id^=generated-row-] input[name^=child-to-select-]").each(function(){
// stuff I'm going to do to each input child
});
when you use a child selector it will search only the direct children of the target parent, in your case the input element is coming at the 3rd level means it is an descendant element not a child
Also to make it much easier apply class like
<div id="generated-row-N" class="generated-row">
<div class="seriously-generated-crap">
<div id="still-seriously-generated-crap-N">
<input name="child-to-select-N" class="child-to-select">
</div>
</div>
</div>
then
$(".generated-row input.child-to-select").each(function(){
// stuff I'm going to do to each input child
});
Use descendant selector,
$("div[id^=generated-row-] input[name^=child-to-select-]").each(function(){
// stuff I'm going to do to each input child
});
or use .find()
$("div[id^=generated-row-]").find("input[name^=child-to-select-]").each(function(){
// stuff I'm going to do to each input child
});
Please keep this in your mind, the elements which are located in the first level of the parent is said to be child elements, on the other hand the elements which are located more than one level deeper to the parent is called as descendants, Additionally children are also comes under the category of descendant.
You do not need immediate child selector.Use:
$("div[id^=generated-row-] input[name^=child-to-select-]").each(function(){
// stuff I'm going to do to each input child
});
If you assign a common css class to-process to your input elements, your code simplifies to
$(".to-process").each(function(){
// stuff I'm going to do to each input child
});
other advantages:
no need to worry about the actual embedding html structure of the elements of interest
common styling simplified
var test= $("div[id^='generated-row-'] input[name^='child-to-select-']")

access child DOM object from parent in dotted notation

Is there a way to select a child DOM object by treating it as data member of its parent DOM object? Imagine I have this code:
<div id=div1>
<div id=innerdiv1></div>
<div id=innerdiv2></div>
</div>
<div id=div2>
<div id=innerdiv1></div>
<div id=innerdiv2></div>
</div>
This example won't work in real life because both pairs of child divs have the same id's (innerdiv1, innerdiv2), but that's exactly what bothers me about the "id" thing.
Is there some way in javascript to access a child element as a data member, something like document.getElementById('div1.innerdiv1'), which would return a different object from document.getElementById('div2.innerdiv1').
I can't stand that each id has to be unique throughout the document. It becomes a major issue when you have a lot of code and you accidentally use the same id twice. It makes for really nasty bugs that are difficult to squash.
You can use document.querySelector in modern browsers. document.getElementById is pretty much obsolete.
document.querySelector('#div1 #innerdiv1')
You can use classes for the inner divs instead of ids, which do not need to be unique.
The document object has a getElementById method, but the returned elements do not have this method, and it couldn't take a string that isn't exactly the id of an element [if that's what you want try a library, like jQuery or Pumbaa80's suggestion of document.querySelector].
In some browsers you can try:
document.getElementById('div1').getElementsByTagName('div')[0]
As a side note, try dropping these two html documents into html5.validator.nu or http://validator.w3.org/#validate_by_input
<!DOCTYPE html><head><title>t</title></head><body>
<div id=div1><div id=d1>one</div><div id=d2>two</div>three</div>
<div id=div2><div id=d1>four</div><div id=d2>five</div>six</div>
</body>
Now you can totally avoid using the same id twice by just using classes instead.
<!DOCTYPE html><head><title>t</title></head><body>
<div id=div1><div class=d1>one</div><div class=d2>two</div>three</div>
<div id=div2><div class=d1>four</div><div class=d2>five</div>six</div>
</body>
For the first one, you could use document.querySelector('#div2 #d1') or $('#div2 #d1')
but I don't think the result would be guaranteed across all browsers due to the fact that this should be equivalent to writing document.querySelector('#d1') which you can see returns the first occurring id that matches, or $('#d1') which returns both id matching elements in an array.
And for the second one you could use document.querySelector('#div2 .d1') or $('#div2 .d1') or the other statements for very similar results, except that your html is valid this time. You don't even have to have css that defines d1 and d2 and if you used an attribute like class="d1 mySubHeading" and class="d2 mySubHeading" you could style both with mySubHeading and leave d1 and d2 there purely for selection via these methods.

Categories