Если у вас есть такая функция, как:
int foo()
{
// more stuff
foo();
}
Затем foo () будет продолжать называть себя, все глубже и глубже, и когда пространство, используемое для отслеживания того, какие функции вы используете, заполненный, вы получаете ошибку переполнения стека.
document.querySelector()
находит только первое совпадение.
Вместо этого попробуйте использовать: document.querySelector('.studentGrades:last-child')
.
Проблема в том, что эта строка возвращает первый элемент:
let removeDay = document.querySelector('.studentGrades');
Вы можете получить последний элемент с помощью:
let removeDay = document.querySelector('.studentGrades:last-child');
Однако нет необходимости звонить document.querySelector
столько раз. Вместо этого вы можете напрямую обращаться к последнему элементу контейнера с помощью Node.lastChild
:
const container = document.getElementById('container');
const add = document.getElementById('add');
const remove = document.getElementById('remove');
let index = -1;
add.onclick = () => {
// Add 10 new elements at the end:
const newLastIndex = index + 10;
while (index < newLastIndex) {
let div = document.createElement('div');
div.className = 'studentGrades';
div.innerHTML = ++index;
container.appendChild(div);
}
remove.disabled = false;
};
remove.onclick = () => {
// Remove last 10 elements:
for (let i = 0; i < 10; ++i) {
container.removeChild(container.lastChild);
// This will not work in IE:
// container.lastChild.remove();
}
index -= 10;
if (index === -1) {
remove.disabled = true;
}
};
body,
button {
font-family: monospace;
}
#container {
position: relative;
border: 3px solid black;
border-right: none;
margin-bottom: 10px;
}
#container:empty {
border-top: none;
}
.studentGrades {
position: relative;
border-right: 3px solid black;
width: 10%;
box-sizing: border-box;
display: inline-block;
text-align: right;
padding: 5px;
}
<div id="container"></div>
<button id="add">ADD</button>
<button id="remove" disabled>REMOVE</button>
Если вам не нужно поддерживать IE, вместо использования Node.removeChild()
:
container.removeChild(container.lastChild);
Вы можете использовать ChildNode.remove()
и выполните:
container.lastChild.remove();
Вы могли бы создать Stack, например:
function Stack() {
let items = [];
let maxIndex = -1;
this.isEmpty = () => {
return maxIndex === -1;
};
this.push = (item) => {
(items.length > ++maxIndex) ? (items[maxIndex] = item) : items.push(item);
};
this.pop = () => {
return (maxIndex >= 0) ? items[maxIndex--] : undefined;
};
this.top = () => {
return (maxIndex >= 0) ? items[maxIndex] : undefined;
}
}
, а затем нажимать элементы всякий раз, когда вы добавляете div
:
function addDay(S) {
// For loop to create 10 div elements.
for (k = 1; k < 11; k++) {
let div = document.createElement("div");
div.setAttribute("class", "studentGrades")
div.className += " sgID" + k
div.setAttribute("onclick", "userInput(this, Number(prompt('Please, enter
number here')))");
div.innerHTML = "0";
document.querySelector("#container3").appendChild(div);
S.push(div);
}}
и всплываете всякий раз, когда вы удаляете item, здесь мы просто удаляем все элементы из стека:
function removeDay(S) {
var itemToRemove;
while (itemToRemove = S.pop()) itemToRemove.remove();
}}
Естественно, где-то вам нужно будет создать стек каким-то образом, например:
let S = new Stack();
Может быть, так:
function addDay() {
for (k = 1; k < 11; k++) {
let div = document.createElement("div");
div.setAttribute("class", "studentGrades");
div.className += " sgID" + k;
div.setAttribute("onclick", "userInput(this, Number(prompt('Please, enter number here')))");
div.innerHTML = "0";
document.querySelector("#container3").appendChild(div)
}
}
function removeDay() {
for (let j = 0; j < 10; j++){
if(document.querySelectorAll(".studentGrades:last-child").length){
document.querySelectorAll(".studentGrades:last-child")[0].remove();
}
}
}
<div id="container3"></div>
<input type="button" value="add" onclick="addDay();">
<input type="button" value="remove" onclick="removeDay();">