需要2次点击才能工作的按钮。 -香草JavaScript

时间:2018-10-14 06:46:04

标签: javascript

我的代码在下面的jsfiddle代码段中。每当我按下“删除”按钮时,都需要2次单击才能删除最初用html生成的框。如果我添加了它们,则这些框一键即可正常工作。问题在于这些通过标记制作的盒子。

链接到代码:this

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .box-container {
                display: flex;
            }

            .box-item {
                display: inline-block;
                height: 30px;
                width: 30px;
                background: orangered;
                margin: 0 10px;
            }

            .activated {
                background: dodgerblue;
            }

        </style>
    </head>

    <body>
        <div id="box-container">
            <span class="1 box-item"></span>
            <span class="2 box-item"></span>
            <span class="3 box-item"></span>
        </div>

        <button id="add">Add</button>
        <button id="remove">Remove</button>

        <script src="main.js"></script>
    </body>

</html>

JS代码

const boxContainer = document.getElementById("box-container");
const boxItems = document.getElementsByClassName("box-item");
const addBtn = document.getElementById("add");
const removeBtn = document.getElementById("remove");

function Box(element) {
    this.__el = element;
    this.activated = true;
}

Box.prototype.init = function() {
    this.activateBox();
    this.__el.addEventListener("click", this.toggleActivation.bind(this));
};

Box.prototype.logger = function() {
    console.log(this);
};

Box.prototype.activateBox = function() {
    if (this.activated) {
        this.__el.classList.add("activated");
    }
};

Box.prototype.deactivateBox = function() {
    if (!this.activated) {
        this.__el.classList.remove("activated");
    }
};

Box.prototype.toggleActivation = function() {
    this.__el.classList.toggle("activated");
    return (this.activated = !this.activated);
};

let box = [];

for (let i = 0; i < boxItems.length; i++) {
    box[i] = new Box(boxItems[i]);
    box[i].init();
}

const addBox = function() {
    const node = document.createElement("span");
    node.classList.add("box-item", "activated");
    boxContainer.appendChild(node);
};

function removeBox() {
    boxContainer.removeChild(boxContainer.lastChild);
}

addBtn.addEventListener("click", addBox);
removeBtn.addEventListener("click", removeBox);

PS:我检查了其他两个标题相同的问题,但它们不能解决我的问题。

1 个答案:

答案 0 :(得分:3)

问题是您的HTML在.box-item之间包含文本节点

    <div id="box-container">
        <span class="1 box-item"></span>
        <span class="2 box-item"></span>
        <span class="3 box-item"></span>
    </div>

所以,当您致电

boxContainer.removeChild(boxContainer.lastChild);

如果父级的最后一个子节点是文本节点,则在使用lastChild时将选择该文本节点。那不是您想要的-您不想选择文本节点。您只想删除<span>元素,因此您可以删除.children中的最后一项:

const { children } = boxContainer;
boxContainer.removeChild(children[children.length - 1]);

或者,更优雅地,选择lastElementChild属性,这要感谢Andre的评论:

boxContainer.removeChild(boxContainer.lastElementChild);

(令人困惑的是,children的最终索引与lastChild返回的节点不是相同)

const boxContainer = document.getElementById("box-container");
const boxItems = document.getElementsByClassName("box-item");
const addBtn = document.getElementById("add");
const removeBtn = document.getElementById("remove");

function Box(element) {
  this.__el = element;
  this.activated = true;
}

Box.prototype.init = function() {
  this.activateBox();
  this.__el.addEventListener("click", this.toggleActivation.bind(this));
};

Box.prototype.logger = function() {
  console.log(this);
};

Box.prototype.activateBox = function() {
  if (this.activated) {
    this.__el.classList.add("activated");
  }
};

Box.prototype.deactivateBox = function() {
  if (!this.activated) {
    this.__el.classList.remove("activated");
  }
};

Box.prototype.toggleActivation = function() {
  this.__el.classList.toggle("activated");
  return (this.activated = !this.activated);
};

let box = [];

for (let i = 0; i < boxItems.length; i++) {
  box[i] = new Box(boxItems[i]);
  box[i].init();
}

const addBox = function() {
  const node = document.createElement("span");
  node.classList.add("box-item", "activated");
  boxContainer.appendChild(node);
};

function removeBox() {
  boxContainer.removeChild(boxContainer.lastElementChild);
}

addBtn.addEventListener("click", addBox);
removeBtn.addEventListener("click", removeBox);
.box-container {
  display: flex;
}

.box-item {
  display: inline-block;
  height: 30px;
  width: 30px;
  background: orangered;
  margin: 0 10px;
}

.activated {
  background: dodgerblue;
}
<div id="box-container">
  <span class="1 box-item"></span>
  <span class="2 box-item"></span>
  <span class="3 box-item"></span>
</div>

<button id="add">Add</button>
<button id="remove">Remove</button>

或者,您可以更改HTML以使没有文本节点:

<div id="box-container"><span class="1 box-item"></span><span class="2 box-item"></span><span class="3 box-item"></span></div>

const boxContainer = document.getElementById("box-container");
const boxItems = document.getElementsByClassName("box-item");
const addBtn = document.getElementById("add");
const removeBtn = document.getElementById("remove");

function Box(element) {
  this.__el = element;
  this.activated = true;
}

Box.prototype.init = function() {
  this.activateBox();
  this.__el.addEventListener("click", this.toggleActivation.bind(this));
};

Box.prototype.logger = function() {
  console.log(this);
};

Box.prototype.activateBox = function() {
  if (this.activated) {
    this.__el.classList.add("activated");
  }
};

Box.prototype.deactivateBox = function() {
  if (!this.activated) {
    this.__el.classList.remove("activated");
  }
};

Box.prototype.toggleActivation = function() {
  this.__el.classList.toggle("activated");
  return (this.activated = !this.activated);
};

let box = [];

for (let i = 0; i < boxItems.length; i++) {
  box[i] = new Box(boxItems[i]);
  box[i].init();
}

const addBox = function() {
  const node = document.createElement("span");
  node.classList.add("box-item", "activated");
  boxContainer.appendChild(node);
};

function removeBox() {
  boxContainer.removeChild(boxContainer.lastChild);
}

addBtn.addEventListener("click", addBox);
removeBtn.addEventListener("click", removeBox);
.box-container {
  display: flex;
}

.box-item {
  display: inline-block;
  height: 30px;
  width: 30px;
  background: orangered;
  margin: 0 10px;
}

.activated {
  background: dodgerblue;
}
<div id="box-container"><span class="1 box-item"></span><span class="2 box-item"></span><span class="3 box-item"></span></div>

<button id="add">Add</button>
<button id="remove">Remove</button>