使用 appendchild 将字符串转换为 JavaScript 中的 DOM 节点 (ul/li)

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

我正在尝试利用 createElementcreateTextNodeappendChild 重写一个过时的简单待办事项列表代码示例。

代码示例需要使用 array join() 方法,因此很遗憾,这无法删除。旧版本只是在代码片段中为ul列表写了HTML。

我不确定如何继续我在 js 第 30 行输入评论的地方:“需要将任务(来自 stringToInsert)作为列表呈现到 div id="output" 此处“

我参考了以下 Whosebug 文章来帮助我重写代码: - 此示例使用 join() 和 appendChild 但不使用列表项。

create-ul-and-li-elements-in-javascript- 从那个,我从 Fiddle and put it into function createul() in my example codepen

复制了代码

一旦函数 addTask() 开始工作 createul() 并且它的关联 HTML 元素(例如渲染列表按钮)将被删除。

// 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>

编辑:如果没有其他方法,我可以将它转换回数组,如下所示。

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

或基于以下内容:

stringToInsert.split(' : ').forEach ... 或者如果这不起作用我可以尝试 map()

我将向您展示一种可能有助于解决问题的不同方法 -

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>

这里有一个更现代的方法,使用像 React 这样的 DOM 库 -

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>