JS:第一次调用后的函数导致空错误
2020-12-10
63
我只是随便玩了一下,然后转到 CNN 文章并在控制台中运行了此代码。这个想法是能够单击
p
元素,它会将 DOM 节点替换为其中包含反向文本的节点。它按预期工作,但只能工作一次。当我尝试再次运行它以将其反转回来时,我在控制台中遇到错误,我不知道为什么:
TaggedEventTracker.js:56 Uncaught TypeError: Cannot read property 'dataset' of null
at e.findNearestZjsOrAElement (TaggedEventTracker.js:56)
at e.findNearestZjsOrAElement (TaggedEventTracker.js:63)
at e.trackTaggedEvent (TaggedEventTracker.js:73)
at HTMLDocument.<anonymous> (TaggedEventTracker.js:17)
代码:
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
let node = target;
let nodeText = target.innerHTML;
let newEl = document.createElement('p');
newEl.innerHTML = [...nodeText].reverse().join("");
node.parentNode.replaceChild(newEl, node);
}
2个回答
为什么要创建新节点来替换旧节点?您只需替换原始元素的 innerHTML 即可。
替换元素时,它们的事件跟踪器似乎已损坏。
此外,通过替换节点,您还可以替换与其关联的事件处理程序。
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
target.innerHTML = [...target.innerHTML].reverse().join("");
}
<p>`123456789</p>
<p>`123456789</p>
<p>`123456789</p>
如果您想保留原始功能并仍然替换文本,您将需要克隆节点并附加新的事件处理程序。
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
let node = target;
let nodeText = target.innerHTML;
let newEl = target.cloneNode();
newEl.innerHTML = [...nodeText].reverse().join("");
node.parentNode.replaceChild(newEl, node);
newEl.onclick = function(evt) {updateText(evt.target)}
}
<p>12233</p>
<p>x3332233</p>
imvain2
2020-12-10
如果您想在其中交换文本,这就是您所需要的。不要使用 innerHTML,而要使用 textContent。
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
let node = target;
node.textContent = [...target.textContent].reverse().join("");
}
Krystian Sitek
2020-12-10