【问题标题】:Converting string to DOM node (ul/li) in JavaScript with appendchild使用 appendchild 在 JavaScript 中将字符串转换为 DOM 节点(ul/li)
【发布时间】:2020-09-19 06:49:21
【问题描述】:

我正在尝试利用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()

【问题讨论】:

  • stackoverflow.com/questions/63509328/… 从处理函数返回false 不会阻止提交表单。这仅适用于内联侦听器代码。
  • 我有一个很大的问题,就是在我开始使用它之前页面会刷新为空白,但你说得对,当我将其注释掉时,它现在没有发生。我会进一步调查。
  • 原始代码示例(不包括在内)放在同一个地方。
  • 解决方法很简单,如果您不想提交表单,请不要提交。使用按钮类型的按钮,并监听该按钮的点击,而不是监听表单的提交事件。
  • 然后只需将事件对象参数包含在处理函数的参数列表中,并调用其preventDefault方法。另请注意,您也可以在 JS 中更改按钮的类型...

标签: javascript html dom appendchild


【解决方案1】:

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

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>

【讨论】:

  • 这非常令人印象深刻。非常干净整洁的代码,我可以从中学到很多东西。谢谢。
  • 我注意到渲染函数中第 22 行的 tasks.map。如果我不能使用 forEach,我正在考虑使用 map 数组函数,你举了一个比我想象的更好的例子。
  • 我很高兴能提供帮助。祝你的 JS 之旅好运!
  • 我注意到你没有使用';'。例如: const tasks = [ ] // 而不是: const tasks = [ ]; // 这是为什么?
  • 敏锐的眼睛,很好的捕捉! JavaScript 有automatic semicolon insertion,在大多数情况下你完全不需要它们。作为函数式风格的倡导者,当我在 JS 中需要 ; 时,我觉得这是我需要重组程序的问题。
猜你喜欢
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 2013-01-27
  • 2011-08-28
  • 2013-01-14
相关资源
最近更新 更多