How to set DOM element as first child?
Asked Answered
R

9

414

I have an element E and I'm appending some elements to it. All of a sudden, I find out that the next element to append should be the first child of E. What's the trick, how to do it? Method unshift doesn't work because E is an object, not array.

Long way would be to iterate through E's children and to move'em key++, but I'm sure that there is a prettier way.

Registration answered 5/1, 2010 at 16:19 Comment(1)
You guys are fast! I'm sorry, I think I was misunderstood. element e |- child-el_1 |- child-el_2 |- child-el_3 And then comes child-el_4 ... which needs to be fit as first child. prepend would put child-el_4 before [b]e[/b], am I wrong and tired or what?Registration
S
736
var eElement; // some E DOM instance
var newFirstElement; //element which should be first in E

eElement.insertBefore(newFirstElement, eElement.firstChild);
Spongy answered 5/1, 2010 at 16:35 Comment(8)
You my friend, just got your self a bear! Useful extra finding. docs.jquery.com/Manipulation/insertBeforeRegistration
For info if there is no element in the parent the child will be added anyway.Postcard
In case of firstChild is text node throws exception. but jquery prepend dousn't.Hemphill
@Sergey, works for me with text node too, tested on Firefox and Chromium. What browser did you use? Are you sure the problem was not on your side? Would you care to prepare a snippet/jsfiddle that reproduces the problem?Timbre
list.outerHTML = entry.outerHTML + list.outerHTML; Hope helps someone.Valadez
@DenizPorsuk setting outerHTML is destructive IIRC. The elements being re-created lose bound events and variable references.Dipteran
@SergeySahakyan use eElement.firstElementChildMischief
Why this only works with elements created in javascript and not with already existing (since pageload) DOM elements? At least for me any methods like prepend(), insertBefore() etc. just appended the element. Now i needed to createElement() programmatically and pass the original elem's properties to the freshly created one. This way prepending worked. Guess it's about some internal node order or so. Someone please explain. vanilla jsSoidisant
S
320

2018 version - prepend

parent.prepend(newChild)  // [newChild, child1, child2]

This is modern JS! It is more readable than previous options. It is currently available in Chrome, FF, and Opera.

The equivalent for adding to the end is append, replacing the old appendChild

parent.append(newChild)  // [child1, child2, newChild]

Advanced usage

  1. You can pass multiple values (or use spread operator ...).
  2. Any string value will be added as a text element.

Examples:

parent.prepend(newChild, "foo")   // [newChild, "foo", child1, child2]

const list = ["bar", newChild]
parent.append(...list, "fizz")    // [child1, child2, "bar", newChild, "fizz"]

Related DOM methods

  1. Read More - child.before and child.after
  2. Read More - child.replaceWith

Mozilla Documentation

Can I Use

Sternum answered 8/5, 2017 at 0:22 Comment(4)
Great solution, thanks! It irks me that they decided adding a child to the end is .appendChild() but adding it to the beginning is .prepend() instead of sticking to convention and calling it .prependChild()Soria
append() exists as well, works the same way as prepend(), but at the endSternum
I also got confused when I saw these questions asking about implementing prepend while I found it's already been that. :( Ok, it didn't exist in the past.Fredelia
@Marquizzo, Why not use append? For backcompat, obviously appendChild couldn't just be removed.Barnette
C
140

2017 version

You can use

targetElement.insertAdjacentElement('afterbegin', newFirstElement)

From MDN :

The insertAdjacentElement() method inserts a given element node at a given position relative to the element it is invoked upon.

position
A DOMString representing the position relative to the element; must be one of the following strings:
beforebegin: Before the element itself.
afterbegin: Just inside the element, before its first child.
beforeend: Just inside the element, after its last child.
afterend: After the element itself.

element
The element to be inserted into the tree.

In the family of insertAdjacent there is the sibling methods:

element.insertAdjacentHTML('afterbegin','htmlText')`

That can inject html string directly, like innerHTML but without override everything, so you can use it as a mini-template Engin and jump the oppressive process of document.createElement and even build a whole component with string manipulation process

element.insertAdjacentText for inject sanitize string into element . no more encode/decode

Caine answered 12/4, 2017 at 16:0 Comment(5)
great suggestion but why "back to 2017", this is a standard method even on ie8Accused
thanks. and another thank for your insight. title is for helping people distinguish quickly that is new answerCaine
What if element = document.importNode(documentfragment, true)?Conservancy
that return element typeof document-fragment that not have insertAdjacent...(). until we have a better answer your best guess is to append the fragment to a div . make your dom manipulation and then use Range.selectNodeContents() and Range.extractContents() to get back a fragmentCaine
where 'element' is the element in which you want to add, and 'element' is the element you want to add ;)Highbinder
P
15

You can implement it directly i all your window html elements.
Like this :

HTMLElement.prototype.appendFirst = function(childNode) {
    if (this.firstChild) {
        this.insertBefore(childNode, this.firstChild);
    }
    else {
        this.appendChild(childNode);
    }
};
Paraphrase answered 3/1, 2015 at 4:35 Comment(3)
prepend is the vanilla JS equivalent, without needing a prototype. It will be standard in ES7, and you should use if possible for your applicationSternum
@Sternum - DOM API methods have nothing to do with ECMAScript versions.Winterize
yorg - Just FYI, it's fine to pass null as the reference element in insertBefore, no need for your branch above.Winterize
O
8

Accepted answer refactored into a function:

function prependChild(parentEle, newFirstChildEle) {
    parentEle.insertBefore(newFirstChildEle, parentEle.firstChild)
}
Opec answered 16/7, 2015 at 16:27 Comment(1)
+1 for using parent child relationship. Accepted answer lacks that. I need to know what eElement is for it to make sense. And for that, I need to read the question. Most of the time, I just check the title and go directly to the answer, ignoring the question details.Pluralize
H
5

Unless I have misunderstood:

$("e").prepend("<yourelem>Text</yourelem>");

Or

$("<yourelem>Text</yourelem>").prependTo("e");

Although it sounds like from your description that there is some condition attached, so

if (SomeCondition){
    $("e").prepend("<yourelem>Text</yourelem>");
}
else{
    $("e").append("<yourelem>Text</yourelem>");
}
Hutcherson answered 5/1, 2010 at 16:23 Comment(3)
+1 for the $ version! I'm writing a jQuery extend func, so i'll use the native version whenever I can for performance reasons, but this is perfect!Liatris
Na, he's looking for JavaScript, not jquery.Tumefy
@Tumefy The jQuery tag has been there since the first revision, so that is highly misleading.Sprightly
A
2

I think you're looking for the .prepend function in jQuery. Example code:

$("#E").prepend("<p>Code goes here, yo!</p>");
Anabiosis answered 5/1, 2010 at 16:23 Comment(1)
You guys are fast! I'm sorry, I think I was misunderstood. element e |- child-el_1 |- child-el_2 |- child-el_3 And then comes child-el_4 ... which needs to be fit as first child. prepend would put child-el_4 before [b]e[/b], am I wrong and tired or what?Registration
T
0

I created this prototype to prepend elements to parent element.

Node.prototype.prependChild = function (child: Node) {
    this.insertBefore(child, this.firstChild);
    return this;
};
Tirza answered 20/8, 2017 at 17:27 Comment(0)
V
0
var newItem = document.createElement("LI");       // Create a <li> node
var textnode = document.createTextNode("Water");  // Create a text node
newItem.appendChild(textnode);                    // Append the text to <li>

var list = document.getElementById("myList");    // Get the <ul> element to insert a new node
list.insertBefore(newItem, list.childNodes[0]);  // Insert <li> before the first child of <ul>

https://www.w3schools.com/jsref/met_node_insertbefore.asp

Vlaminck answered 12/12, 2017 at 23:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.