#javascript #html
#javascript #HTML
Вопрос:
Я пытаюсь изучить javascript в веб-программировании. Начиная с простой веб-страницы регистрации школы: веб-страница позволяет динамически создавать любое количество оценок, нажав кнопку «Оценка «; под каждой оценкой любое количество учеников может быть создано нажатием кнопки «Студент «. Кнопка «Оценка » работает должным образом, однако нажатие кнопки «Студент » не отображает информацию об ученике, не уверен, что происходит. Любая помощь будет высоко оценена. Заранее спасибо.
Ссылочные коды:
<!DOCTYPE html>
<html>
<body>
<div>
<label>Registration</label>
<div class="form-inline justify-content-center" id="school" style="display:none">
<label for="fname">Grade:</label>
<input type="text" id="grade" name="Grade"><br><br>
<div id="students">
<div id="student">
<label for="fname">First:</label>
<input type="text" id="first" name="First"><br><br>
<label for="lname">Last:</label>
<input type="text" id="last" name="Last"><br><br>
</div>
<div class="text-center" id="add_student">
<span id="idStudentRootCopy">----S----</span>
<button type="button" onclick="addItem('student', 'idGradeRootCopy', false)">Student </button>
</div>
</div>
</div>
<div class="text-center" id="add_grade">
<span id="idGradeRootCopy">----G----</span>
<button type="button" onclick="addItem('school', 'idGradeRootCopy', true)">Grade </button>
</div>
</div>
<script>
var count = 0;
function addItem(id, index, root) {
var original = document.getElementById(id);
var before = document.getElementById(index);
var clone = original.cloneNode(true);
clone.style.display='block';
clone.id = id count;
var newFields = clone.childNodes;
for (var i = 0; i < newFields.length; i ) {
var fieldName = newFields[i].name;
if (fieldName)
newFields[i].name = fieldName count;
}
if (root) {
original.parentNode.insertBefore(clone, before.parentNode);
} else {
original.insertBefore(clone, before);
}
}
</script>
</body>
</html>
Комментарии:
1. Для чего нужен CSS
#student
?2. Вы должны разделить свой HTML, CSS и JavaScript. Поэтому используйте внешний CSS и JavaScript. У вас есть
root
аргумент, установленныйtrue
в вашем прослушивателе кнопки оценки.
Ответ №1:
Если вы откроете инструменты разработчика в своих браузерах и нажмете кнопку Student , вы получите сообщение об ошибке типа:
Неперехваченное DOMException: Node.insertBefore: дочерний элемент для вставки перед не является дочерним элементом этого узла
Итак, вы на самом деле пытаетесь поместить клонированный узел в неправильное место. В любом случае все немного запутанно. Допустим, вы нажали кнопку Grade три раза, и теперь вы решили нажать на Student первого клона — как он должен знать, куда поместить студента, поскольку существует три оценки?
Ну, конечно, есть исправление. Каждый ученик кнопка является дочерним элементом уникального клона школы <div>
, которому вы также присвоили уникальный идентификатор (school1, school2, …). Итак, если вы передадите addItem()
функции ссылку на кнопку, которую вы фактически нажали, мы можем получить ее родительский div, например:
clickedElement.parentNode.parentNode.parentNode
и добавьте клонированный узел, используя appendChild()
вместо insertBefore()
.
Вот пример (просто нажмите «Выполнить фрагмент кода»):
var count = 0;
function addItem(id, index, root, clickedElement) {
var original = document.getElementById(id);
var before = document.getElementById(index);
var clone = original.cloneNode(true);
clone.style.display = 'block';
clone.id = id count;
var newFields = clone.childNodes;
for (var i = 0; i < newFields.length; i ) {
var fieldName = newFields[i].name;
if (fieldName)
newFields[i].name = fieldName count;
}
if (root) {
original.parentNode.insertBefore(clone, before.parentNode);
} else {
clickedElement.parentNode.parentNode.parentNode.appendChild(clone);
}
}
<div>
<label>Registration</label>
<div class="form-inline justify-content-center" id="school" style="display:none">
<label for="fname">Grade:</label>
<input type="text" id="grade" name="Grade"><br><br>
<div id="students">
<div id="student">
<label for="fname">First:</label>
<input type="text" id="first" name="First"><br><br>
<label for="lname">Last:</label>
<input type="text" id="last" name="Last"><br><br>
</div>
<div class="text-center" id="add_student">
<span id="idStudentRootCopy">----S----</span>
<button type="button" onclick="addItem('student', 'idGradeRootCopy', false,this)">Student </button>
</div>
</div>
</div>
<div class="text-center" id="add_grade">
<span id="idGradeRootCopy">----G----</span>
<button type="button" onclick="addItem('school', 'idGradeRootCopy', true,this)">Grade </button>
</div>
</div>
Обновить
Если вы нажмете на кнопку Grade , она автоматически также «создаст» поле ввода для учащихся, поскольку его div является частью школьного div. Поэтому переместите его из школьного div и измените его режим отображения на none.
Если вы хотите, чтобы новое поле ввода student отображалось прямо перед кнопкой Student , нам действительно нужно использовать .insertBefore()
.
Вот измененный пример:
var count = 0;
function addItem(id, index, root, clickedElement) {
var original = document.getElementById(id);
var before = document.getElementById(index);
var clone = original.cloneNode(true);
clone.style.display = 'block';
clone.id = id count;
var newFields = clone.childNodes;
for (var i = 0; i < newFields.length; i ) {
var fieldName = newFields[i].name;
if (fieldName)
newFields[i].name = fieldName count;
}
if (root) {
original.parentNode.insertBefore(clone, before.parentNode);
} else {
clickedElement.parentNode.insertBefore(clone, clickedElement);
}
}
<div>
<label>Registration</label>
<div id="student" style="display:none">
<label for="fname">First:</label>
<input type="text" id="first" name="First"><br><br>
<label for="lname">Last:</label>
<input type="text" id="last" name="Last"><br><br>
</div>
<div class="form-inline justify-content-center" id="school" style="display:none">
<label for="fname">Grade:</label>
<input type="text" id="grade" name="Grade"><br><br>
<div id="students">
<div class="text-center" id="add_student">
<span id="idStudentRootCopy">----S----</span>
<button type="button" onclick="addItem('student', 'idStudentRootCopy', false,this)">Student </button>
</div>
</div>
</div>
<div class="text-center" id="add_grade">
<span id="idGradeRootCopy">----G----</span>
<button type="button" onclick="addItem('school', 'idGradeRootCopy', true,this)">Grade </button>
</div>
</div>
Комментарии:
1. Спасибо. Я немного не знаком с DOM. Моя первоначальная попытка была основана на следующей мысли: 1) оставьте раздел «Оценка» без какого-либо «Ученика» при его создании. 2) при нажатии кнопки «Student » будет создана новая информация об ученике, которая будет помещена прямо перед кнопкой «Student «, на которую нажимается. Не уверен, выполнимо ли это или как это сделать (если выполнимо). Но инструменты разработки могут быть очень полезны
2. Опечатка в моих исходных кодах, ‘idGradeRootCopy’ должна быть ‘idStudentRootCopy’: <div class=»text-center» id=»add_student»> <span id=»idStudentRootCopy»> —-S —-</span> <тип кнопки=»кнопка» onclick=»addItem(‘student’, ‘idGradeRootCopy’, false)»> Student </button> </div> Но это все равно не раб отает. Вероятно, мне нужно узнать больше 🙂
3. Теперь я понимаю, что вы имеете в виду. Я обновил свой ответ!
4. Спасибо, это именно то, чего я хочу достичь
5. Рад, что смог помочь NotFun! Кстати, если вы считаете, что это правильный ответ, пожалуйста, подумайте о том, чтобы принять его, используя кнопку «галочка».