Four positions
Picture an element on the page. There are four places you can put new content relative to it:
<!-- .before() puts content here -->
<ul id="list">
<!-- .prepend() puts content here -->
<li>Existing item</li>
<!-- .append() puts content here -->
</ul>
<!-- .after() puts content here -->.prepend()and.append()insert inside the element, at the start or end..before()and.after()insert outside, as a sibling.
<ul id="list"><li>Existing item</li></ul>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
const $list = $("#list");
$list.append("<li>Appended (last)</li>");
$list.prepend("<li>Prepended (first)</li>");
$list.before("<p>Before the list</p>");
$list.after("<p>After the list</p>");
console.log($list.children().map((i, el) => $(el).text()).get().join(" | "));
console.log("previous:", $list.prev().text(), "| next:", $list.next().text());
</script>Prepended (first) | Existing item | Appended (last)
previous: Before the list | next: After the listWhat you can insert
All four methods accept:
- an HTML string:
.append("<li>New</li>"); - a jQuery object:
.append($("<li>", { text: name })); - a plain DOM element;
- an array of any of these;
- several arguments at once:
.append($a, $b, "<hr>"); - a function returning the content, called once per target element.
If the selection contains several elements, the content is inserted into each of them (copies are made for all but the last). That is convenient for adding the same badge to every card, but surprising if you meant to add one element: check .length on the target first if you are not sure how many elements it holds.
<div class="card"><h4>Lamp</h4></div>
<div class="card"><h4>Desk</h4></div>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$(".card").append(function (index) {
return $("<button>", { text: "Buy " + $(this).find("h4").text(), "data-index": index });
});
console.log($(".card button").map((i, el) => $(el).text()).get().join(", "));
</script>Buy Lamp, Buy DeskSwapped versions for chaining
Each method has a twin with the arguments the other way round:
| Target first | Content first |
|---|---|
$(target).append(content) |
$(content).appendTo(target) |
$(target).prepend(content) |
$(content).prependTo(target) |
$(target).after(content) |
$(content).insertAfter(target) |
$(target).before(content) |
$(content).insertBefore(target) |
The difference is what they return. .append() returns the target; .appendTo() returns the inserted content, so you can keep working on the new element:
<div id="toasts"></div>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("<div>", { text: "Settings saved", "class": "toast" })
.appendTo("#toasts")
.css("background", "#dcfce7")
.attr("role", "status");
console.log($("#toasts").html());
</script><div class="toast" role="status" style="background: rgb(220, 252, 231);">Settings saved</div>Inserting moves elements
An element can only be in one place in the page. If you insert an element that already exists, it moves:
<style> ul { border: 1px solid #ccc; min-height: 20px; padding: 4px 24px; } </style>
<p>To do</p>
<ul id="a"><li>Write report</li><li>Email Ravi</li></ul>
<p>Done</p>
<ul id="b"></ul>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#a").on("click", "li", function () {
$(this).appendTo("#b");
console.log("to do:", $("#a li").length, "| done:", $("#b li").length, "| moved:", $("#b li").text());
});
</script>to do: 1 | done: 1 | moved: Write reportClicking a task moves the same element to the Done list. Its event handlers and data go with it. Because nothing is copied, there is never a stale duplicate left behind, and the move is cheap even for large elements. This is also how drag-and-drop lists and "move up" and "move down" buttons work: select the item, then insert it before its previous sibling or after its next one, for example $item.insertBefore($item.prev()). (The handler here is attached in a special "delegated" way so it keeps working for moved items; the events section explains it.)
To keep the original and insert a copy, use .clone(), covered in the wrapping lesson.
Inserting text safely
.append("some string") treats a string that looks like HTML as HTML. When the content is plain text from a user, wrap it in an element with text, or append a text node:
<p id="greeting">Hello, </p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
const userName = "<b>Asha</b>";
$("#greeting").append(document.createTextNode(userName));
console.log($("#greeting").text());
</script>Hello, <b>Asha</b>The name is shown with its angle brackets rather than in bold.
A practical example: a live list
<input id="item" placeholder="Add an item">
<button id="add">Add</button>
<ol id="shopping"></ol>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#add").on("click", function () {
const text = $("#item").val().trim();
if (!text) return;
$("<li>", { text }).appendTo("#shopping");
$("#item").val("").trigger("focus");
console.log("items:", $("#shopping li").length, "| last:", $("#shopping li").last().text());
});
</script>items: 1 | last: Milk
items: 2 | last: BreadCommon mistakes
- Mixing up inside and outside:
.after()adds a sibling, not a child. - Expecting inserting to copy an existing element.
- Appending user text as a string that may contain HTML.
- Using
.appendTo()and expecting the container back for further chaining.
Exercise
You have a heading and a paragraph. Insert a horizontal rule (<hr>) after the heading, and a "Last updated" note at the start of the paragraph, using two different methods.
Show one possible answer
<h2 id="title">News</h2>
<p id="body">The site has a new jQuery course.</p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#title").after("<hr>");
$("#body").prepend($("<em>", { text: "Last updated today. " }));
console.log($("#body").text());
</script>Last updated today. The site has a new jQuery course.Key points
- .append() adds content inside an element at the end; .prepend() inside at the start.
- .after() and .before() add content outside, as the next or previous sibling.
- .appendTo(), .prependTo(), .insertAfter() and .insertBefore() do the same with the arguments swapped, which suits chains.
- Inserting an element that is already on the page moves it; it is not copied.