无法居中从 XMLHttpRequest 生成的元素

Can't center an element generated from XMLHttpRequest

我正在构建一个相当复杂的网络应用程序。加载主页,然后加载所有菜单项(300 多个)、表单提交等。通过 XMLHttpRequest 加载。我有一个基本的 "panel" 模板,允许面板的外观和行为(拖动、调整大小等)就像应用程序的子 window 一样。我将所有 XMLHttpRequest 请求的页面加载到 "panel" 模板的内容部分。

我 运行 遇到的问题是,如果我尝试将新的 "panel" 居中,它似乎找不到新的 "panels" 大小。我的代码已设置,因此当单击菜单项时,它 运行 是一个调用 XMLHttpRequest 函数的函数,原始函数将回调函数传递给 XMLHttpRequest。回调函数然后克隆面板模板,因此我可以更改几个元素属性,然后我将响应附加到文档片段中克隆的 "panel" 模板。然后所有内容都附加到显示的 HTML,之后我找到新的 "panels" 大小并尝试将其居中但它总是失败。

因为每个函数都比我在上面拼写的要多得多,所以希望下面是代码相关部分的准确精简版本。

XMLHttpRequest 函数没有异常,一旦成功响应,回调将 运行 "OpenPanel" 函数(见下文)。

回调函数:

function OpenPanel(e, response)
{
    var rescontent = response.querySelector('.content');
    var newid = rescontent.getAttribute('data-id');
    var titlebar = rescontent.getAttribute('data-title');

    var frag = document.createDocumentFragment();
    var clonepanel = doc.getElementById('paneltemplate').cloneNode(true);
    clonepanel.id = newid;
    frag.appendChild(clonepanel);

    frag.querySelector('.titlebar').innerHTML = titlebar;
    var replacelem = frag.querySelector('.content');
    replacelem.parentNode.replaceChild(rescontent, replacelem);

    doc.getElementById('mainbody').appendChild(frag);

    var newpanel = document.getElementById(newid);
    newpanel.addEventListener('mousedown', PanelSelect, true);

    newpanel.style.cssText = PanelPosition(newpanel);
}

面板位置函数:

function PanelPosition(panel)
{
    var lh = panel.clientHeight;
    var lw = panel.clientWidth;
    var wh = panel.parentNode.clientHeight;
    var ww = panel.parentNode.clientWidth;

    var paneltoppos = (wh - lh) / 2;
    var panelleftpos = (ww - lw) / 2;

    return 'top: ' + paneltoppos + 'px; left: ' + panelleftpos + 'px;';
}

我尝试使用延迟 1 毫秒的 setTimeout,但这会导致面板在移动之前在错误的位置在屏幕上闪烁。从我的角度来看,这让应用程序感觉很便宜,或者就像只给出了次要的努力。即使它没有闪现,setTimeout 看起来更像是一种破解而不是解决方案。

我已经用几个不同的 "pages"(xhr 请求)尝试了这段代码,我几乎感觉到当回调函数为 运行(我怀疑是可能的)。例如,我输入

console.log('top: '+wh+' - '+lh+'(wh - lh) left: '+ww+' - '+lw+'(ww - lw)');

在 "PanelPosition" 函数中,如果没有 setTimeout,面板高度 (lh) 和宽度 (lw) 在 100 到 200 像素之间。但是使用 setTimeout 时,面板的高度和宽度通常超过 500 像素。当然,这会严重影响居中的位置。

过去几天我尝试了几次搜索,但没有任何结果。因此,如果有描述问题和解决方案的好 post 或文章,请随时指点我。

应该注意,因为我 运行 只在 node-webkit/nw.js(chromium/webkit 浏览器)中使用网络应用程序,所以不需要跨浏览器解决方案。

好吧,我想我要回答我自己的问题了。

在寻找完全不相关的东西时,我发现了这个 SO post。接受的答案提供了解释问题的线索。

Unfortunately, it seems that you have to hand the controls back to the browser (using setTimeout() as you did) before the final dimensions can be observed; luckily, the timeout can be very short.

基本上 javascript 而不是 绘制附加元素直到函数调用结束。所以 setTimeout 是解决我的问题的一种方法。但是,还有第二种解决方案。如果我只需要等到函数结束,那么让我们做一个小的(集中的)函数。所以我只是将创建附加 "panel" 所需的所有代码移动到一个完全独立的函数中。这样做我解决了另一个悬而未决的问题。

编辑:

还是不行。显然,一个单独的函数现在不起作用,但在我 posted 之前它就起作用了。谁知道也许我在重新加载页面之前没有保存更改。