比较父节点和子节点的相似性
Comparing a parent and a child node for similarity
给定以下结构
<p>
<p>
<span>
<span class="a">
<p>
我想把它变成
<p>
<span>
<span class="a">
是的,第一个块无效,我们将忽略它。这只是一个例子。
基本上,我想做的是检查是否有任何子项是必需的,如果不需要,则将其删除,保留其所有子项。因此,所有 <p>
都是相同的直元素,因此只有最上面的元素真正在做任何事情(在我的代码中,我意识到情况并非总是如此)。然而,虽然名称相同,但跨度并不相同,因为一个有 class="a"
而另一个没有 class,因此它们都保持不变。
如果 class 名称不同,我正在寻找的内容的扩展将不仅有效,而且任何可能使其实际不同的属性都有效。
我在想我可以使用 node1.attributes === node2.attributes
,但这不起作用,即使 node1
和 node2
属性的长度为零。此外,node1 === node2
、node1.isEqualNode(node2)
和 node1.isSameNode(node2)
也都失败了。没错,因为它们不是同一个节点。
那么我怎样才能正确地检查节点是否符合移除条件?
另一个例子,什么时候这会真正有用
<p>
<b>
Some text
<u>that is
<b>bolded</b> <!-- << That <b> is totally useless, and should be removed. -->
</u>
</b>
</p>
否 Jquery 请。
哦,这将是一个有趣的面试问题!
关于解决方案-创建一个函数来遍历 DOM 任何你喜欢的方式,它接收一个谓词函数作为参数。然后收集一组通过谓词的项目,然后执行 'fixing' 。
在您的情况下,谓词显然是一些您需要实现的 isChildNecessary 函数。
您打算如何处理第二遍、第三遍等等?你什么时候停下来?删除一些节点后,您可能会得到另一个 'invalid' 状态。只是需要考虑一下。
这就是我最终得到的结果:
it = doc.createNodeIterator(doc.firstChild, NodeFilter.SHOW_ALL, null, false);
node = it.nextNode();
while(node){
// Remove any identical children
// Get the node we can move around. We need to go to the parent first, or everything will be true
var tempNode = node.parentNode;
// While we haven't hit the top - This checks for identical children
while(tempNode && tempNode !== div && tempNode !== doc){
// If they're the same name, which isn't not on the noDel list, and they have the same number of attributes
if(node.nodeName === tempNode.nodeName && noDel.indexOf(node.nodeName) < 0 && node.attributes.length === tempNode.attributes.length){
// Set flag that is used to determine if we want to remove or not
var remove = true;
// Loop through all the attributes
for(var i = 0; i < node.attributes.length; ++i){
// If we find a mismatch, make the flag false and leave
if(node.attributes[i] !== tempNode.attributes[i]){
remove = false;
break;
}
}
// If we want to remove it
if(remove){
// Create a new fragment
var frag = doc.createDocumentFragment();
// Place all of nodes children into the fragment
while(node.firstChild){
frag.appendChild(node.firstChild);
}
// Replace the node with the fragment
node.parentNode.replaceChild(frag, node);
}
}
// Otherwise, look at the next parent
tempNode = tempNode.parentNode;
}
// Next node
node = it.nextNode();
}
给定以下结构
<p>
<p>
<span>
<span class="a">
<p>
我想把它变成
<p>
<span>
<span class="a">
是的,第一个块无效,我们将忽略它。这只是一个例子。
基本上,我想做的是检查是否有任何子项是必需的,如果不需要,则将其删除,保留其所有子项。因此,所有 <p>
都是相同的直元素,因此只有最上面的元素真正在做任何事情(在我的代码中,我意识到情况并非总是如此)。然而,虽然名称相同,但跨度并不相同,因为一个有 class="a"
而另一个没有 class,因此它们都保持不变。
如果 class 名称不同,我正在寻找的内容的扩展将不仅有效,而且任何可能使其实际不同的属性都有效。
我在想我可以使用 node1.attributes === node2.attributes
,但这不起作用,即使 node1
和 node2
属性的长度为零。此外,node1 === node2
、node1.isEqualNode(node2)
和 node1.isSameNode(node2)
也都失败了。没错,因为它们不是同一个节点。
那么我怎样才能正确地检查节点是否符合移除条件?
另一个例子,什么时候这会真正有用
<p>
<b>
Some text
<u>that is
<b>bolded</b> <!-- << That <b> is totally useless, and should be removed. -->
</u>
</b>
</p>
否 Jquery 请。
哦,这将是一个有趣的面试问题! 关于解决方案-创建一个函数来遍历 DOM 任何你喜欢的方式,它接收一个谓词函数作为参数。然后收集一组通过谓词的项目,然后执行 'fixing' 。 在您的情况下,谓词显然是一些您需要实现的 isChildNecessary 函数。
您打算如何处理第二遍、第三遍等等?你什么时候停下来?删除一些节点后,您可能会得到另一个 'invalid' 状态。只是需要考虑一下。
这就是我最终得到的结果:
it = doc.createNodeIterator(doc.firstChild, NodeFilter.SHOW_ALL, null, false);
node = it.nextNode();
while(node){
// Remove any identical children
// Get the node we can move around. We need to go to the parent first, or everything will be true
var tempNode = node.parentNode;
// While we haven't hit the top - This checks for identical children
while(tempNode && tempNode !== div && tempNode !== doc){
// If they're the same name, which isn't not on the noDel list, and they have the same number of attributes
if(node.nodeName === tempNode.nodeName && noDel.indexOf(node.nodeName) < 0 && node.attributes.length === tempNode.attributes.length){
// Set flag that is used to determine if we want to remove or not
var remove = true;
// Loop through all the attributes
for(var i = 0; i < node.attributes.length; ++i){
// If we find a mismatch, make the flag false and leave
if(node.attributes[i] !== tempNode.attributes[i]){
remove = false;
break;
}
}
// If we want to remove it
if(remove){
// Create a new fragment
var frag = doc.createDocumentFragment();
// Place all of nodes children into the fragment
while(node.firstChild){
frag.appendChild(node.firstChild);
}
// Replace the node with the fragment
node.parentNode.replaceChild(frag, node);
}
}
// Otherwise, look at the next parent
tempNode = tempNode.parentNode;
}
// Next node
node = it.nextNode();
}