弹出窗口不会关闭

时间:2018-03-13 15:36:11

标签: javascript

单击关闭按钮时弹出窗口不会关闭,我尝试使用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");

Popup

解决方案:

问题正在发生,因为:

  • 我正在使用+=将弹出窗口的内容附加到主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");

2 个答案:

答案 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。

这种限制有什么意义?
restriction