[英]Adding to innerHTML of document.body causes jQuery .on() to not find its target
[英]jquery: multiple ajax calls with responses in different order and document.body causes object to lose link with DOM Element
我正在进行一些很奇怪的事情,似乎无法弄清楚。
我有2个ajax调用,这些调用使我获取一些html,这些html必须写入具有传递的ElementID的元素或文档主体中。 如果两个响应都以与发出呼叫相同的顺序返回,则没有问题。 如果两个响应都必须写入通过ID获得的Element,则也没有问题。
但是,如果响应以与启动顺序不同的顺序返回,并且其中一个响应被写入文档主体,则容器对象似乎失去了与DOM元素的链接。
这是JS小提琴: JS小提琴
您会发现,如果您进行更改
Resengo({
CompanyID: '350034',
Call: 'B',
Time: '60',
ElementID: 'B'
});
至
Resengo({
CompanyID: '350034',
Call: 'B',
Time: '60'
});
,其响应不会写入页面,而pageContainer已完全失去与其DOM元素的链接。
编辑:当然,可以通过更改轻松地解决此问题
function renderWidget(html) {
if (pageContainer) {
pageContainer.innerHTML += html;
console.log(pageContainer);
}
}
至
function renderWidget(html) {
if (settings.ElementID) {
pageContainer = document.getElementById(settings.ElementID);
}
if(pageContainer) {
pageContainer.innerHTML += html;
console.log(pageContainer);
}
}
但我对此为什么不起作用感到好奇,因为这似乎不合逻辑
编辑2:这是相关的javascript
var Resengo = (function () {
// constructor
var Resengo = function resengo(settings) {
jQuery = window.jQuery;
getWidget();
// private class variable
var settings = settings;
var pageContainer;
function getWidget() {
jQuery(document).ready(function ($) {
/******* Create and add loader *******/
if (settings.ElementID) {
pageContainer = document.getElementById(settings.ElementID);
} else {
pageContainer = document.body;
}
/******* Load HTML *******/
var url;
if (settings.ElementID) {
carouselWidth = $('#' + settings.ElementID).outerWidth();
}
if (settings.ElementID) {
carouselHeight = $('#' + settings.ElementID).outerHeight();
}
if (settings.Time) {
doOpenReservationPopup = settings.Time * 1000;
}
if (settings.Language) {
language = settings.Language;
}
url = '/echo/html/';
var delay = 0;
if(settings.Call == 'A') {
delay = 1;
}
$.ajax({
url: url,
type: 'POST', // form submit method get/post
data: {
html: "<p>Text echoed back to request</p>",
delay: delay
},
dataType: 'html', // request type html/json/xml
success: function (data) {
renderWidget(data);
}
});
});
};
function renderWidget(html) {
if (pageContainer) {
pageContainer.innerHTML += html;
console.log(pageContainer);
}
}
};
return Resengo;
})();
Resengo({
CompanyID: '350034',
Call: 'A',
ElementID: 'A'
});
Resengo({
CompanyID: '350034',
Call: 'B',
Time: '60',
ElementID: 'B'
});
和相关的html:
<body bgcolor="#999999">
<div id="Feedbacks">
</div>
<br /><br />
<div id="A">
</div>
<div id="B">
</div>
</body>
但是,如果响应以与启动顺序不同的顺序返回,并且其中一个响应被写入文档主体,则容器对象似乎失去了与DOM元素的链接。
是的,这是因为设置节点的innerHTML
属性时,将删除所有子节点,解析HTML字符串,并从中创建新节点。
因此,对body
子节点的所有引用均被破坏。 节点不只是相同,因为它们碰巧具有相同的id
属性或其他属性。
var div1 = document.getElementById('test'); document.body.innerHTML = '<div id="test">Test</div>'; var div2 = document.getElementById('test'); document.write(div1 == div2);
<div id="test">Test</div>
在JS中对对象进行JSON序列化和反序列化时,基本上发生了相同的事情:
var obj = { 'a': 'AAA' }; var obj2 = JSON.parse(JSON.stringify(obj)); obj.b = 'BBB'; document.write(JSON.stringify(obj2));
为什么不打印{"a":"AAA", "b":"BBB"}
?
因为obj
和obj2
是两个不同的对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.