找出两个dom元素的差异,然后使它们相同
find difference in two dom elements then make them same
如果我有两个元素:
元素A:
<div id="myID">
<div id="a"></div>
<div id="b"><div id="ba"></div></div>
<div id="c"><span id="ca"></span></div>
</div>
和元素B:
<div id="myID">
<div id="a"></div>
<div id="b"><div id="ba"></div></div>
<div id="c"><span id="ca"></span></div>
<div id="d"></div>
</div>
是否可以发现Element B
比Element A
有更多的子元素,然后找到附加元素并在Element A
中创建它
p.S:在实际代码中,新元素是用Ajax Request
加载的,但我不想用加载的内容替换所有内容,我只需要添加新内容,跳过现有内容
p.S.S:在我当前的代码中,我有Md5校验和来检查新内容是否与现有内容不同,但如果新内容只有很小的变化,它会替换所有内容,这就是我的问题所在。
我当前的一段代码:
window.processResponse = function(data) {
// Note : "data" is Ajax responseText;
if(!data) return false;
var $data = document.createElement("div");
$data.innerHTML = data;
var em = $data.getElementsByTagName("*");
for(var i = 0; i < em.length; i++)
{
var parent = sget(em[i].id); // sget function is : document.getElementById
if(parent)
{
var html = em[i].innerHTML.replace(/('s)+/gim, "").replace(/('n|'r'n)+/gim, "");
var id = em[i].id;
savedPages[id] = savedPages[id] || [];
var _md5 = md5(html);
if(savedPages[id][0] == _md5) continue;
savedPages[id] = [_md5, getTime()];
parent.innerHTML = em[i].innerHTML;
}
if(em[i].tagName === "SCRIPT")
{
var code = em[i].innerHTML.replace(/('s)+/gim, "").replace(/('n|'r'n)+/gim, "");
var id = em[i].id;
savedPages[id] = savedPages[id] || [];
var _md5 = md5(code);
if(savedPages[id][0] == _md5) continue;
savedPages[id] = [_md5, getTime()];
try{eval(em[i].innerHTML)}catch(ex){log(ex)};
}
}
};
因此,您可以对其进行优化,但这也取决于您在哪个浏览器中运行此代码。我假设如下:
-
所有ID都是唯一的,并且您依赖于此。您想要比较的基本元素具有相同的ID,而不是相同的结构。
-
正如您所说,所有子节点都有ID,并且您希望只比较子节点,而不是嵌套节点
-
从服务器接收的元素只有额外的子元素,而不是更少。要删除子项,您必须添加一些其他代码。
-
因此,如果你有相同数量的孩子,我们假设他们是相同的(为了优化)。如果这不是真的,那么你必须实施删除儿童以及
话虽如此,我相信这种东西更适合在服务器端,那应该只发送给客户端实际修改的部分。这就是我们通常所做的——或者,如果我们不在乎,就取代一切。
var div = document.createElement('div');
div.innerHTML = s;
var root = div.firstChild;
var children = root.children;
var documentRoot = document.getElementById(root.id);
if (documentRoot && documentRoot.children.length < children.length) {
var node = null;
var previousNode = null;
var index = 0;
while ( node = children[index++] ) {
var documentNode = document.getElementById(node.id);
if (!documentNode) {
if (previousNode)
documentRoot.insertBefore(node, previousNode.nextSibling);
else
documentRoot.insertBefore(node, documentRoot.firstChild);
documentNode = node;
}
previousNode = documentNode;
}
previousNode = null;
} else {
// probably append as is somewhere
}
解决方案并不那么简单。如果样本A中不存在父节点myID,但两个样本中都有子节点,指示DOM中需要比较和调整的3个层,该怎么办?你将如何比较:
<div id="papa">
<div id="myID">
<div id="a"></div>
<div id="b">
<div id="ba"></div>
</div>
<div id="c">
<span id="ca"></span>
</div>
</div>
</div>
与
<div id="papa">
<div id="a"></div>
<div id="b">
<div id="ba"></div>
</div>
<div id="c">
<span id="ca"></span>
</div>
</div>
在这种情况下,比较变得更加复杂。实际上,您将需要一个完整的XML/HTML语言感知diff实用程序和一个merge函数。您可以使用Pretty Diff来演示它会变得多么复杂,但不幸的是它没有合并功能,因此它不能完全自动解决您的问题。
- 将事件侦听器添加到文档,而不是签入元素存在,然后添加事件侦听器
- 将元素移动到右侧,然后返回到左侧
- 添加animate.css类,然后使用remove移除元素
- Angular js,在选择元素上,我想 POST 数据以将其保存在数据库中,然后我想使用 PUT 更新它而无需重新加载
- 在元素中搜索字符串,然后将其放入条件语句中
- 从异步调用返回数组,然后为数组的每个元素返回其他异步调用
- JQuery 测试元素是可见的还是隐藏的,然后添加删除类
- 为什么这个脚本只工作一次?只替换元素一次,然后再也不替换
- 如何删除元素的结束标记,添加一些文本,然后重新添加标记
- jQuery检查URL,然后显示和隐藏元素
- Javascript(动态)插入到数组中,然后移动+1下面的所有元素
- jQuery-等待此元素,然后执行1次
- 如何正确地等待元素获得正确的宽度,然后在Angular 2中访问它
- ()插入元素,然后将其取回
- 从数组中删除元素,然后保留其状态以备将来使用,而不使用全局变量
- jQuery查找元素,然后组成逗号分隔的列表
- 使用Raphael.js可以相对定位一个元素,然后将其偏移一个绝对单位
- 我如何让我的网站检测鼠标是否被使用,然后在元素中添加一个类
- 等待文档鼠标按下完成,然后元素单击才能开始
- Javascript循环形式的值先名称,然后元素id