我有这个基本的代码来处理所有文本节点:
function walk (node) {
if (node.nodeType == '3') {
handleText (node)
}
node = node.firstChild
while (node) {
walk (node)
node = node.nextSibling
}
}
不幸的是,这种处理所有文本节点,包括诸如<script>
和<style>
,我不想要的。我更新了我的代码以下忽略这些具体内容:
function walk (node) {
if (node.nodeType == '3' && node.tagName != 'SCRIPT' && node.tagName != 'STYLE') {
handleText (node)
}
node = node.firstChild
while (node) {
walk (node)
node = node.nextSibling
}
}
但是,这是行不通的。我究竟做错了什么?
与node
的nodeType
一个3
将是一个文本节点。由于这听起来像你想排除这是script
或style
标签的孩子文本节点的遍历,你应该把测试别处 - 如果walk(node)
不tagName
OR SCRIPT
,让家长STYLE
/ <script>
标签不迭代只<style>
在摆在首位:
function walk (node) {
if (node.nodeType === 3) {
handleText (node);
}
node = node.firstChild;
while (node) {
const { tagName } = node;
if (tagName !== 'SCRIPT' && tagName !== 'STYLE') {
walk (node);
}
node = node.nextSibling;
}
}
(也注意到,nodeType
计算结果为整数,所以你可以使用严格相等比较===
代替)
为了避免while
循环和重新分配,你可以考虑使用forEach
代替:
function walk (node) {
if (node.nodeType === 3) {
handleText (node);
return;
}
Array.prototype.forEach.call(
node.childNodes,
(childNode) => {
const { tagName } = childNode;
if (tagName !== 'SCRIPT' && tagName !== 'STYLE') {
walk (child);
}
}
);
}
标签检查应在父节点上:
function walk(node) {
if (node.nodeType == 3 && !/SCRIPT|STYLE/.test(node.parentNode.tagName)) handleText(node);
for (node = node.firstChild; node; node = node.nextSibling) walk(node)
}