如何让浏览器等待页面完全加载后再显示?

96

我讨厌能够看到网页加载的过程。我认为等待页面完全加载并准备好显示,包括所有脚本和图像,然后再由浏览器显示会更具吸引力。所以我有两个问题:

  1. 我该如何做到这一点?
  2. 这是常见的做法吗?如果不是,为什么?

61
有些页面要等所有内容加载完后才会显示,我不喜欢这种情况。不要以为用户与你想法相同。 - Fredrik Mörk
12
Facebook这样做真的让我很生气。 - Josh Stodola
12
如果你这样做,至少要确保立即显示一个页面加载中的提示信息。 - Tor Haugen
7
你说你讨厌看到网页加载的过程,有时我也这样。特别是当内容在加载时跳来跳去时,会更加让人烦恼。你可以通过为图片设置明确的尺寸来减少这种情况,这样浏览器就知道要为它们留多大的空间,在加载时就不需要移动文字来适应它们。 - Nathan Long
@tkbx 一个好的想法是使用HTML5缓存这些元素,以便“框架”几乎瞬间加载。对于那些希望使其看起来更加流畅和专业的人来说,静态页面内容应该以这种方式完成。您甚至可以缓存一个带有加载栏的脚本,其中大块动态内容(如正文)会出现。只要您不需要支持IE9(不确定10),这就是一个很好的选择。只需确保每个页面都有一种发送“框架版本号”或其他信息的方式,以便触发清除缓存。 - Anonymous Penguin
显示剩余2条评论
16个回答

38

出于所有给出的原因以及更多原因,这是一个非常糟糕的想法。话虽如此,以下是使用 jQuery 实现它的方法:

<body>
<div id="msg" style="font-size:largest;">
<!-- you can set whatever style you want on this -->
Loading, please wait...
</div>
<div id="body" style="display:none;">
<!-- everything else -->
</div>
<script type="text/javascript">
$(document).ready(function() {
    $('#body').show();
    $('#msg').hide();
});
</script>
</body>

如果用户禁用了JavaScript,他们将永远无法看到页面。如果页面永远无法完成加载,他们也看不到页面。如果页面加载时间过长,他们可能会认为出了问题,并选择去其他地方而不是一直等待。


12
解决此问题的一种方法是利用<noscript>标签来“撤消”display:none的效果,以避免无法使用JavaScript的问题。 - Chris Thompson
我不得不使用 $(window) 而不是 $(document) - Jake Ireland

20
我认为这是一个非常糟糕的想法。用户喜欢看到进展,简单明了。将页面保持在一个状态几秒钟,然后立即显示加载的页面,会让用户感觉什么都没有发生,你可能会失去访问量。
一种选择是在页面上显示加载状态,而在后台处理内容,但这通常是为当网站实际处理用户输入时保留的。

http://www.webdeveloper.com/forum/showthread.php?t=180958

底线是,页面加载时至少需要展示一些视觉活动,而我认为分段加载页面并不算太糟糕(假设你没有做一些严重拖慢页面加载时间的事情)。


1
我设计了一个网站,当加载重量级内容时使用轻量级的旋转器 - 重量级内容被设置为 display: none。一旦所有内容都加载完毕,旋转器就会淡出,内容就会淡入。这个方法很有效,因为现在旋转器已经被普遍理解为“正在加载,请稍等”。注意:它使用jQuery。 - ADTC
6
我认为这样概括是不公平的。如果你正在构建一个非常快速和迅捷的网站,那么浏览器决定展示几帧未完成渲染的网站会让人感到很烦恼。我认为我们应该努力实现更好的网站和更好的用户体验。我并不是说这种修复方法是一种好的修复方法,我更希望浏览器等待处理完成。然后由网站来确保他们的东西被优化得很好且加载速度很快。我们不应该建立这样的系统,让程序员可以逃避懒惰和不良行为。 - BjarkeCK
关键在于您的页面设计是否覆盖了浏览器对页面加载的信号。浏览器一直有一个信号来显示页面是否仍在加载。现代浏览器使用动画加载图标来显示它,因此您甚至可以看到后台选项卡是否完全加载。最佳实践是确保无论您的页面如何加载,都要尊重该信号。任何向浏览器发出页面已完全加载的信号,而实际上并没有加载完成的页面设计,很可能会误导和惹恼用户。如果浏览器说已经加载完成,则对于在后台打开的选项卡,页面内部信号是无用的。 - cazort

13

以下是使用jQuery解决的方案:

<script type="text/javascript">
$('#container').css('opacity', 0);
$(window).load(function() {
  $('#container').css('opacity', 1);
});
</script>
我把这个脚本放在了</body>标签后面。只需将 "#container" 替换为您要隐藏的 DOM 元素的选择器即可。我尝试了几种变体(包括 .hide()/.show().fadeOut()/.fadeIn()),仅设置不透明度似乎对页面影响最小(闪烁、页面高度变化等)。您还可以将 css('opacity', 0) 替换为 fadeTo(100, 1),以获得更平滑的过渡效果。(不,fadeIn() 不起作用,至少在 jQuery 1.3.2 中是这样。)
现在有一些注意事项:我实施上述内容是因为我正在使用 TypeKit 并且当您刷新页面时字体需要几百毫秒才能加载,这会产生一些闪烁。因此,在 TypeKit 加载之前,我不希望任何文本出现在屏幕上。但是,如果使用上面的代码而页面上的某些内容无法加载,则会遇到大麻烦。有两种明显的改进方法:
  1. 最长时间限制(例如 1 秒),超过该限制后所有内容都将显示,而无论页面是否已加载完成
  2. 某种加载指示器(例如来自 http://www.ajaxload.info/ 的某些内容)
我不打算在此处实现加载指示器,但时间限制很容易。只需将以下内容添加到上面的脚本中即可:
$(document).ready(function() {
  setTimeout('$("#container").css("opacity", 1)', 1000);
});

所以现在,最糟糕的情况是,您的页面将需要额外等待一秒钟才能出现。


它闪烁是因为你使用JS隐藏了页面。我认为最好使用纯CSS来隐藏它。JavaScript的任务是在页面完全加载后删除display:none。 - Daniel Wu

13

这确实有一个有效的用途。其一是防止人们在所有页面元素和JavaScript加载完毕之前单击链接/触发JavaScript事件。

IE中,您可以使用页面转换,这意味着页面直到完全加载后才显示:

<meta http-equiv="Page-Enter" content="blendTrans(Duration=.01)" />
<meta http-equiv="Page-Exit" content="blendTrans(Duration=.01)" />

注意这个短暂的持续时间。它只足够确保页面在完全加载之前不会显示。

FireFox和其他浏览器中,我使用的解决方案是创建一个与页面大小相同且为白色的DIV,然后在页面底部放置隐藏它的JavaScript代码。另一种方法是使用jQuery并同样地将其隐藏。虽然不像IE的解决方案那样无痛苦,但两者都能很好地工作。


针对Firefox的解决方案:那些禁用了JavaScript的用户怎么办? - ChristopheD
8
回答:世界上那10个关闭 JavaScript 的人将无法看到该页面。 - bagofmilk
2
@ChristopheD 看起来很多东西都依赖于JS,所以[至少对于我的网站]它无论如何都无法正常运行。 - Anonymous Penguin

6
紧跟着您的 <body> 标签,添加类似于以下内容的代码...
 <style> body  {opacity:0;}</style>

在你的标签中,第一件要做的事情是添加类似以下内容的代码...
 <script>
  window.onload = function() {setTimeout(function(){document.body.style.opacity="100";},500);};
 </script>

这是好还是坏的做法取决于您的访问者以及等待的时间。

仍然存在一个未解决的问题,我在这里没有看到任何答案,那就是如何确保页面已经稳定。例如,如果您正在加载字体,则页面可能会在加载和显示所有字体之前重新排版。我想知道是否有事件可以告诉我页面已经完成渲染。


4
请确保服务器缓冲该页面,而不是在构建时立即(流式传输)发送给客户端浏览器。
由于您没有指定技术栈:
- PHP:请查看ob_start - ASP.NET:确保Response.BufferOutput = True(默认情况下为True)

2
请注意,尽管此方法可帮助发送巨大的动态构建的HTML页面,但对于“外部”链接的图像、脚本/样式表是无效的(但这些内容在第一次页面加载后将被存储在浏览器缓存中)。 - ChristopheD

3
在PHP-Fusion开源CMS中,我们在核心部分是这样做的 - http://www.php-fusion.co.uk
    <?php
        ob_start();
        // Your PHP codes here            
        ?>
        YOUR HTML HERE


        <?php 
        $html_output = ob_get_contents();
        ob_end_clean();
        echo $html_output;
    ?>

您将无法逐个加载查看任何内容。唯一的加载器是您的浏览器标签旋转器,在所有内容都加载完成后立即显示所有内容。试试吧。

这种方法完全符合html文件规范。


3

必须使用jQuery

我看过一些页面,它们在页面上方放置一个黑色或白色的div,然后在document.load事件中将其移除。或者你可以使用jQuery的.ready方法。话虽如此,那是我见过最烦人的网页之一,我建议不要这样做。


2
您可以使用一些 CSS 隐藏所有内容:
#some_div
{
  display: none;
}

然后在JavaScript中将一个函数分配给document.onload以删除该div。

jQuery使这样的事情变得非常容易。


7
当然,如果用户没有启用JavaScript,他们就无法看到你的页面。 - Nathan Long

2
除了Trevor Burnham的答案之外,如果你想处理禁用的javascript和延迟加载css,可以参考以下链接:禁用javascript延迟加载css HTML5
<html class="no-js">

    <head>...</head>

    <body>

        <header>...</header>

        <main>...</main>

        <footer>...</footer>

    </body>

</html>

CSS

//at the beginning of the page

    .js main, .js footer{

        opacity:0;

    }

JAVASCRIPT

//at the beginning of the page before loading jquery

    var h = document.querySelector("html");

    h.className += ' ' + 'js';

    h.className = h.className.replace(
    new RegExp('( |^)' + 'no-js' + '( |$)', 'g'), ' ').trim();

JQUERY

//somewhere at the end of the page after loading jquery

        $(window).load(function() {

            $('main').css('opacity',1);
            $('footer').css('opacity',1);

        });

资源


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接