javascript - 弹出窗口不会关闭

标签 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");

最佳答案

问题就在这里:

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/

相关文章:

javascript - Android JQuery focus() 解决方法

javascript - JS 源在 Chrome/Firefox 调试器中不可见,但在页面中正确加载

javascript - 在部分功能之后重新渲染

javascript - 在 Javascript 中获取 Devexpress Gridview 排序依据和排序顺序

javascript - 在所有浏览器中显示桌面通知

javascript - 拥有 CB 和 PayPal 的 Braintree 自定义表单

javascript - 如何创建一个javascript倒计时,刷新后继续计数

javascript - 获取浏览器中所有现有内置变量的完整列表

javascript - 具有动态 jQuery 选择器的循环事件处理程序

javascript - str.split() 随机失败?