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

问题描述

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

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

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

我已参考以下stackoverflow文章来帮助我重写代码js-how-to-concatenate-variables-inside-appendchild-此示例使用join()和appendChild,但不使用列表项。

create-ul-and-li-elements-in-javascript- 从那一开始,我从Fiddle复制了代码,并将其放入example codepen

中的函数createul()中。

一旦函数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>