我正在使用javascript创建日历应用程序。日历视图是使用javascript(dom元素)显示的,为此我创建了一个通用方法,并调用了该方法来显示更新的日历视图。单击特定日期时,我需要更新日历的显示,但是当触发更新事件时,日历仅更新一次。我创建了一个类似的演示,并在下面提供了相同的演示。
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(document).ready(() => {
this.show();
for (let i = 0; i < 10; i++) {
$('#li-' + i).click(() => {
alert(i);
this.show();
});
}
});
function show() {
let elem = document.getElementById('body');
elem.innerHTML = "";
let ul = document.createElement('ul');
for (let i = 0; i < 10; i++) {
let li = document.createElement('li');
let text = document.createTextNode(i);
li.appendChild(text);
li.setAttribute('id', 'li-' + i);
li.style.cursor = 'pointer';
ul.appendChild(li);
elem.appendChild(ul);
}
}
</script>
</head>
<body>
<div id="body"></div>
</body>
</html>
在此示例中,当我单击“ li”元素时,将触发click事件并显示警告框。同样,调用“ show()”方法来更新视图。但是,单击另一个“ li”元素时,不会触发该事件。
答案 0 :(得分:3)
旁注:我一定会重构您的代码。
问题:this.show()
实际上是重绘 ID为body
的整个div。
重新绘制元素(并删除以前的现有元素)会取消注册点击事件,这些点击事件不会自动注册。在当前情况下,您在渲染事件后立即一次注册事件,但是在再次渲染div之后不再注册它们。
解决方案是通过移动for
函数内部的show
重新注册事件。
$(document).ready(() => {
this.show();
});
function show() {
let elem = document.getElementById('body');
elem.innerHTML = "";
let ul = document.createElement('ul');
for (let i = 0; i < 10; i++) {
let li = document.createElement('li');
let text = document.createTextNode(i);
li.appendChild(text);
li.setAttribute('id', 'li-' + i);
li.style.cursor = 'pointer';
ul.appendChild(li);
elem.appendChild(ul);
}
for (let i = 0; i < 10; i++) {
$('#li-' + i).click(() => {
alert(i);
this.show();
});
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="body">
</div>
答案 1 :(得分:1)
当您单击任何元素时,您再次调用show(),以便再次创建DOM并取消绑定 这样您就可以绑定到文档,即如果创建了新的DOM,它将自动被绑定
$(document).on("click", 'body #li-' + i, function(event){
alert(i);
this.show();
}.bind(this));