我有一个页面,其最终渲染由一些jQuery运行的JavaScript调整,格式为
<script>
(function ($) {
//
})(jQuery);
</script>
这个JS根据DOM元素的初始大小和位置进行调整。
这在大多数情况下运作良好,但偶尔会有结果出来。
我认为原因是JavaScript试图获取尚未渲染的元素的位置,因此后续的定位计算出错了。
如何确保在此JS运行之前完全呈现DOM?
答案 0 :(得分:3)
你说你已经等到jQuery的 (我想到我看到了你的回复评论说你是,但我现在没有看到该评论而引用的代码没有。)你可以等到ready
事件发生了。window
load
事件火灾,但这发生在这个过程的后期。
相反,我建议继续在ready
(或更早,通过将脚本标记放在body
的末尾而不使用ready
)运行,但设置为计时器触发并重新检查您所依赖的事物的大小,如果这些更改则调整大小。初始计时器可能设置为“零”毫秒(实际上不是),然后可能再次设置为50,然后是100或200,然后只需调整window
resize
的大小。
像这样模糊的东西:
<!-- ...content... -->
<script src="yourscript.js"></script>
</body>
</html>
...其中yourscript.js
是:
(function($) {
var start = +new Date(),
loaded = false,
lastSizes = {}, // Sizes of relevant elements
resizeTimer = 0;
// Check resize on load, flagging that load is complete.
// Maybe resize on resize.
$(window).load(function() {
loaded = true;
checkResize();
}).resize(maybeResize);
// Initial trigger
initialResizeCheck();
// Actually do a resize operation
function resize() {
// ...your sizing logic, which sets the sizes in `lastSizes`
}
// Check the sizes in `lastSizes` vs. current ones, calls
// `resize` if they're not set up yet or if they've changed.
// (Wouldn't be uncommon for this to be combined with `resize`).
function checkResize() {
}
// The function we use early on to proactively check until `load` fires
function initialResizeCheck() {
var elapsed = +new Date() - start;
checkResize();
if (!loaded) {
if (elapsed < 10) {
setTimeout(initialResizeCheck, 0);
}
else if (elapsed < 100) {
setTimeout(initialResizeCheck, 30);
}
else if (elapsed < 500) {
setTimeout(initialResizeCheck, 100);
}
}
}
// Trigger a resize when the window is resized, but not until it
// stops being resized.
function maybeResize() {
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(checkResize, 10);
}
})(jQuery);
这些间隔完全是袖手旁观,但你明白了。积极主动,然后在必要时进行调整。