jquery select child through random generated divs - javascript

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-']")

Related

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?

how to reference a child element on a cloned element

I am running some tests on a DOM element,
the result of the tests is one of the element descendants.
for example:
<div id="myelement" class="some-class">
<div class="some-child-class"></div>
<div class="some-other-child-class">
<div class="grandchild-class"></div>
<div class="another-grandchild"></div>*
</div>
</div>
let's assume that:
test(document.getElementById('myelement'));
will return the Element marked with asterisk
Now my problem is:
The test procedure is heavy and resource consuming.
I don't want to run it when i don't have to.
And sometimes, I clone an element that has already been tested (meaning - i KNOW the result of the test), but since I am getting an object reference as a result I can't use it to access the relevant child on the cloned element.
Is there any efficient way of somehow "save" the relative path from a parent Element to a specific descendant DOM element and then "apply" it on another element?
So you could assign unique ids to each element and cache the test results in an Object at the Elements id. However, i dont know if this is useful. An example implementation:
var test=function(el){
return this[el.id] || (this[el.id]=advancedtesting(el));
}.bind({});
So you could do:
test(document.getElementById('myelement'));//caches
test(document.getElementById('myelement'));//returns the cached
You could use jQuery for that.
The selectors they use can take the form of 'nth-child' or 'nth-of-type' (see documentation here).
What is does is that targets child element from the position they have relative from where you start from.
In your case if you want to start from your first element and go down to the starred one you can do:
$('#myelement').find('div:nth-child(2) > div:nth-child(2)')
What this does is that it takes #myelement as a base from which you will begin the search, and after that it goes down to the second child element that is a div, and again into this div's second child element.
You could reuse that selector with a different base.

Find first ancestor to be a child of an object with specific class using jQuery

I am looking for a correct way to find elements first ancestor to be a child of an element with a specific class.
Using XPath notation I'm looking for (if I didn't botch it):
./ancestor::*[../#class='my_class']
I guess I can run a while(...) loop calling parent() until current elements parent has specified class and go from there, but maybe there is some selector/filter/whatever in jQuery that can be used instead?
If I understood it correctly, you're trying to get the last ancestor when going up, before hitting the ancestor with '.my_class':
$(element).parentsUntil('.my_class').last()
See documentation.
In jquery find a child with specific class :
$("mycontrol").find(".myclass");
find parent with specific class :
$("mycontrol").closest(".myclass"); //return the first parent
Perhaps
jQuery(".my_class").parent().eq(0)
If I have this right.. First parent that is a child of an element with class "my_class":
Find all the elements with class .my-class and get the set of their children, then use .closest()
on your jQuery object, with that set as an argument.
$('myElementSelector').closest($('.my-class').children())
I think that should do it...

In CSS, is it possible to target class property identified by index number?

I'm trying to target a class element (appearing more than once in the DOM) by its index or iteration, strictly using CSS.
I know of several different ways of achieving this: I could toss the element(s) in an array and retrieve a specific index of said element (Javascript). I could label the element I'm trying to target with an #ID. I could refine the targeted element by specifying an attribute (.element[href="link"]). The pseudo-class :first-child and :last-child only target the children of that (parent) element (Duh!).
Example: I have a .class appearing 5 times within my DOM and I want to affect the CSS properties of the 3rd iteration of that .class element.
I wish there was a pseudo-class of .element:index-3. There's probably something out there that let's you do just that.
If I understand you correctly, you want to style the element with the content "Me!" in this example:
<body>
<p>Not me.</p>
<p class="me">Not me.</p>
<div><p class="me">Not me.</p></div>
<p class="me">Me!</p>
<div><div><p class="me">Not me.</p></div></div>
<p class="me">Not me.</p>
</body>
This should be possible In some cases (see below) it is possible with the pseudo-class :nth-of-type:
.me:nth-of-type(3) {color:red;}
As ScottS noted in the comments, this is only possible if all classes are on the same element type (e.g. p).
I have a .class appearing 5 times within my DOM and I want to affect the CSS properties of the 3rd iteration of that .class element.
I'm reading this as "target third element that uses .class across the entire DOM", e.g.:
<h1 class="class">...</h1> #1
<div>
<ul class="class"> #2
<li>...</li>
<li class="class">...</li> #3, target this one!
<li>...</li>
</ul>
<div class="class">...</div> #4
</div>
<p class="class">...</div> #5
Any :nth- pseudo-class notation represents an element qualified by the number of siblings matching a certain criteria (:nth-child(an+b) has an+b-1 siblings before it etc.).
CSS specification (including selectors level 4 draft) does not provide means of qualifying elements by index outside of sibling context (i.e. only individual nodes can be traversed, not the entire DOM tree). There is a performance reason behind this (traversing DOM is tough, imagine async content update, this is not how rendering engines work); but also something like :nth-element-ever(3) would be a very, very arbitrary criteria and would be better targeted by introduction of another class that means exactly what it does, preferably during code generation.
If the elements are not placed as adjacent siblings, or at least in the same "scope" (container element), there's no way for you to find out existence, iteration, or actually nothing about "related" elements.
Your best shot is either use a very ugly solution,
based on the assumption the elements are siblings, which might look like so: li.class:first-child + li + li { color: black; } to find the 3rd iteration,
or just use some JS to calculate occurance of an instace and insert it as a special class, like "gimme-css-here".

javascript : add some content in parentNode

What could be best way to add some content into ParentNode, if it has several child nodes without id.
the condition are :
<div class="parent_div">
<div class="child_div_1" > I need to add contents inside this div </div>
<div class ="child_div_2" onmouseover="addClass(this)"> </div>
</div>
My possible solution : function addClass(obj) {
obj.parentNode.firstChild.appendChild(...);
}
But i have doubt if someone changes the position of first child then what? according to you what could be best way to sort out this problem.
Use JQuery :
function addClass(obj) {
$(obj.parentNode)
.find("ClassName_in_which_you_want_to_append")
.append("your_derived_contents");
}
Note : find() it just look up the class_name whatever you want. Position doesn't matter. It just look up inside the parent node.
append() : just add the contents as a child
I hope this helps you a lot.
I'm not sure I understand. There must be something determining which element you want to put the content in and, if that's the case, it should have an ID (a unique element deserves a unique field, right?)
If those class names that you've defined (child_div_1) are meaningful to the element in which you need to insert content, you can use the method getElementsByClassName to select the correct element.
function addClass(obj) {
obj.parentNode.getElementsByClassName('child_div_1')[0].appendChild(/* ... */);
}
If the class names you've given in the example are just arbitrary, you're going to have to add some additional information to your block elements.
please add the ids for those tags that you need to refer to, it's much easier and more accurate for your javascript code to run.

Categories