当我点击关闭按钮时,弹出窗口不会关闭,我尝试使用 console.log 进行调试,看起来 closeButton.onclick
函数由于某种原因根本没有运行。
当从控制台手动运行 close() 函数时,一切正常。
class Popup {
constructor(content){
this.div = document.createElement("div");
this.div.className = "block";
//tried positioning popup into the center of the screen, doesn't work yet
this.div.style.position = "fixed";
this.div.style.margin = "auto auto";
//caption
this.caption = document.createElement("div");
this.caption.style.textAlign = "right";
//closeButton
this.closeButton = document.createElement("button");
this.closeButton.textContent = "X";
this.closeButton.onclick = this.close;
document.body.appendChild(this.div);
this.div.appendChild(this.caption);
this.caption.appendChild(this.closeButton);
this.div.innerHTML += content;
}
close(){
this.div.parentNode.removeChild(this.div);
delete this;
}
}
new Popup("close me");
这就是它的样子:
var popup = new Popup("hm hello");
解决方案:
出现这个问题是因为:
我使用
+=
将弹出窗口的内容直接附加到主 div 中。这使得 DOM 刷新和 onclick 触发器重置。this.closeButton.onclick = this.close;
这里onclick触发器会执行close函数,同时也会覆盖this
关键字,所以它包含一个按钮称为触发器,而不是 Popup 对象。我决定将 Popup 放入一个对 onclick 函数可见的变量中。现在一切正常。
class Popup {
constructor(content){
this.div = document.createElement("div");
this.div.className = "block";
this.div.style.position = "fixed";
this.div.style.margin = "auto auto";
//делоем капшон
this.caption = document.createElement("div");
this.caption.style.textAlign = "right";
//кнопка закрытия
this.closeButton = document.createElement("button");
this.closeButton.textContent = "X";
let popup = this;
this.closeButton.onclick = function(){popup.close()};
this.content = document.createElement("div");
this.content.innerHTML = content;
this.caption.appendChild(this.closeButton);
this.div.appendChild(this.caption);
this.div.appendChild(this.content);
document.body.appendChild(this.div);
}
close(){
this.div.parentNode.removeChild(this.div);
delete this;
}
}
new Popup("hello guys");
最佳答案
问题就在这里:
this.div.innerHTML += content;
当您为 .innerHTML
赋值时,整个先前的值将被新值覆盖。即使新值包含与先前值相同的 HTML 字符串,原始 HTML 中元素上的任何 DOM 事件绑定(bind)都将丢失。解决方案是不使用 .innerHTML
而是使用 .appendChild
。要在您的情况下完成此操作(这样您就不会丢失现有内容),您可以创建一个“虚拟”元素,您可以在其上使用 .innerHTML
,但是由于 .innerHTML
的性能问题,最好使用 DOM 对象的 .textContent
属性设置非 HTML 内容。
您在 close()
中也会遇到麻烦,无法找到正确的 parentNode
和要删除的节点,因此我已经对其进行了更新。
class Popup {
constructor(content){
this.div = document.createElement("div");
this.div.className = "block";
this.div.style.position = "fixed";
this.div.style.margin = "auto auto";
//caption
this.caption = document.createElement("div");
this.caption.style.textAlign = "right";
//closeButton
this.closeButton = document.createElement("button");
this.closeButton.textContent = "X";
this.closeButton.addEventListener("click", this.close);
this.caption.appendChild(this.closeButton);
this.div.appendChild(this.caption);
// Create a "dummy" wrapper that we can place content into
var dummy = document.createElement("div");
dummy.textContent = content;
// Then append the wrapper to the existing element (which won't kill
// any event bindings on DOM elements already present).
this.div.appendChild(dummy);
document.body.appendChild(this.div);
}
close() {
var currentPopup = document.querySelector(".block");
currentPopup.parentNode.removeChild(currentPopup);
delete this;
}
}
var popup = new Popup("hm hello");
关于javascript - 弹出窗口不会关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49260148/