如何使用 Javascript 动态生成输入字段,然后使用它们的值?
How can I dynamically generate input fields with Javascript and then use their values?
我希望能够在提交时找到 courseAmount
输入字段的数字值,然后生成新的输入字段(进入 [=5= 下面的 hourForm
表单]) 通过 javascript 中的 onsubmit
方法,然后在提交 hourForm
表单时从每个生成的输入字段中检索值,并将这些值放入数组中。
但是,我在使用 javascript 实际生成输入字段时遇到了困难,我怀疑我在检索 courseAmount
输入的值并将其移植到我的 [=9] 时遇到了困难=] 函数,但我不确定这是否是问题所在。
这是我的 HTML:
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<form id="initialForm" method="post" onsubmit="createInput()" action="">
<label>Number of hours for which you would like to study</label>
<input type="number" name="overallHours" id="overallHours" class="stored" min="1" max="20" step="1" value="1"/>
<label>Number of courses you would like to study for</label>
<input type="number" name="courseAmount" id="courseAmount" class="stored" min="1" max="20" step="1" value="1"/>
<input type="submit" class="submitStudy" value="Submit"/>
</form>
<form id="hourForm" method="post" onsubmit="calcHours">
<label>State the desired time spent working in each course</label>
</form>
</body>
这是我的 Javascript:
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var counter = 0;
function createInput() {
var newForm = document.getElementById("hourForm");
document.getElementById("initialForm").style.display = "none";
document.getElementById("hourForm").style.display = "block";
for (i = 0; i <= courseNumberTotal; i++) {
newForm.innerHTML = "<label>Course #" + (counter + 1) + "</label>" + "<input type='number' name='courseHours' class='newInputs' min='1' max='9' step='1' value='1'/>";
counter++;
}
newForm.innerHTML = "<input type='submit' value='submit'/>";
}
谁能帮我解决这个问题 Javascript?我的 JSFiddle 尝试是徒劳的,因为 JSFiddle 不善待表单重新加载页面。
谢谢!
当调用 createInput()
函数时,您没有得到想要的结果,因为您在循环的每次迭代中重置 newForm.innerHTML
,然后在结束时再次重置。而不是使用 =
你应该使用 +=
来附加所需的文本而不是替换现有的文本。
// Replacing the contents of newForm.innerHTML
newForm.innerHTML = "foo";
// Appending to newForm.innderHTML (You want to do this)
newForm.innerHTML += "foo";
另一个问题是,当您按下提交时,页面会在 createInput()
能够获得所需结果之前重新加载。您很可能希望停止页面实际提交,从而在您按下提交按钮时重新加载。为此,您可以将表单的 onsubmit
属性更改为 "return createInput()"
,然后将行 return false;
添加到 createInput()
函数的末尾,以向浏览器表明您不想提交表格。
来自关于内部的 mdn 页面HTML:"Removes all of element's children, parses the content string and assigns the resulting nodes as children of the element." https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
一般来说您根本不想使用 innerHTML。几乎总有更好的方法。在这种情况下,这将是 createElement 和 appendChild。
此外,没有"onsubmit"这样的方法。你这样调用的是一个 HTML 属性,它为 submit 事件注册了一个处理程序。 http://www.quirksmode.org/js/introevents.html
但是使用 html 属性有其严重的缺点:http://www.quirksmode.org/js/events_advanced.html
考虑到所有这些,我会这样做:http://jsfiddle.net/ashnur/rwod4z1d/
HTML:
<form id="initialForm" method="post" action="">
<label>Number of hours for which you would like to study</label>
<input type="number" name="overallHours" id="overallHours" class="stored" min="1" max="20" step="1" value="1" /><hr>
<label>Number of courses you would like to study for</label>
<input type="number" name="courseAmount" id="courseAmount" class="stored" min="1" max="20" step="1" value="1" /><hr>
<input type="submit" class="submitStudy" value="Submit" />
</form>
<form id="hourForm" method="post" >
<label>State the desired time spent working in each course</label><hr>
</form>
js:
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var counter = 0;
var initialForm = document.getElementById("initialForm");
var hourForm = document.getElementById("hourForm");
initialForm.addEventListener('submit', createInput);
hourForm.addEventListener('submit', calcHours);
function calcHours() {}
function createInput(ev) {
ev.preventDefault(); // this is not needed if you are using a bare button and the click event
var newForm = document.getElementById("hourForm");
initialForm.style.display = "none";
hourForm.style.display = "block";
for (i = 0; i <= courseNumberTotal; i++) {
addControl(newForm, "Course #" + (counter + 1));
counter++;
}
var submit = document.createElement('input');
submit.type = 'submit';
submit.value = 'submit';
newForm.appendChild(submit);
}
function addControl(form, labelText) {
var label = document.createElement('label');
var input = document.createElement('input');
var hr = document.createElement('hr');
input.type = 'number';
input.name = 'courseHours';
input.classname = 'newInputs';
input.min = '1';
input.max = '9';
input.step = '1';
input.value = '1';
label.textContent = labelText;
form.appendChild(label);
form.appendChild(input);
form.appendChild(hr);
}
正如 Tobias 正确指出的那样,允许您的表单提交事件继续,这会导致页面刷新和 "reset" 所有纯 JavaScript 数据。此外,您不是在提交表单时(在用户输入金额之后)捕获您的值(notedOverallHours
和 courseNumberTotal
),而是在您的页面初始化时(before 用户输入了任何内容)。
所以,要解决这个问题,首先要对您的 HTML:
进行微小的修改
...
<form id="initialForm" method="post" action="">
...
请注意,我从您的表单中删除了 onsubmit
属性。我们可以通过 JavaScript 本身的事件来捕获它。
接下来将一个事件侦听器附加到您的表单以阻止它提交并调用您的 createInput()
函数:
document.getElementById("initialForm").addEventListener('submit', function (e) {
e.preventDefault();
createInput();
});
这将附加一个 eventListener
来侦听 initialForm
元素上的 submit
事件。第一个参数是您要监听的事件类型(在本例中为 submit
),第二个参数是您要触发的回调。
回调函数总是获取传入的事件(e
参数)。通过在此事件上调用 preventDefault
,我们可以阻止它冒泡并实际导致页面刷新。
接下来我们调用 createInput()
函数,经过一些修改后,它看起来像这样:
function createInput() {
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var newForm = document.getElementById("hourForm");
document.getElementById("initialForm").style.display = "none";
document.getElementById("hourForm").style.display = "block";
// Add our elements
for (i = 1; i <= courseNumberTotal; i++) {
var child = document.createElement('li');
child.innerHTML = "<label>Course #" + (i) + "</label>" + "<input type='number' name='courseHours-"+ i+"' class='newInputs' min='1' max='9' step='1' value='1'/>";
newForm.appendChild(child);
}
// Add our button
var button = document.createElement('li');
button.innerHTML = "<input type='submit' value='submit'/>";
newForm.appendChild(button);
}
如您所见,我在 createInput()
函数中捕获了 notedOverallHours
和 courseNumberTotal
变量,因此它们将携带 在 [=] 期间设置的任何值69=]表单提交事件。
然后我们遍历每个课程编号。我们没有替换 innerHTML
,而是首先创建一个元素(在我们的例子中是 li
)并用 HTML
字符串填充该元素。接下来我们将此 child 元素附加到 parent 表单。
在循环内我删除了 counter
变量,因为您可以在循环内简单地使用 i
的值,无需创建额外的变量。我还为每个 child 附加了 name
属性 i
,这样就不会出现任何名称冲突。
在函数的末尾,我们只需创建并附加一个包含提交按钮的新 li
元素。
您可以通过使用 createElement
函数实际创建 label
和 input
元素并使用 [=75] 单独设置其属性和 text
来进一步优化=] 设置器,而不是像我在这里所做的那样将所有内容都倾倒在 li
元素中,以使事情暂时变得更简单。我会把它留作练习 :)
我用这个确切的代码创建了一个粗略的 JSFiddle here。
我希望能够在提交时找到 courseAmount
输入字段的数字值,然后生成新的输入字段(进入 [=5= 下面的 hourForm
表单]) 通过 javascript 中的 onsubmit
方法,然后在提交 hourForm
表单时从每个生成的输入字段中检索值,并将这些值放入数组中。
但是,我在使用 javascript 实际生成输入字段时遇到了困难,我怀疑我在检索 courseAmount
输入的值并将其移植到我的 [=9] 时遇到了困难=] 函数,但我不确定这是否是问题所在。
这是我的 HTML:
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<form id="initialForm" method="post" onsubmit="createInput()" action="">
<label>Number of hours for which you would like to study</label>
<input type="number" name="overallHours" id="overallHours" class="stored" min="1" max="20" step="1" value="1"/>
<label>Number of courses you would like to study for</label>
<input type="number" name="courseAmount" id="courseAmount" class="stored" min="1" max="20" step="1" value="1"/>
<input type="submit" class="submitStudy" value="Submit"/>
</form>
<form id="hourForm" method="post" onsubmit="calcHours">
<label>State the desired time spent working in each course</label>
</form>
</body>
这是我的 Javascript:
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var counter = 0;
function createInput() {
var newForm = document.getElementById("hourForm");
document.getElementById("initialForm").style.display = "none";
document.getElementById("hourForm").style.display = "block";
for (i = 0; i <= courseNumberTotal; i++) {
newForm.innerHTML = "<label>Course #" + (counter + 1) + "</label>" + "<input type='number' name='courseHours' class='newInputs' min='1' max='9' step='1' value='1'/>";
counter++;
}
newForm.innerHTML = "<input type='submit' value='submit'/>";
}
谁能帮我解决这个问题 Javascript?我的 JSFiddle 尝试是徒劳的,因为 JSFiddle 不善待表单重新加载页面。
谢谢!
当调用 createInput()
函数时,您没有得到想要的结果,因为您在循环的每次迭代中重置 newForm.innerHTML
,然后在结束时再次重置。而不是使用 =
你应该使用 +=
来附加所需的文本而不是替换现有的文本。
// Replacing the contents of newForm.innerHTML
newForm.innerHTML = "foo";
// Appending to newForm.innderHTML (You want to do this)
newForm.innerHTML += "foo";
另一个问题是,当您按下提交时,页面会在 createInput()
能够获得所需结果之前重新加载。您很可能希望停止页面实际提交,从而在您按下提交按钮时重新加载。为此,您可以将表单的 onsubmit
属性更改为 "return createInput()"
,然后将行 return false;
添加到 createInput()
函数的末尾,以向浏览器表明您不想提交表格。
来自关于内部的 mdn 页面HTML:"Removes all of element's children, parses the content string and assigns the resulting nodes as children of the element." https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
一般来说您根本不想使用 innerHTML。几乎总有更好的方法。在这种情况下,这将是 createElement 和 appendChild。
此外,没有"onsubmit"这样的方法。你这样调用的是一个 HTML 属性,它为 submit 事件注册了一个处理程序。 http://www.quirksmode.org/js/introevents.html
但是使用 html 属性有其严重的缺点:http://www.quirksmode.org/js/events_advanced.html
考虑到所有这些,我会这样做:http://jsfiddle.net/ashnur/rwod4z1d/
HTML:
<form id="initialForm" method="post" action="">
<label>Number of hours for which you would like to study</label>
<input type="number" name="overallHours" id="overallHours" class="stored" min="1" max="20" step="1" value="1" /><hr>
<label>Number of courses you would like to study for</label>
<input type="number" name="courseAmount" id="courseAmount" class="stored" min="1" max="20" step="1" value="1" /><hr>
<input type="submit" class="submitStudy" value="Submit" />
</form>
<form id="hourForm" method="post" >
<label>State the desired time spent working in each course</label><hr>
</form>
js:
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var counter = 0;
var initialForm = document.getElementById("initialForm");
var hourForm = document.getElementById("hourForm");
initialForm.addEventListener('submit', createInput);
hourForm.addEventListener('submit', calcHours);
function calcHours() {}
function createInput(ev) {
ev.preventDefault(); // this is not needed if you are using a bare button and the click event
var newForm = document.getElementById("hourForm");
initialForm.style.display = "none";
hourForm.style.display = "block";
for (i = 0; i <= courseNumberTotal; i++) {
addControl(newForm, "Course #" + (counter + 1));
counter++;
}
var submit = document.createElement('input');
submit.type = 'submit';
submit.value = 'submit';
newForm.appendChild(submit);
}
function addControl(form, labelText) {
var label = document.createElement('label');
var input = document.createElement('input');
var hr = document.createElement('hr');
input.type = 'number';
input.name = 'courseHours';
input.classname = 'newInputs';
input.min = '1';
input.max = '9';
input.step = '1';
input.value = '1';
label.textContent = labelText;
form.appendChild(label);
form.appendChild(input);
form.appendChild(hr);
}
正如 Tobias 正确指出的那样,允许您的表单提交事件继续,这会导致页面刷新和 "reset" 所有纯 JavaScript 数据。此外,您不是在提交表单时(在用户输入金额之后)捕获您的值(notedOverallHours
和 courseNumberTotal
),而是在您的页面初始化时(before 用户输入了任何内容)。
所以,要解决这个问题,首先要对您的 HTML:
进行微小的修改...
<form id="initialForm" method="post" action="">
...
请注意,我从您的表单中删除了 onsubmit
属性。我们可以通过 JavaScript 本身的事件来捕获它。
接下来将一个事件侦听器附加到您的表单以阻止它提交并调用您的 createInput()
函数:
document.getElementById("initialForm").addEventListener('submit', function (e) {
e.preventDefault();
createInput();
});
这将附加一个 eventListener
来侦听 initialForm
元素上的 submit
事件。第一个参数是您要监听的事件类型(在本例中为 submit
),第二个参数是您要触发的回调。
回调函数总是获取传入的事件(e
参数)。通过在此事件上调用 preventDefault
,我们可以阻止它冒泡并实际导致页面刷新。
接下来我们调用 createInput()
函数,经过一些修改后,它看起来像这样:
function createInput() {
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var newForm = document.getElementById("hourForm");
document.getElementById("initialForm").style.display = "none";
document.getElementById("hourForm").style.display = "block";
// Add our elements
for (i = 1; i <= courseNumberTotal; i++) {
var child = document.createElement('li');
child.innerHTML = "<label>Course #" + (i) + "</label>" + "<input type='number' name='courseHours-"+ i+"' class='newInputs' min='1' max='9' step='1' value='1'/>";
newForm.appendChild(child);
}
// Add our button
var button = document.createElement('li');
button.innerHTML = "<input type='submit' value='submit'/>";
newForm.appendChild(button);
}
如您所见,我在 createInput()
函数中捕获了 notedOverallHours
和 courseNumberTotal
变量,因此它们将携带 在 [=] 期间设置的任何值69=]表单提交事件。
然后我们遍历每个课程编号。我们没有替换 innerHTML
,而是首先创建一个元素(在我们的例子中是 li
)并用 HTML
字符串填充该元素。接下来我们将此 child 元素附加到 parent 表单。
在循环内我删除了 counter
变量,因为您可以在循环内简单地使用 i
的值,无需创建额外的变量。我还为每个 child 附加了 name
属性 i
,这样就不会出现任何名称冲突。
在函数的末尾,我们只需创建并附加一个包含提交按钮的新 li
元素。
您可以通过使用 createElement
函数实际创建 label
和 input
元素并使用 [=75] 单独设置其属性和 text
来进一步优化=] 设置器,而不是像我在这里所做的那样将所有内容都倾倒在 li
元素中,以使事情暂时变得更简单。我会把它留作练习 :)
我用这个确切的代码创建了一个粗略的 JSFiddle here。