javascript - jquery:多个 ajax 调用以不同的顺序响应,并且 document.body 导致对象丢失与 DOM 元素的链接

标签 javascript jquery ajax dom

我遇到了一些非常奇怪的事情,我似乎无法弄清楚。

我有 2 个 ajax 调用,它们为我获取一些 html,这些 html 必须写入具有传递的 ElementID 的元素或文档正文。 如果两个响应返回的顺序与调用启动的顺序相同,则没有问题。如果两个响应都必须写入我们通过 Id 获取的 Element,也没有问题。

但是,如果响应返回的顺序与启动顺序不同,并且其中一个响应被写入文档正文,则容器对象似乎会丢失与 DOM 元素的链接。

这是 JS fiddle :JS fiddle

如果你改变,你就会看到这一点

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>

最佳答案

However, if the responses come back in a different order from the order they are launched in and one of the responses is written to the document body, the container object seems to lose its link to the DOM Element.

是的,这是因为当设置节点的 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"}
因为 objobj2 是两个不同的对象。

关于javascript - jquery:多个 ajax 调用以不同的顺序响应,并且 document.body 导致对象丢失与 DOM 元素的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32005927/

相关文章:

javascript - 加载表中的记录。浏览器无响应

javascript - 使用 span 代替 div 来显示省略号

javascript - 在 jquery 中访问 Spring MVC 模型对象

javascript - HTML5 + JAVASCRIPT 使用文件的前 4 个字节进行异步表单验证

javascript - 发布的 Ajax 发送的数据似乎没有出现在 Django View 中

jquery - 使用Jquery ajax json响应?

javascript - 如何在 jQuery 中定位未选中的复选框?

javascript - 创建新 MouseEvent 的老式方法是什么样子的?

javascript - 为此加载点脚本选择不同的颜色

javascript - 按名称/键回调 json 值