For inserting an element after another element in JavaScript can be done in some ways. Let’s see which are they and try examples.
To insert an element after another element you should use the insertBefore[] method. Here is the syntax:
referenceNode.parentNode.insertBefore[newNode, referenceNode.nextSibling];
Here referenceNode is the node that you want to put after newNode. If the referenceNode is the last child, the referenceNode.nextSibling will be null and insertBefore can handle the case by adding to the end of the list:
Title of the Document
#divId {
color: green;
font-size: 25px;
}
span {
color: blue;
font-size: 20px;
}
Welcome to W3docs
function insertAfter[referenceNode, newNode] {
referenceNode.parentNode.insertBefore[newNode, referenceNode.nextSibling];
}
let elem = document.createElement["span"];
elem.innerHTML = "It's a Javascript book";
let div = document.getElementById["divId"];
insertAfter[div, elem];
You can also use one of the newest approaches: the insertAdjacentElement[] method which inserts a given element node at a specified position relative to the element it is executed upon:
... content ...
The Node.insertBefore[] method is used to insert a node before a reference node as parent node's child. If the specified node exists in the document, insertBefore[] moves it from its current position to the new position, meaning that a node cannot be in two locations of the document at the same time.
DOM navigation properties are great when elements are close to each other. What if they are not? How to get an arbitrary element of the page?
There are additional searching methods for that.
document.getElementById or just id
If an element has the id
attribute, we can get the element
using the method document.getElementById[id]
, no matter where it is.
For instance:
Element
// get the element
let elem = document.getElementById['elem'];
// make its background red
elem.style.background = 'red';
Also, there’s a global variable named by id
that references the element:
Element
// elem is a reference to DOM-element with id="elem"
elem.style.background = 'red';
// id="elem-content" has a hyphen inside, so it can't be a variable name
// ...but we can access it using square brackets: window['elem-content']
…That’s unless we declare a JavaScript variable with the same name, then it takes precedence:
let elem = 5; // now elem is 5, not a reference to
alert[elem]; // 5
Please don’t use id-named global variables to access elements
This behavior is described in the specification, so it’s a kind of standard. But it is
supported mainly for compatibility.
The browser tries to help us by mixing namespaces of JS and DOM. That’s fine for simple scripts, inlined into HTML, but generally isn’t a good thing. There may be naming conflicts. Also, when one reads JS code and doesn’t have HTML in view, it’s not obvious where the variable comes from.
Here in the tutorial we use id
to directly reference an element for brevity, when it’s obvious where the element comes from.
In real life document.getElementById
is
the preferred method.
The id
must be unique
The id
must be unique. There can be only one element in the document with the given id
.
If there are multiple elements with the same id
, then the behavior of methods that use it is unpredictable, e.g. document.getElementById
may return any of such elements at random. So please stick to the rule and keep id
unique.
Only document.getElementById
, not anyElem.getElementById
The
method getElementById
can be called only on document
object. It looks for the given id
in the whole document.
querySelectorAll
By far, the most versatile method, elem.querySelectorAll[css]
returns all elements inside elem
matching the given CSS selector.
Here we look for all
elements that are last children:
- The
- test
- has
- passed
let elements = document.querySelectorAll['ul > li:last-child'];
for [let elem of elements] {
alert[elem.innerHTML]; // "test", "passed"
}
This method is indeed powerful, because any CSS selector can be used.
Can use pseudo-classes as well
Pseudo-classes in the CSS selector like :hover
and :active
are also supported. For instance, document.querySelectorAll[':hover']
will return the collection with elements that the pointer is over now [in nesting order: from the outermost
to the most nested one].
querySelector
The call to elem.querySelector[css]
returns the first element for the given CSS selector.
In other words, the result is the same as elem.querySelectorAll[css][0]
, but the latter is looking for all elements and picking one, while elem.querySelector
just looks for one. So it’s faster and also shorter to write.
matches
Previous methods were searching the DOM.
The elem.matches[css] does not look for anything, it merely checks if elem
matches the given CSS-selector. It returns true
or false
.
The method comes in handy when we are iterating over elements [like in an array or something] and trying to
filter out those that interest us.
For instance:
...
...
// can be any collection instead of document.body.children
for [let elem of document.body.children] {
if [elem.matches['a[href$="zip"]']] {
alert["The archive reference: " + elem.href ];
}
}
closest
Ancestors of an element are: parent, the parent of parent, its parent and so on. The ancestors together form the chain of parents from the element to the top.
The method elem.closest[css]
looks
for the nearest ancestor that matches the CSS-selector. The elem
itself is also included in the search.
In other words, the method closest
goes up from the element and checks each of parents. If it matches the selector, then the search stops, and the ancestor is returned.
For instance:
Contents
- Chapter 1
- Chapter 2
let chapter = document.querySelector['.chapter']; // LI
alert[chapter.closest['.book']]; // UL
alert[chapter.closest['.contents']]; // DIV
alert[chapter.closest['h2']]; // null [because h2 is not an ancestor]
getElementsBy*
There are also other methods to look for nodes by a tag, class, etc.
Today, they are mostly history, as querySelector
is more powerful and shorter to write.
So here we cover them mainly for completeness, while you can still find them in the old scripts.
elem.getElementsByTagName[tag]
looks for elements with the given tag and returns the collection of them. The tag
parameter can also be a star "*"
for “any tags”.elem.getElementsByClassName[className]
returns elements that have the given CSS class.document.getElementsByName[name]
returns elements with the given name
attribute, document-wide. Very rarely used.
For instance:
// get all divs in the document
let divs = document.getElementsByTagName['div'];
Let’s find all input
tags inside the table:
Your age:
less than 18
from 18 to 50
more than 60
let inputs = table.getElementsByTagName['input'];
for [let input of inputs] {
alert[ input.value + ': ' + input.checked ];
}
Don’t forget the "s"
letter!
Novice developers sometimes forget the letter "s"
. That is, they try to call getElementByTagName
instead of getElementsByTagName
.
The "s"
letter is absent in getElementById
, because it returns a single element. But getElementsByTagName
returns a collection of elements, so there’s "s"
inside.
It returns a collection, not an element!
Another widespread novice mistake is to
write:
// doesn't work
document.getElementsByTagName['input'].value = 5;
That won’t work, because it takes a collection of inputs and assigns the value to it rather than to elements inside it.
We should either iterate over the collection or get an element by its index, and then assign, like this:
// should work [if there's an input]
document.getElementsByTagName['input'][0].value = 5;
Looking for .article
elements:
Article
Long article
// find by name attribute
let form = document.getElementsByName['my-form'][0];
// find by class inside the form
let articles = form.getElementsByClassName['article'];
alert[articles.length]; // 2, found two elements with class "article"
Live collections
All methods "getElementsBy*"
return a live collection. Such collections always reflect the current state of the document and “auto-update” when it changes.
In the example below, there are two scripts.
- The first one creates a reference to the collection of
. As of now, its length is 1
.- The
second scripts runs after the browser meets one more
, so its length is 2
.First div
let divs = document.getElementsByTagName['div'];
alert[divs.length]; // 1
Second div
alert[divs.length]; // 2
In contrast, querySelectorAll
returns a static collection. It’s like a fixed array of elements.
If we use it instead, then both scripts output 1
:
First div
let divs = document.querySelectorAll['div'];
alert[divs.length]; // 1
Second div
alert[divs.length]; // 1
Now we can easily see the difference. The static collection did not increase after the appearance of a new div
in the document.
Summary
There are 6 main methods to search for nodes in DOM:
Method
Searches by...
Can call on an element?
Live?
querySelector
CSS-selector
✔
-
querySelectorAll
CSS-selector
✔
-
getElementById
id
-
-
getElementsByName
name
-
✔
getElementsByTagName
tag or '*'
✔
✔
getElementsByClassName
class
✔
✔
By far the most used are querySelector
and querySelectorAll
, but getElement[s]By*
can be sporadically helpful or found in the old scripts.
Besides that:
- There is
elem.matches[css]
to check if elem
matches the given CSS selector. - There is
elem.closest[css]
to look for the nearest ancestor that matches the given CSS-selector. The elem
itself is also checked.
And let’s mention one more method here to check for the child-parent relationship, as it’s sometimes
useful:
elemA.contains[elemB]
returns true if elemB
is inside elemA
[a descendant of elemA
] or when elemA==elemB
.
How do you add an element after another element?
To insert an element after an existing element in the DOM tree, you follow these steps: First, select the parent node of the existing element. Then, insert the new element before [insertBefore[]] the next sibling [nextSibling] of the existing element.
How do you get siblings of an element?
To get all siblings of an element, we'll use the logic:. First, select the parent of the element whose siblings that you want to find.. Second, select the first child element of that parent element.. Third, add the first element to an array of siblings.. Fourth, select the next sibling of the first element..
What is next sibling in JavaScript?
The read-only nextSibling property of the Node interface returns the node immediately following the specified one in their parent's childNodes , or returns null if the specified node is the last child in the parent element.
How do I get after JavaScript?
In JavaScript, to get the content property value, as specified by ::after pseudo-element, you can use the window. getComputedStyle[] method. It exposes the CSSStyleDeclaration object [as read-only], from which you can access the style information of ::after pseudo-element.
Chủ Đề