我以前遇到过这个问题,基本上我想把我的应用程序的所有内容分开,即缓存dom,绑定事件,javascript中没有html等。
我有一个问题,在我的bindevents
方法中,我点击了删除按钮,但删除按钮仅在添加待办事项后才存在。
我遇到了错误:
未捕获的TypeError:无法读取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();
})();
答案 0 :(得分:0)
首先,您可能只是尝试在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);
});
答案 1 :(得分:0)
当你的事件处理函数被定义时,你应该bind()
你的事件处理函数,而不是当他们被设置为监听器时。
bindEvents: function() {
this.addToDo.addEventListener("click", this.add);
this.deleteToDo.addEventListener("click", this.delete);
},
add: function() {
// ...
}.bind(this),
delete: function() {
// ...
}.bind(this),
答案 2 :(得分:0)
我会从init过程中移除deletetodo缓存和事件赋值(无论如何总是为null)并在添加按钮时监听事件。