我是HTML和JS的新手,我面临以下问题:
我在html中有一个输入,它创建了一个新的li元素(结合JS);是否可以为每个新创建的li元素提供自己的id?例如,删除特定元素?
例如:
<li id="one"> .. </li>
<li id="two"> .. </li>到目前为止,它只创建了<li> ... </li>
我认为可以用for循环来完成它,但是我不知道如何在我的例子中使用它。
请参见下面的JS代码:
function NewEntry() {
var Inputfield = document.getElementById("Inputfield");
var AddButton = document.getElementById("AddButton");
var ul = document.querySelector("ul");
var li = document.createElement("li");
li.appendChild(document.createTextNode(Input.value));
ul.appendChild(li);
Input.value = "";我试图在代码中插入一个for循环,但之后它没有添加任何元素。
function NewEntry() {
var Inputfield = document.getElementById("Inputfield");
var AddButton = document.getElementById("AddButton");
var ul = document.querySelector("ul");
var li = document.createElement("li");
for (var i = 0; i < li.length; i++)
li[i].id = 'abc-' + i;
li.appendChild(document.createTextNode(Input.value));
ul.appendChild(li);
Input.value = "";发布于 2022-11-06 23:06:38
您的for循环需要花括号才能正常工作:
function NewEntry() {
var Inputfield = document.getElementById("Inputfield");
var AddButton = document.getElementById("AddButton");
var ul = document.querySelector("ul");
var li = document.createElement("li");
for (var i = 0; i < li.length; i++) {
abcElements[i].id = 'abc-' + i;
li.appendChild(document.createTextNode(Inputfield.value));
ul.appendChild(li);
}
Inputfield.value = "";
}否则,只有for语句之后的直接行将作为循环的一部分运行。
还出现了一个错误-你有Input而不是Inputfield?但是我注意到这里还使用了一些没有定义的其他变量,所以我假设省略了一些额外的代码?
发布于 2022-11-06 23:36:27
您可以计算<ul>中的元素数,并将其用作<li>的id。
var AddButton = document.getElementById("AddButton");
AddButton.addEventListener("click", NewEntry);
function NewEntry() {
var Inputfield = document.getElementById("Inputfield");
var ul = document.querySelector("ul");
var li = document.createElement("li");
li.id = ul.childElementCount;
li.appendChild(document.createTextNode(Inputfield.value));
ul.appendChild(li);
Inputfield.value = "";
console.log(li);
}<input type="text" id="Inputfield" />
<button id="AddButton">Add</button>
<ul></ul>
发布于 2022-11-07 10:50:44
实现这一目标的一个简单方法如下,并在JavaScript中作了解释性评论:
// a generator function, to generate a constantly increasing counter:
const generator = function*() {
// the initial value of the counter:
let i = 0;
// this loop causes the generator to return a number infinitely
// though while the loop is infinite it yields one value and then
// pauses until the next call; this is one instance where an
// infinite loop is deliberate and not a problem:
while (true) {
// increments the value of i, and then returns it to the
// calling context:
yield ++i;
}
},
// assigning a reference to the generator:
counter = generator(),
// a simple Arrow function that takes two arguments:
// tag: String, the element-type to create, and
// props: an Object of element-properties and values to
// assign to the created element:
create = (tag, props) => Object.assign(document.createElement(tag), props),
// a reference to the various elements to which event-listeners are attached:
list = document.querySelector('#list'),
form = document.querySelector('form'),
input = document.querySelector('input'),
button = document.querySelector('#add'),
// the addNew function, written as an Arrow function:
addNew = () => {
// caching the source of the text:
const inputField = document.querySelector('input');
// here we take the value, trim it to remove leading and trailing
// white-space, and then retrieve its length; if there is a zero
// length (so either nothing was entered, or only whitespace) then
// we return here:
if (inputField.value.trim().length === 0) {
return false;
}
// otherwise we cache a reference to the element to which the
// created <li> element will be appended:
const ul = document.querySelector('#list'),
// we call the create() function, here creating an <li>
// element, and passing in an object of properties and
// values:
li = create('li', {
// we set the 'id' - using a template literal string - to
// the string of 'abc-' plus next-value of the counter:
id: `abc-${counter.next().value}`,
// and set the text-content of the element to the
// trimmed value of the <input>:
textContent: inputField.value.trim()
}),
// here we create a <button>,
deleteButton = create('button', {
// with its className set to 'delete':
className: 'delete',
// its text-content set to 'delete task':
textContent: 'delete task',
// and its type set to 'button' in order to
// prevent the <button> submitting the <form>:
type: 'button'
});
// we append the created <button> to the created <li>:
li.append(deleteButton);
// we append the <li> to the <ul>:
ul.append(li);
// and reset the value of the <input> to an empty string:
inputField.value = '';
};
// here we prevent form submission:
form.addEventListener('submit', (e) => e.preventDefault());
// here we bind an anonymous function as the event-handler of the
// 'keyup' event on the <input> element:
input.addEventListener('keyup', (evt) => {
// if the, or an, 'Enter' key is pressed (note that evt.keyCode is
// almost entirely deprecated now, but is here for backwards
// compatibility, it can and possibly should be removed):
if (evt.key === 'Enter' || evt.keyCode === 13) {
// here we call the addNew() function:
addNew();
}
});
// we bind the addNew() function - note the deliberate lack of
// parentheses - as the event-handler for the 'click' event:
button.addEventListener('click', addNew);
// because we're adding the delete <button> elements we delegate the
// event-handling to the closest ancestor element present in the DOM
// on page-load, here that's the #list element. Here we bind the
// anonymous function as the event-handler for the 'click' event
// which bubbles to the <ul>:
list.addEventListener('click', (evt) => {
// if the element on which the click event fired has an ancestor
// .delete element (therefore it was fired on, or in, the .delete
// <button>):
if (evt.target.closest('.delete')) {
// we navigate from the event-target to the closest <li>
// ancestor element and use Element.remove() to remove that
// element from the document:
evt.target.closest('li').remove();
}
})*,
::before,
::after {
box-sizing: border-box;
font-family: system-ui;
font-size: 16px;
margin: 0;
padding: 0;
}
main {
inline-size: clamp(15em, 80vw, 1000px);
margin-inline: auto;
}
h2 {
font-size: 1.4em;
text-align: center;
}
fieldset {
display: grid;
padding: 0.5em;
}
legend {
border-inline: 1px solid currentColor;
border-radius: 0.25em;
margin-inline: 1em;
padding-inline: 0.5em;
}
label {
display: flex;
gap: 1em;
justify-content: space-between;
margin-block: 0.5em;
}
label input[type=text] {
flex-grow: 1;
}
#list {
border: 1px solid currentColor;
display: grid;
gap: 0.5em;
list-style-type: none;
margin-block: 1em;
margin-inline: auto;
padding: 0.5em;
}
#list:empty::before {
color: hsl(0deg 30% 30% / 0.8);
content: "A beautiful, quiet day of reflection...";
font-style: italic;
}
#list li {
background-color: lavender;
display: grid;
padding: 0.25em;
}
#list li:nth-child(odd) {
background-color: lightcyan;
}
li[id]::before {
content: "#" attr(id) ": ";
}
.delete {
justify-self: end;
}<main>
<section>
<h2>To do list</h2>
<form action="#" method="post">
<fieldset>
<legend>New task</legend>
<label>
<span class="labelText">What do you want to do today?</span>
<input type="text">
</label>
<button id="add" type="button">Add task to list</button>
</fieldset>
</form>
<ul id="list"></ul>
</section>
</main>
值得注意的是,使用生成器函数为id属性生成计数器存在一个潜在问题;计数器只会增加,因此,如果您有三个元素abc-1、abc-2、abc-3,然后删除这些元素,然后创建另外三个元素,这些元素将继续从abc-4中继续。因此,id将独立于创建的元素的数量。这可能是一个好处,因为复制的值无法创建,因此生成器创建复制id的可能性很小。
参考文献:
https://stackoverflow.com/questions/74340355
复制相似问题