I have the following piece of HTML.
<div id="outer"><b class="dest">something</b>
<div id="test"><b class="dest">unwanted stuff</b></div>
</div>
Let's say I already have a reference to the outer element with document.querySelector("#outer"). How can I query all b elements with the dest class and are the first child of its parent? I tried document.querySelector("#outer").querySelector("b.dest") and document.querySelector("#outer").querySelector("b.dest:first-child") but only the first b element has returned. How can I get both b elements (through the result of document.querySelector("#outer"))?
.querySelector only selects one element max.
.querySelectorAll Returns an array-like node list.
You want:
var bElements = document.getElementById("outer").querySelectorAll('b.dest:first-child');
This will return an array of all elements that:
Have a parent with an id of outer
have the class dest
are the first-child of their parent
Then you can access each element just like an array, ex.
bElements[0]
DEMO:
var bElements = document.getElementById("outer").querySelectorAll('b.dest:first-child');
console.log(bElements)
<div id="outer"><b class="dest">something</b>
<div id="test"><b class="dest">unwanted stuff</b></div>
</div>
Related
I have an object that was retrieved from this expression:
const element = document.querySelector("...my selector...");
I need to get all child elements that have certain attributes, The only way I know to get all children is by:
const children = Array.from(element.childNodes);
but now each child in children is not an element, rather a node, hence, I cannot use getAttribute('') on them;
How do I "cast" a Node to an Element?, Or is there a better way to do this?
How do I "cast" a Node to an Element?
You can't.
Elements are a subset of Nodes.
If it isn't an Element already, then you can't turn it into one.
Consider:
<div>Hello, <strong>World</strong></div>
You have two child nodes. The text node "Hello, " and the strong element node.
It doesn't make sense to treat "Hello, " as an element.
Consider using children instead of childNodes. It fetches only element children.
I need to get all child elements that have certain attributes
In that case, you're probably better off just using a selector which gets you that in the first place. You'll need a child combinator and an attribute selector in addition to your existing selector. Then you'll need to use All to get more than one result.:
document.querySelectorAll("...my selector... > [someAttribute]"
You said you want to select all children with a specific attribute. So select them with querySelectorAll using an attribute selector.
var elems = document.querySelectorAll("#theParentSelector > [theChildsAttribute]")
console.log(elems.length)
Array.from(elems).forEach( function (el) {
console.log(el.getAttribute("theChildsAttribute"))
});
<div id="theParentSelector">
<div theChildsAttribute="1">Foo 1</div>
<div>Bar</div>
<div theChildsAttribute="2">Foo 2</div>
<div theChildsAttribute="3">Foo 3</div>
</div>
You'd use children to gain access to all HTML based nodes:
document.querySelector("...my selector...").children
I'm writing a function for swapping the position of child elements in a parent element.
<div class="parent">
<div class="first-child"></div>
<div class="second-child"></div>
</div>
So I'm getting the children of .parent turning the Nodelist into an array, reordering the array to swap the order / position of the elements i.e first-child, second-child becomes second-child, first-child - This all works perfectly. However, ideally the function will return the parent element with the reordered structure, but because I effectively spliced the nodelist into an array the elements in the array are no longer considered 'nodes' meaning I get an error when attempting to append it as a child to the parent.
So, how can I convert an array of elements back into a Nodelist as I understand that a Nodelist is not native to javascript?
Here's a Codepen of what I have so far. http://codepen.io/anon/pen/QNPKqB?editors=0011
Thanks!
The error in your code isn't that you need a NodeList, it's that you've named both a function and an element swap.
var parent = document.querySelector('.swap');
swap(parent, first, second);
Is what you need
I don't have a codepen account so instead, see the working code here:
https://jsfiddle.net/owr15hnf/
This is how you can convert HTML to node list,
const targetElement = document.getElementById('targetElement');
const htmlElementsArray = Array.from(targetElement.children).map(el => el.outerHTML)
// htmlElementsArray contains an array of HTML Elements.
console.log(htmlElementsArray,'ArrayList.')
const nodeList = new DOMParser().parseFromString([htmlElementsArray].join(''), "text/html").body.childNodes;
// nodeList is the converted Html list to node list
console.log(nodeList,'nodeList')
You can find the example here: https://codepen.io/furki911/pen/qByzdXm?editors=1111
Assuming that I have the following HTML:
<body>
<section role="main">
</section>
</body>
1) Can I do this?
var section = document.getElementsByTagName("section");
2) Can I do this?
var section = document.querySelector("section[role=main]");
3) And finally, how can I append childs to this element? appendChild() doesn't work.
var p = document.createElement("p").innerText("A paragraph.");
section.appendChild(p);
You can use either 1 or 2,
Using getElementsByTagName -
check out the fiddle - http://jsfiddle.net/2jzho6hh/3/
this one returns an array of all elements with tag name section, so to access the first section element you have to use the 0 index on the array. For the second element use 1 index on the array and so on..
Using querySelector,
check the fiddle - http://jsfiddle.net/2jzho6hh/2/
querySelector returns first element matching the selector you have specified as in this case section[role=main] which means select the first sectionelement with attribute role and its value being main
There is also one other method querySelectorAll which is, you may think, a union of above two methods. It selects elements on the basis of CSS selector syntax just like querySelector does and it returns an array of all elements matching the selector just like the getElementsByTagName
Correct code is
var p = document.createElement("p");
p.innerHTML="A paragraph";
section.appendChild(p);
don't add innerHTML at the time of declaring p.If you do so p will not return child node.Declare p as a node and then add innerhtml to it.
HTML
<div id="board">
<div>ab X</div>
<div>a <span class='target'>V</span> b</div>
<div>Xab</div>
<div>
I wanted to access the DOM place of V in my HTML and alert V, I must not use $('#board').eq(1).text().charAt(2). I need its DOM position so that I can easily trace the span that is wrapping the V.
THIS is not working, What's the right way?
alert($('#board').eq(1).eq(2).text());
This is the original problem, i can get someone who can help me so im trying to revised it How will i get the span class id under which the text belongs?
ALGORTIHM:
1. Found V from row looping and y looping
2. Find the span where it belongs to
Assuming span elements that have V text content should be selected, you can use .filter() method:
var $span = $('#board span').filter(function() {
return (this.textContent || this.innerText) === 'V';
});
Getting index of selected element:
$span.index();
Index of the V character within the text content of span's parent element:
var vIndex = $span.parent().text().indexOf('V');
Note that jQuery returns a jQuery-wrapped array of the selected elements, as you are using ID selector, the returned collection has only one wrapper/top-level selected element:
Object[div#board]
.eq(1)(just like getting an element by index from a simple array) returns the second top-level selected element that doesn't exist in the collection. Apart from that chaining .eq() methods in that way doesn't make any sense as it returns only one element.
I've tried
d3.select(".cell:first")
d3.selectAll(".cell").filter(":first")
d3.selectAll(".cell").select(":first")
but neither work
d3.select(".cell") already selects the first matched element:
Selects the first element that matches the specified selector string, returning a single-element selection. If no elements in the current document match the specified selector, returns the empty selection. If multiple elements match the selector, only the first matching element (in document traversal order) will be selected.
Source: https://github.com/mbostock/d3/wiki/Selections#wiki-d3_select
"How would I get the last item?"
D3 appears to return the results of d3.selectAll() in a collection, positioned in an array. For instance, requesting all paragraphs on the d3 homepage results in:
[ Array[32] ] // An array with a single array child. Child has 32 paragraphs.
So if we wanted to get the last paragraph from that collection, we could do the following:
var paragraphs = d3.selectAll("p");
var lastParag = paragraphs[0].pop();
Or more concisely:
var obj = d3.select( d3.selectAll("p")[0].pop() );
"What about :last-child?"
The :last-child selector isn't the same as getting the last element on a page. This selector will give you the elements that are the last child of their parent container. Consider the following markup:
<div id="foo">
<p>Hello</p>
<p>World</p>
<div>English</div>
</div>
<div id="bar">
<p>Oie</p>
<p>Mundo</p>
<div>Portuguese</div>
</div>
In this example, running d3.select("p:last-child") won't return any of your paragraphs. Even d3.selectAll("p:last-child") won't. Neither of those containers have a last child that is a paragraph (they are <div> elements: <div>English</div> and <div>Portuguese</div>).
If you want to get the first DOM element from the D3's selection, use .node() method:
var sel = d3.selectAll('p'); // all <P>, wrapped with D3.selection
var el = sel.node(); // the first <P> element