393

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.

Pang
  • 9,564
  • 146
  • 81
  • 122
Popara
  • 4,280
  • 2
  • 19
  • 19
  • 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? – Popara Jan 05 '10 at 16:35

9 Answers9

712
var eElement; // some E DOM instance
var newFirstElement; //element which should be first in E

eElement.insertBefore(newFirstElement, eElement.firstChild);
nemisj
  • 11,562
  • 2
  • 25
  • 23
  • 7
    You my friend, just got your self a bear! Useful extra finding. http://docs.jquery.com/Manipulation/insertBefore – Popara Jan 05 '10 at 17:02
  • 131
    For info if there is no element in the parent the child will be added anyway. – Knu Apr 12 '14 at 21:28
  • In case of firstChild is text node throws exception. but jquery prepend dousn't. – Sergey Sahakyan Oct 03 '16 at 16:40
  • 3
    @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? – user Dec 08 '16 at 15:19
  • list.outerHTML = entry.outerHTML + list.outerHTML; Hope helps someone. – Deniz Porsuk Sep 21 '18 at 07:59
  • @DenizPorsuk setting outerHTML is destructive IIRC. The elements being re-created lose bound events and variable references. – caiosm1005 Jul 02 '20 at 16:14
  • @SergeySahakyan use eElement.firstElementChild – Jan Turoň Sep 25 '20 at 14:38
  • 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 js` – Viktor Borítás Jan 18 '22 at 14:21
295

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

Gibolt
  • 42,564
  • 15
  • 187
  • 127
  • 31
    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()` – M - Jul 26 '19 at 00:30
  • 8
    `append()` exists as well, works the same way as `prepend()`, but at the end – Gibolt Jul 26 '19 at 06:39
  • 2
    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. – Rick Oct 25 '19 at 13:29
  • 1
    @Marquizzo, Why not use `append`? For backcompat, obviously `appendChild` couldn't just be removed. – Pacerier Aug 02 '20 at 13:35
138

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

pery mimon
  • 7,713
  • 6
  • 52
  • 57
  • 2
    great suggestion but why "back to 2017", this is a standard method even on ie8 – Vitaliy Terziev May 18 '17 at 13:28
  • thanks. and another thank for your insight. title is for helping people distinguish quickly that is new answer – pery mimon May 19 '17 at 15:47
  • What if element = document.importNode(documentfragment, true)? – Martin Meeser Feb 08 '18 at 09:27
  • 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 fragment – pery mimon Feb 18 '18 at 23:17
  • where 'element' is the element in which you want to add, and 'element' is the element you want to add ;) – bokkie Apr 17 '18 at 10:32
13

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);
    }
};
Andreas
  • 5,393
  • 9
  • 44
  • 53
yorg
  • 600
  • 5
  • 7
  • 2
    `prepend` is the vanilla JS equivalent, without needing a prototype. It will be standard in ES7, and you should use if possible for your application – Gibolt May 25 '17 at 00:01
  • @Gibolt - DOM API methods have nothing to do with ECMAScript versions. – T.J. Crowder Oct 19 '21 at 09:26
  • 2
    yorg - Just FYI, it's fine to pass `null` as the reference element in `insertBefore`, no need for your branch above. – T.J. Crowder Oct 19 '21 at 09:26
8

Accepted answer refactored into a function:

function prependChild(parentEle, newFirstChildEle) {
    parentEle.insertBefore(newFirstChildEle, parentEle.firstChild)
}
Joseph Dykstra
  • 1,416
  • 1
  • 15
  • 17
  • 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. – akinuri Oct 10 '17 at 07:49
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>");
}
James Wiseman
  • 29,946
  • 17
  • 95
  • 158
2

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

$("#E").prepend("<p>Code goes here, yo!</p>");
Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
  • 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? – Popara Jan 05 '10 at 16:37
0

I created this prototype to prepend elements to parent element.

Node.prototype.prependChild = function (child: Node) {
    this.insertBefore(child, this.firstChild);
    return this;
};
Raza
  • 3,147
  • 2
  • 31
  • 35
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

Ilker Cat
  • 1,862
  • 23
  • 17