Reputation: 839
When attempting to pass an element created by the document.createElement
method, we encounter unusual results:
var Todo = (function () {
return {
items: [],
addItem: function () {
var task = document
.querySelector('#top-todo')
.value
.trim()
if (task !== '') {
this.items.push({ task, complete: false })
document.querySelector('#top-todo').value = ''
console.log('Added item: ' + task)
var newTodo = document.createElement('li')
.appendChild(document.createElement('p'))
.appendChild(document.createTextNode(task))
document.querySelector('#todo-list').appendChild(newTodo)
}
}
}
})()
<div>
<ul id="todo-list">
<li>
<input id="top-todo" placeholder="I need to..." type="text" />
</li>
</ul>
<input onclick="Todo.addItem()" type="button" value="add" />
</div>
Rather than a total failure or typeError we see only the textNode element being appended to the #todo-list
element. What is the cause of this behavior? And is there a valid way to use the method as an argument to append or insert?
Upvotes: 1
Views: 937
Reputation: 1
The returned value is the appended child.
You can chain .parentElement.parentElement
, the number of nested elements set as child elements of li
, to last .appendChild()
call to get reference to document.createElement('li')
at newTodo
var Todo = (function () {
return {
items: [],
addItem: function () {
var task = document
.querySelector('#top-todo')
.value
.trim()
if (task !== '') {
this.items.push({ task, complete: false })
document.querySelector('#top-todo').value = ''
console.log('Added item: ' + task)
var newTodo = document.createElement('li')
.appendChild(document.createElement('p'))
.appendChild(document.createTextNode(task))
.parentElement.parentElement
document.querySelector('#todo-list').appendChild(newTodo)
}
}
}
})()
<div>
<ul id="todo-list">
<li>
<input id="top-todo" placeholder="I need to..." type="text" />
</li>
</ul>
<input onclick="Todo.addItem()" type="button" value="add" />
</div>
Upvotes: 1
Reputation: 3220
document.createElement('li')
returns a li element
document.createElement('li')
.appendChild(document.createElement('p'))
returns a p element
document.createElement('li')
.appendChild(document.createElement('p'))
.appendChild(document.createTextNode(task))
returns a text node
So you are actually appending a text node.
Upvotes: 1
Reputation: 16875
var newTodo = document.createElement('li')
.appendChild(document.createElement('p'))
.appendChild(document.createTextNode(task))
.appendChild()
returns the element that was appended. When you chain functions, you get the last returned value in the chain.
It goes kinda like this:
li
(li
is current working value)p
p
to li
(p
is current working value)p
(text node is current working value)newTodo
.And then you go on to insert newTodo
, which is a text node, into the document.
Breaking it up like this would get you what you want:
var newTodo = document.createElement('li');
newTodo
.appendChild(document.createElement('p'))
.appendChild(document.createTextNode(task));
Upvotes: 1