【发布时间】:2016-12-28 20:32:33
【问题描述】:
简介
假设我有一个包含 3 个项目的列表(这些项目是用户在单击 chrome 扩展弹出窗口内的按钮时添加的 URL,参见图片)。当我单击项目编号 3 的“X”按钮时,它只会删除该项目。之后,当我单击“X”第 2 项时,第二项被删除。最后,当单击第一项的“X”时,它也会被删除。一切都按预期工作。当我尝试相反时,就会出现问题。
问题
我们有相同的 3 个项目列表。现在,我决定先删除第 1 项,而不是先删除第 3 项。当我这样做时,所有 3 个项目都立即消失了。然后我再次重新加载了 3 个项目并尝试从删除第 2 项开始,这次只删除第 2 项和第 3 项,剩下第 1 项。这是一个奇怪的错误,因为似乎每当我单击“X”按钮时,连续的项目与我要删除的项目一起被删除。
在 Google 点击“X”之前:
点击“X”后,只剩下 Facebook:
调试器
所以我觉得这很奇怪,我试图用调试器解决这个问题。仅按 Google 的“X”按钮时收到以下错误(与上图相同):
然后我去了 popup.js 并查看了包含这些行的特定代码行:
// the specific URL to delete
list.removeChild(items[j]);
在代码部分,我更详细地发布了代码部分。我在谷歌上搜索了这个错误,发现了这个:removeChild。在这里,错误描述如下:
“如果子元素实际上是元素的子元素,因此存在于 DOM 中,但被移除了”。
现在这让我想知道,我再次凝视着我的代码,但据我所知,我没有删除谷歌之后的 URL,只删除了谷歌本身。我试图在纸上解决它,但不幸的是徒劳无功。我唯一能想到的是我应该从“addToDom”函数中删除“createButtonEvents”。但如果我这样做,我将无法再删除第 1 项(但我可以在不删除第 3 项的情况下删除第 2 项)。我认为这个问题比我最初想象的要复杂得多,所以我自己无法解决这个问题,这就是我在这里问这个问题的原因。现在是“代码”部分。
代码
任何想要查看完整代码(所有行和文件)的人,请前往此页面:GitHub
对于那些只关心发生这种情况的特定代码的人:
我的 popup.js 文件的一部分:
document.addEventListener('DOMContentLoaded', function() {
restore();
document.getElementById('add').addEventListener('click', fetchUrl);
document.getElementById('clear').addEventListener('click', clearAll);
});
function restore() {
// get the tab link and title
chrome.storage.local.get({urlList:[], titleList:[]}, function(data) {
urlList = data.urlList;
titleList = data.titleList;
// add the titles and url's to the DOM
var n = urlList.length;
for (var i = 0; i < n; i++) {
addToDom(urlList[i], titleList[i]);
}
// 'X' button handlers only when all URL's are in DOM
createButtonEvents();
});
}
function addToDom(url, title) {
// change the (greeting) text message
document.getElementById("div").innerHTML = "<h2 id='title'>Saved Pages</h2>";
// Build the new DOM elements programmatically
var newItem = document.createElement('li');
var newLink = document.createElement('a');
var thisButton = document.createElement('button');
newLink.textContent = title;
thisButton.textContent = 'X';
thisButton.setAttribute('class', 'buttons');
thisButton.setAttribute('tabindex', -1);
newItem.setAttribute('class', 'items');
newLink.setAttribute('href', url);
newLink.setAttribute('target', '_blank');
newLink.setAttribute('tabindex', -1);
newLink.setAttribute('id', 'item');
newItem.appendChild(thisButton);
newItem.appendChild(newLink);
document.getElementById('list').appendChild(newItem);
createButtonEvents();
}
function createButtonEvents() {
// create event listeners for all the 'X' buttons next to list items
// after the 'addToDom' function has been executed
var allButtons = document.getElementsByClassName('buttons');
for (var j = 0, k = allButtons.length; j < k; j++) {
listenJ(j);
}
function listenJ(j) {
allButtons[j].addEventListener('click', () => removeMe(j));
}
}
function removeMe(j) {
// remove it from the DOM
var items = document.getElementsByClassName('items');
var list = document.getElementById('list');
// the specific URL to delete
list.removeChild(items[j]);
// return the DOM to original state
if (items.length === 0) {
document.getElementById('list').innerHTML = '';
document.getElementById('div').innerHTML = '<h3>No content yet! Click "add link" to add the link of the current website!</h3>';
}
// remove it from chrome-storage
chrome.storage.local.get({urlList:[], titleList:[]}, function(data) {
urlList = data.urlList;
titleList = data.titleList;
urlList.splice(j, 1);
titleList.splice(j, 1);
// update chrome storage
saveList();
});
}
编辑
以防万一有人没有读过它,我将在这里再次在调试器部分重复这句话:
我唯一能想到的就是我应该从“addToDom”函数中删除“createButtonEvents”。但如果我这样做,我将无法再删除第 1 项(但我可以在不删除第 3 项的情况下删除第 2 项)。我认为这个问题比我最初想象的要复杂得多。
我知道“按钮类”上的多个事件处理程序可能同时工作,但我不知道如何以另一种方式格式化代码。
【问题讨论】:
标签: javascript google-chrome google-chrome-extension event-handling popupwindow