单击关闭按钮时弹出窗口不会关闭,我尝试使用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");
答案 0 :(得分:2)
问题在于:
this.div.innerHTML += content;
为.innerHTML
指定值时,将使用新值覆盖整个先前的值。即使新值包含与前一个值相同的HTML字符串,原始HTML中元素的任何DOM事件绑定也将丢失。解决方案是不使用.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");
答案 1 :(得分:0)
我终于找到了最终解决方案。 正如Scott Marcus在他的回答中提到的,我将在close函数中遇到麻烦,所以我决定将Popup对象放入一个可以关闭函数的变量中。没有应用课程,一切正常。虽然它可能看起来像一个糟糕的代码。
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")
P.S。