I have an interface that switches between displaying different div elements. When it switches which element it displays, I need to access a specific child node of that div element, with each div element having their children arranged differently.
The childNodes and children property both return an object that can only select children with item(index) which is annoying to use as the relevant child element's index is different in each div. For Protractor, I used the webmanager.by(selector) which was able to search with other parameters than index. Is there something similar I can use to select the child node with data-relevant="true". I am also unsure if that attribute is the best way to specify in the HTML which child node is relevant.
This is an Angular application if that helps.
If you want to select the child node with data-relevant="true" from some parent element, you could use the selector method
element.querySelector()
That would return the first matching element...
in your specific case it could be something like
parent-element.querySelector( "[data-relevant='true']" );
or if you want to select all paragraphs p with the data-relevant attribute value true within the parent div: parentDiv.querySelectorAll( "p[data-relevant='true']" );
You can find some examples on
http://www.w3.org/TR/selectors-api/#processing-selectors
An alternative would be to use a special class to identify which child node is relevant...
you could get this element/or many elements with getElementsByClassName(someClassName)
Code Sample With .querySelectorAll() method:
<script type="text/javascript">
window.addEventListener("load", init, false);
function init(){
var parentDiv = document.getElementById("divWithChildren");
var relevantChildren = parentDiv.querySelectorAll( "[data-relevant='true']" );
alert (relevantChildren[2].id); // this will give the id of the 3rd child element with data-relevant='true'
}
</script>
Related
Suppose that I want to add a newly created paragraph (using document.createElement("p")) into an existing div (with class name "container") in one of my html files. Is there a way to do this by calling some methods?
Since there's a getElementById() method, I figured I would use a getElementByClassName() method too, but that doesn't exist; what exists is getElementsByClassName() instead. One way I can get around this is to just change my div to have an id rather than a class name, and use the getElementById() to add the paragraph into the div, but I wanted to know if there was some method that I could call that would help me retrieve a class element (rather than the elements within the class itself).
I've tried looking for this online, but what I've found are answers to "how to add class names to elements" instead, which is not what I want to know.
For one element, this will chose first in DOM order:
var p = document.createElement("p");
p.innerHTML = "p element";
document.querySelector(".container").appendChild(p);
<div class="container">container</div>
For all elements with chosen class:
[...document.querySelectorAll('.container')].forEach(el => {
var p = document.createElement("p");
p.innerHTML = "p element";
el.appendChild(p);
})
<div class="container">container</div>
<div class="container">container2</div>
HTML DOM elements' IDs have to be unique within a document - and so asking for an element by Id will return you just one element (or null if there isn't a matching element).
However a class name can be applied to multiple elements, so you would expect to get zero one or more elements when searching by class, hence the getElementsByClassName returns a collection.
So if you have a list of elements with the class name container, and you know your document (hopefully) only contains one element with that name, you can pick the first element returned by the getElementsByClassName - e.g. getElementsByClassName('container')[0]
Note - getElementsByClassName returns all elements to which the class has been directly applied, for the children of the element on which it is being called. I've interpreted your query as relating to the whole document in the context of your original question.
From the starting point of an element that happens to be a select box (element has a class of: service_category_selection) I want to find another select box (element has a class of: service_selection).
I need to grab specifically the closest element with class: service_selection because I don't want to grab all of the elements with that class.
Snapshot of how far away that first select box is from the second select box:
Assume that $(this) already contains the first select box. Now I just need to draw the route to the closest next select box with the class: service_selection.
I attempted to use .closest but it wasn't working for me.
Example: var el = $(this).closest(".service_selection");
You need to get the overall top parent container - then find the element:
var el = $(this).closest(".row").find(".service_selection");
Doing this kind of navigation is a bit hackish and easy to break since your logic highly rely on your layout. I suggest you to use a unique CSS class on that element and access it directly.
I'm quite new to javascript and JQuery programming. Usually, to access elements I give them an id, so I can get them like $("#"+id).blabla().
But now I need to dynamically create a div, and access elements inside it.
Something like
<div id="automaticallyGeneratedId">
<div ???></div> <!-- first div -->
<div ???></div> <!-- second div -->
</div>
What are the best practices to access and identify each of the inner divs?
I generate another id for them?
Or what?
I don't have the theory of selectors fully clear.
edit: modified the question from identifying a single inner div to identifying divs amongs many of them
You can maintain a pattern when you're generating id. For example:
if you always generate id like: myid1, myid2,myid3...
<div id="myid1">
<div></div>
</div>
<div id="myid2">
<div></div>
</div>
......
then you can try:
$('div[id^=myid]').find('div').foo();
OR
$('div[id^=myid] div').foo();
Here, ^= is start with selector, so div[id^=myid] will select div whose id start with myid.
You can also use Contain word selector which is ~= and use like $('div[id~=myid]'). This will select div with id contains word myid.
Instead of id if you want to use other attribute eg. name then change selector like:
$('div[name^=myid]') or $('div[name~=myid]').
It's usually a good practice that if you already have a reference to that outer div to just search from there using find.
You can give it an id, or if you want to use a more general approach you can use classes.
<div class="subdiv">...
$('#automaticallyGeneratedId').find('div.subdiv')
Usually, when you create them, you can assign event handlers and the likes straight on them. Like this:
var div = $( '<div></div>' );
div.on( 'click', function() {
// Do something when the generated div is clicked
});
// Then, add it to the DOM
$( 'body' ).append( div );
You don't need to bother selecting them with ID or classes, they're already available in your code.
Another way is to use event bubbling to handle newly created elements of the same class. A good link about this is this one: http://beneverard.co.uk/blog/understanding-event-delegation/
Many ways you can create an element and give him an Id or Class, or use the DOM to access it..
$("html").prepend('<div id="foo"></div>');
$("#foo").doSomething();
another way
$("#automaticallyGeneratedId").find("div").doSomething();
To access the div in the element with the id:
$("#automaticallyGeneratedId div").whatever
If you cache the divs you could use something like:
var myDiv1Child = $('div', myDiv1);
Create a delegated listener and within the listener you can find the element by doing this
//If a div inside the parent is clicked then execute the function within
$('.PARENT_CLASS').click("div", function(){
//This variable holds all the elements within the div
var rows = document.querySelector('.PARENT_CLASS').getElementsByTagName('div');
for (i = 0; i < rows.length; i++) {
rows[i].onclick = function() {
console.log(this); //The element you wish to manipulate
}
}
});
I am trying to delete the child element in the dom from its parent using jquery.
Here is the code snippet.
$('#delete').live('click' , function() {
var strchild = m.split("/",2)[1];
var c = group.children(strchild);
c.remove();
});
strchild contains the id of the child element. group is the parent object. I am getting the right child element in the variable c. But the remove function fails.
Can some help me out here.
Thanks.
If you have
strchild
as the id of the element you want to remove, you can do
$("#" + strchild).remove()
assuming it is the only element with that id (it should be, that's the whole point of id).
EDIT:
With multiple ids, you would need to reference the parent specifically. This is very simple, since you say in your question that group is the parent object. This answer assumes it is the object itself, rather than the id, as your code sample implies.
$("#" + strchild, group).remove()
Adding the second argument here constrains the selector to the specifications of that second argument. So this will search the parent (group) for an element with the id strchild, and then remove that element.
<div onclick="test(this)">
Test
<div id="child">child</div>
</div>
I want to change the style of the child div when the parent div is clicked. How do I reference it? I would like to be able to reference it by ID as the the html in the parent div could change and the child won't be the first child etc.
function test(el){
el.childNode["child"].style.display = "none";
}
Something like that, where I can reference the child node by id and set the style of it.
Thanks.
EDIT: Point taken with IDs needing to be unique. So let me revise my question a little. I would hate to have to create unique IDs for every element that gets added to the page. The parent div is added dynamically. (sort of like a page notes system). And then there is this child div. I would like to be able to do something like this: el.getElementsByName("options").item(0).style.display = "block";
If I replace el with document, it works fine, but it doesn't to every "options" child div on the page. Whereas, I want to be able to click the parent div, and have the child div do something (like go away for example).
If I have to dynamically create a million (exaggerated) div IDs, I will, but I would rather not. Any ideas?
In modern browsers (IE8, Firefox, Chrome, Opera, Safari) you can use querySelector():
function test(el){
el.querySelector("#child").style.display = "none";
}
For older browsers (<=IE7), you would have to use some sort of library, such as Sizzle or a framework, such as jQuery, to work with selectors.
As mentioned, IDs are supposed to be unique within a document, so it's easiest to just use document.getElementById("child").
This works well:
function test(el){
el.childNodes.item("child").style.display = "none";
}
If the argument of item() function is an integer, the function will treat it as an index. If the argument is a string, then the function searches for name or ID of element.
If the child is always going to be a specific tag then you could do it like this
function test(el)
{
var children = el.getElementsByTagName('div');// any tag could be used here..
for(var i = 0; i< children.length;i++)
{
if (children[i].getAttribute('id') == 'child') // any attribute could be used here
{
// do what ever you want with the element..
// children[i] holds the element at the moment..
}
}
}
document.getElementById('child') should return you the correct element - remember that id's need to be unique across a document to make it valid anyway.
edit : see this page - ids MUST be unique.
edit edit : alternate way to solve the problem :
<div onclick="test('child1')">
Test
<div id="child1">child</div>
</div>
then you just need the test() function to look up the element by id that you passed in.
If you want to find specific child DOM element use method querySelectorAll
var $form = document.getElementById("contactFrm");
in $form variable we can search which child element we want :)
For more details about how to use querySelectorAll check this page