Node.isEqualNode
可以用于比较当前节点(Node)和指定节点是否是相同的。和 Node.isSameNode
不同,.isEqualNode
API 并不需要两个被比较的节点是同一个。只需要满足以下的条件,两个节点就会被认为是相同的:
- 两个节点的 nodeType 是相同的;
- (省略非 Element 比较的情况,具体细节可以参考 DOM 规范);
- 如果节点是 element 的话,那么对
A.isEqualNode(B)
来说,A 中所有的属性,都可以在 B 上找到相同的值(反之亦然); - 两个节点应该有等长的
children
; - 两个节点的
children
的每个相同位置上的值都是相同的(递归调用isEqualNode
的定义)。
这里需要说明的几点是:
- 在属性判断的时候,并不需要关心顺序:
const first = document.createElement('div');
const second = document.createElement('div');
const id = 'id';
const className = 'className';
first.id = id;
first.className = className;
second.className = className;
second.id = id;
// first: <div id="id" className="className"></div>
// second: <div className="className" id="id"></div>
first.isEqualNode(second); // => true
- 属性的判断是直接对值进行比较的,因此
style
的顺序不同会造成结果的不同:
const first = document.createElement('div');
const second = document.createElement('div');
first.style.display = 'block';
first.style.color = 'red';
second.style.color = 'red';
second.style.display = 'block';
// first: <div style="display:block;color:red"></div>
// second: <div style="color:red;display:block"></div>
first.isEqualNode(second); // => false
- 属性的比较是顺序无关的,但是
children
的比较是顺序相关的:
const first = document.createElement('div');
const second = document.createElement('div');
const childA = document.createElement('div');
const childB = document.createElement('div');
first.appendChild(childA);
first.appendChild(childB);
second.appendChild(childB);
second.appendChild(childA);
first.isEqualNode(second); // => false
- Node 是 Element 的“父类”,除了一般的 DOM 节点之外,节点上的 attributes,节点中的 comment 等也是 Node。这些节点也有
isEqualNode
API 可以用于比较。对于一般的 Element 来说,可以简单的认为类型,属性和子节点一样,isEqualNode
就会返回true
。