【问题标题】:Delete function gets called before button exists在按钮存在之前调用删除函数
【发布时间】:2017-08-05 18:57:05
【问题描述】:

我以前也遇到过这个问题,基本上我想将我的应用程序的所有内容分开,即缓存 dom、绑定事件、javascript 中没有 html 等。

我有一个问题,在我的 bindevents 方法中,我点击了删除按钮,但删除按钮仅在添加了待办事项后才存在。

我遇到了一个错误:

未捕获的类型错误:无法读取 null 的属性“addEventListener”

因为我想我在 dom 中搜索一个不存在的元素,我如何保持结构不变,但只在添加项目后在 DOM 中搜索删除按钮?

JS

(function() {
    var toDo = {
        data: [],
        cacheDom: function() {
            this.toDoApp = document.getElementById('to-do-app');
            this.toDoTemplate = document.getElementById('to-do-template');
            this.addToDo = document.getElementById('add-to-do');
            this.addToDoValue = document.getElementById('add-to-do-value');
            this.deleteToDo = document.querySelector('.to-do-delete');
        },
        load: function() {
            this.toDoTemplate = Handlebars.compile(this.toDoTemplate.innerHTML);
        },
        render: function() {
            this.toDoApp.innerHTML = this.toDoTemplate(this.data);
        },
        bindEvents: function() {
            this.addToDo.addEventListener("click", this.add.bind(this));
            this.deleteToDo.addEventListener("click", this.delete.bind(this));
        },
        add: function(e) {
            var toDoValue = this.addToDoValue.value;
            if(toDoValue) {
                var toDoObj = {
                    value: toDoValue,
                    id: Date.now()
                }
            this.data.push(toDoObj);
            }
            this.render();
        },
        delete: function() {
            console.log("delete!");
        },
        init: function() {
            this.cacheDom();
            this.bindEvents();
            this.load();
            this.render();
        }
    }

    toDo.init();
})();

【问题讨论】:

  • 你可以把按钮放进去,然后把它隐藏起来。

标签: javascript


【解决方案1】:

您应该在定义事件处理函数时将其bind()ing 到它们的范围内,而不是在将它们设置为侦听器时。

bindEvents: function() {
    this.addToDo.addEventListener("click", this.add);
    this.deleteToDo.addEventListener("click", this.delete);
},
add: function() {
    // ...
}.bind(this),
delete: function() {
    // ...
}.bind(this),

【讨论】:

  • 感谢您的建议,但似乎无法解决我的问题。
【解决方案2】:

一开始你可以尝试在onload之后获取Elements:

window.addEventListener("DOMContentLoaded",toDo.init.bind(toDo));

您可以在窗口中监听所有点击,然后过滤它们:

window.addEventListener("click",function(evt){
 var el = evt.target;
 do {
   if(el.classList.contains("someclass")){
     somefunc.call(el);
    }
 } while ( el = el.parentElement);
});

【讨论】:

    【解决方案3】:

    我会从 init 过程中删除 deletetodo 缓存和事件分配(无论如何它总是为 null),并在添加按钮时监听事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 2016-12-31
      • 1970-01-01
      • 1970-01-01
      • 2021-09-12
      • 2016-02-09
      • 1970-01-01
      相关资源
      最近更新 更多