简体   繁体   中英

Converting string to DOM node (ul/li) in JavaScript with appendchild

I am trying to make use of createElement , createTextNode and appendChild to rewrite an outdated simple to-do list code example.

The code example requires the use of the array join() method so, unfortunately, this can't be removed. The old version just wrote the HTML for the ul list in code fragments.

I am unsure how to proceed where I have entered to comment at line 30 of the js: " need to render the tasks (from stringToInsert) as a list to div id="output" here "

I have referred to the following stackoverflow articles to help me rewrite the code: js-how-to-concatenate-variables-inside-appendchild -This example uses join() and appendChild but not list items.

create-ul-and-li-elements-in-javascript - From that one, I copied the code from a Fiddle and put it into function createul() in my example codepen

Once I have the function addTask() working createul() and it's associated HTML elements (such as the render list button) will be removed.

 // tasks.js #2 // This script manages a to-do list. // Need a global variable: var tasks = []; function addTask() { 'use strict'; console.log("addTask started"); // Get the task: var task = document.getElementById('task'); // Reference to where the output goes: var output = document.getElementById('output'); if (task.value) { tasks.push(task.value); // Update the page: //var message = '<h2>To-Do</h2>'; var stringToInsert = tasks.join(' : '); console.log(stringToInsert); var taskUl = document.createElement('ul'); taskUl.setAttribute('id', 'autoTask'); document.getElementById('output').appendChild(taskUl); /* need to render the tasks (from stringToInsert) as a list to div id ="output" here */ document.getElementById("task").value = ''; } // Return false to prevent submission: return false; } // End of addTask() function. function createul() { var ul = document.createElement('ul'); ul.setAttribute('id', 'proList'); var t, tt; productList = ['Electronics Watch', 'House wear Items', 'Kids wear', 'Women Fashion']; document.getElementById('renderList').appendChild(ul); productList.forEach(renderProductList); function renderProductList(element, index, arr) { var li = document.createElement('li'); li.setAttribute('class', 'item'); ul.appendChild(li); t = document.createTextNode(element); li.innerHTML = li.innerHTML + element; } } function init() { document.getElementById('renderbtn').addEventListener("click", createul); document.getElementById('theForm').onsubmit = addTask; } window.addEventListener('load', init);
 /* css (I have simplified this a little for this example and I am sorry I haven't cut it down further) */ form { margin: 0 auto; width: 400px; padding: 14px; background-color: #ffffff; border: solid 2px #425955; } /* ----------- stylized ----------- */ h1 { font-size: 14px; font-weight: bold; margin-bottom: 8px; } p { font-size: 11px; color: #666666; margin-bottom: 20px; border-bottom: solid 1px #BFBD9F; padding-bottom: 10px; } label { display: block; font-weight: bold; text-align: right; width: 140px; float: left; } select { float: left; font-size: 12px; padding: 4px 2px; border: solid 1px #BFBD9F; width: 200px; margin: 2px 0 20px 10px; } input { float: left; font-size: 12px; padding: 4px 2px; border: solid 1px #BFBD9F; width: 200px; margin: 2px 0 20px 10px; } #submit { clear: both; margin-left: 150px; width: 125px; height: 31px; background: #F1F2D8; text-align: center; line-height: 20px; color: #000000; font-size: 12px; font-weight: bold; } #output { clear: both; margin-bottom: 10px; color: blue; }
 <form action="#" method="post" id="theForm"> <div><label for="task">Task</label><input type="text" name="task" id="task" required></div> <input type="submit" value="Add It!" id="submit"><br> <button type="button" id="renderbtn">render list</button> <div id="renderList"></div> <div id="output"></div>

edit: I can just convert it back to an array with something like the following if there is no other way of doing it.

var ar = stringToInsert.split(' : ');

or something based on:

stringToInsert.split(' : ').forEach ... or if that doesn't work I could try map()

I'm going to show you a different approach that may help clear things up -

 function ul (nodes) { const e = document.createElement("ul") for (const n of nodes) e.appendChild(n) return e } function li (text) { const e = document.createElement("li") e.textContent = text return e } function onSubmit (event) { event.preventDefault() tasks.push(f.taskInput.value) f.taskInput.value = "" render() } function render () { const newList = ul(tasks.map(li)) f.firstChild.replaceWith(newList) } const tasks = [ "wash dishes", "sweep floors" ] // <- initial tasks const f = document.forms.main // <- html form f.addButton.addEventListener("click", onSubmit) // <- button listener render() // <- first render
 <h3>todo list</h3> <form id="main"> <ul></ul> <input name="taskInput" placeholder="example: paint fence"> <button name="addButton">Add Task</button> </form>

And here's a more modern approach using a DOM library like React -

 const { useState, useRef } = React const { render } = ReactDOM function TodoList ({ initTasks = [] }) { const [ tasks, updateTasks ] = useState(initTasks) const inputEl = useRef(null) function onSubmit () { updateTasks([ ...tasks, inputEl.current.value ]) inputEl.current.value = "" } return <div> <h3>todo list</h3> <ul>{tasks.map(t => <li children={t} />)}</ul> <input ref={inputEl} placeholder="ex: paint fence" /> <button onClick={onSubmit}>add</button> </div> } render ( <TodoList initTasks={[ "wash dishes", "sweep floors" ]}/> , document.body )
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM