我试图让它在用户创建一个小部件,然后重新加载页面时(它会出现,因为它保存在 localStorage 中),然后一旦您创建另一个小部件,我希望能够删除该小部件页面刷新之前的旧小部件,但它会删除用户单击的小部件和新小部件。
每次创建新的小部件时,都会为其分配一个属性名称“id”,并且该值是根据 localStorage 中已有的内容确定的,并找到下一个可用(或未使用)的 id 号。在将 widgets 数组设置回 localStorage 之前,它也会按照从最小 id 到最大 id 的顺序进行排序。
我尝试在创建小部件和加载文档时为小部件上的删除按钮附加一个单击监听器。但这不起作用。
现在我想我必须调用一个以 id 作为参数的函数,以便在创建新的小部件时向附加到文档的所有小部件添加点击监听器。
app.js:
function addRemoveListener(id) {
let storageUi = localStorage.getItem('ui');
let localUi = JSON.parse(storageUi);
$(`#widget-${id} > span > .widget-clear`).click(() => {
for (let i = 0; i < localUi.widgets.length; i++) {
let thisWidget = `#widget-${id}`;
if (localUi.widgets[i].id == id) {
localUi.widgets.splice(i, 1)
}
$(thisWidget).remove();
console.log(localUi)
}
let newUi = JSON.stringify(localUi);
localStorage.setItem('ui', newUi);
})
}
widget.js:
static appendToDom(ui) {
let storageUi = localStorage.getItem('ui');
let localUi = JSON.parse(storageUi);
for (let i = 0; i < localUi.widgets.length; i++) {
let widget = localUi.widgets[i];
let query = () => {
if (widget.type == 'humidity') {
return `${Math.floor(ui.weather.currently.humidity * 100)}`
} else if (widget.type == 'eye') {
return `${Math.floor(ui.weather.currently.visibility)}`
} else if (widget.type == 'windsock') {
return `${Math.floor(ui.weather.currently.windSpeed)}`
} else if (widget.type == 'pressure') {
return `${Math.floor(ui.weather.currently.pressure)}`
} else if (widget.type == 'uv-index') {
return `${ui.weather.currently.uvIndex}`
}
}
$('nav').after(`<div class="widget widget-${widget.size}" id="widget-${widget.id}">
<span>
<i class="material-icons widget-clear">clear</i>
<i class="material-icons widget-lock-open">lock_open</i>
<i class="material-icons widget-lock">lock_outline</i>
</span>
<div class="data-container">
<img src=${widget.image}>
<h1> ${widget.type}: ${query()} ${widget.unit} </h1>
</div>
</div>`)
$(`#widget-${widget.id}`).delay(1000 * i).animate({ opacity: 1 }, 1000);
$(`#widget-${widget.id}`).css({ left: `${widget.left}`, top: `${widget.top}`, 'font-size': `${widget.dimensions[2]}` })
$(`.widget`).draggable();
$(`#widget-${widget.id}`).css({ width: `${widget.dimensions[0]}`, height: `${widget.dimensions[1]}` })
addRemoveListener(i);
}
// this function is called earlier in the script when the user has selected
// which kind of widget they want
let makeWidget = () => {
let newWidget = new Widget(this.size, this.id, this.image, this.type, this.unit, this.dimensions);
saveWidget(newWidget);
addRemoveListener(this.id)
}
我对此没有任何问题,直到我在创建新窗口小部件后和刷新之前删除现有窗口小部件。
最佳答案
传递给 addRemoveListener 函数的 id 可能有问题。它可能会为任何小部件传递相同的 id,因此循环将删除 UI,因为 thisWidget
位于 for 循环中。尝试添加一些控制台日志记录。
function addRemoveListener(id) {
let storageUi = localStorage.getItem('ui');
let localUi = JSON.parse(storageUi);
$(`#widget-${id} > span > .widget-clear`).click(() => {
for (let i = 0; i < localUi.widgets.length; i++) {
let thisWidget = `#widget-${id}`;
if (localUi.widgets[i].id == id) {
localUi.widgets.splice(i, 1)
}
// Move this inside the if statement above.
$(thisWidget).remove();
console.log(localUi)
}
let newUi = JSON.stringify(localUi);
localStorage.setItem('ui', newUi);
})
}
或者更好的是,如果 id 不匹配,则重写它以继续
function addRemoveListener(id) {
let storageUi = localStorage.getItem('ui');
let localUi = JSON.parse(storageUi);
$(`#widget-${id} > span > .widget-clear`).click(() => {
for (let i = 0; i < localUi.widgets.length; i++) {
let thisWidget = `#widget-${id}`;
if (localUi.widgets[i].id !== id) {
continue;
}
localUi.widgets.splice(i, 1)
$(thisWidget).remove();
console.log(localUi)
}
let newUi = JSON.stringify(localUi);
localStorage.setItem('ui', newUi);
})
}
关于javascript - 创建新元素时仅拼接一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57650604/