隐藏页面,直到所有内容加载完毕。高级设置。

48

我有一个网页,它大量使用jQuery。

我的目标是只在所有内容准备就绪后显示页面。

这样做可以避免向用户展示令人讨厌的页面渲染过程。

到目前为止,我尝试了以下代码(#body_holderbody内的包装器):

$(function(){
    $('#body_holder').hide();
});
$(window).load(function() {
    $("#body_holder").show();
});

这个方案完全可行,但会破坏布局。

问题在于隐藏包装器会干扰使用的其他jQuery功能和插件(例如布局插件)。

因此,我想必须有另一种技巧来实现这一点。也许可以在window.load发生之前将图片或div覆盖在body上?

你使用什么方法?

编辑:

解决方案很可能不是display:nonehide()


3
你是否考虑使用CSS将"display:none"应用于"#body_holder",然后在$(document).ready(function(){ $("#body_holder").show(); });中,一旦DOM准备就绪,再将其显示出来? - Ohgodwhy
2
如果您在HTML中指定图像大小,页面加载时就不会那么让人讨厌地“跳动”。如果您做对了,渲染可能会比在完全加载所有内容之前等待更少令人讨厌。请重新考虑您是否真的想这样做。 - GolezTrol
@Ohgodwhy 是的,那是我尝试的第一种方法。在 body 上使用 display:none,但效果与我的示例相同。问题仍然存在。它隐藏了页面,但在显示时布局和其他所有内容都混乱了。 - Email
@GolezTrol 謝謝。這個頁面上沒有任何圖片,只渲染了內容和佈局。 - Email
1
不要使用display:none,而是使用opacity:0和filter:alpha(opacity=0);。 - Ohgodwhy
10个回答

52

使用jQuery进行的任何操作通常都需要等待document.ready事件触发,但在我看来这太晚了。

可以像这样将div置于顶部:

<div id="cover"></div>

设置一些样式:

#cover {position: fixed; height: 100%; width: 100%; top:0; left: 0; background: #000; z-index:9999;}

并使用JS在所有元素加载完成后隐藏它:

$(window).on('load', function() {
   $("#cover").hide();
});

或者,如果由于某种原因您的脚本加载时间比DOM元素更长,请设置间隔来检查加载最慢的某些函数的类型,并在所有函数定义完毕后删除覆盖物!

$(window).on('load', function() {
    $("#cover").fadeOut(200);
});

//stackoverflow does not fire the window onload properly, substituted with fake load

function newW()
{
    $(window).load();
}
setTimeout(newW, 1000);
#cover {position: fixed; height: 100%; width: 100%; top:0; left: 0; background: #000; z-index:9999; 
    font-size: 60px; text-align: center; padding-top: 200px; color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<ul>
    <li>This</li>
    <li>is</li>
    <li>a</li>
    <li>simple</li>
    <li>test</li>
    <li>of</li>
    <li>a</li>
    <li>cover</li>
</ul>

<div id="cover">LOADING</div>


这不是你的包装器,而是一个新的元素,它被固定定位并具有较高的z-index,你可以将该元素放置在代码中的任何位置,直到它被JS移除之前,它将覆盖你的网站,这意味着你保持其他网站元素可见,但被“遮盖”元素覆盖。 - adeneo
在小工具中设置超时时间有点糟糕。 :/ - kaiser
@kaiser - 在一个两个月前的答案上发表评论更加无聊吧?超时只是为了展示效果,因为window.load在JSfiddle框架中不会触发,所以除非你强制执行window.load,否则即使代码在常规网站上可以工作,但在fiddle上却不能工作。无论如何,在这个答案之上的那个似乎是正确的答案? - adeneo
这对CEO不会有损害吗?我听说网络爬虫会检查关闭JS后的页面外观,而覆盖物可能会引起他们的怀疑。如果能证明我错了,我会很高兴的。 - I Hafid
1
@IHafid - 是的,这可能会对SEO造成潜在的损害,但是现在的网络爬虫足够智能化,可以识别大部分内容,包括ajax和框架等,所以这并不是一定的情况。 - adeneo
显示剩余4条评论

48

以下是一种针对jQuery的解决方案:

使用CSS隐藏主体,然后在页面加载后显示它:

CSS:

html { visibility:hidden; }

JavaScript

$(document).ready(function() {
  document.getElementsByTagName("html")[0].style.visibility = "visible";
});

当页面加载时,页面将从空白变为显示所有内容,没有闪烁的内容,也没有观看图片加载等情况。


1
我认为如果您使用jQuery,将不会有任何缺点。 - PascalVKooten
3
$ 是 jQuery,不是纯 JavaScript。 - Kyle Pennell
3
非常整洁的解决方案 - 使用'html'元素本身的'visibility'属性消除了包装器的需要。 - Velojet
如果网页在现有的浏览器标签中打开,这种方法非常棒。然而,如果页面是从另一个带有_blank属性的浏览器标签中启动的,会出现一个短暂(但仍然很烦人)的“闪烁”,直到新的网页(其中嵌入了上述代码)接管控制权。有没有办法隐藏浏览器标签之间的这个“闪烁”?谢谢! - ND_Coder
非常整洁的解决方案 - undefined

31

你应该尝试将visibility设置为hidden而不是display:none。将visibility设置为hidden将保留所有元素的位置和尺寸,因此不会引起布局问题。


这很流畅,而且有效。谢谢 +1。我希望它是跨浏览器有效的。 - Email
2
当页面正在加载时,document.style.visibility元素无法设置(直到稍后才为null)。然而,我的老板向我展示了可以设置document.style.opacity = 0。 - Colin

5

在你的HTML中,以以下方式开始:

<body style="opacity:0;">

在你的脚本结尾处:

document.body.style.opacity = 1;


1
对我没用,但这个可以: document.getElementsByTagName("body")[0].style.opacity = "1"; - FedeKrum
有时候它对我也不起作用,我会使用你的建议,但我不知道为什么。 - tecnobillo

4

我偶然看到了这个问题并尝试了@9ete的解决方案,但它没有帮助我。

这个才有效:

CSS:

html { visibility:hidden; }

JS:

window.addEventListener('load', function () {
    document.getElementsByTagName("html")[0].style.visibility = "visible";
});

根据关于 window 的文档,load 事件在所有内容(包括图像)加载完成后触发;而针对 $document,它只表示当 DOM 准备就绪时才会触发 ready 事件。

2

你的问题是有意义的,但我不会在页面加载时隐藏或覆盖页面。

这会阻止用户了解页面上正在发生的事情。虽然可能需要加载很多东西,但页面的不同部分应该在加载时逐渐变得活跃起来。您应该锁定尚未准备好的控件,可能在它们上面显示旋转器或其他进度指示器。或者在加载项目时将光标设置为等待

这可以让用户保持联系,并允许他在在线部分上看到并与之交互,而不是在一切准备就绪之前遮盖所有部分。

通常,您希望首先加载用户最快速访问的内容,通常是以上折叠内容。加载是可以轻松协调使用 Promises 的优先级设置。

至少看到页面可以让用户了解情况并决定如何操作。保持透明。


2
我正在寻找一种不需要JavaScript的解决方案,所以我找到了一种在大多数浏览器中能够令人满意地工作的方法。
由于CSS规则的加载顺序很重要:
- 在第一个CSS文件或head内联中定义隐藏类。
.hidden-onpage-load{ display: none; } 
  • 在 HTML 的 body 中,可以使用该类作为:
<div class="hidden-onpage-load"> ... </div>
  • 在所有其他CSS和JS文件加载完后,重新定义它的内联样式或在CSS文件中定义。
.hidden-onpage-load{ display: block; } 

0
我想到的最简单的解决方案是将body标签包装在一个div中,如之前建议的那样,但一开始将其设置为隐藏状态,然后使用JQuery(或javascript)在所有组件加载完成后进行加载并显示。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="bodyDiv" hidden>

Hello World!

</div>
<script>
$(document).ready(function() {

  // add JQuery widget loads here
  
  $("#bodyDiv").show(); // reveal complete page
})
</script>


0

别忘了,很多框架使用JavaScript来构建页面。为了防止在这些修改完成之前显示页面,您需要做一些类似于此处所描述的事情(例如,在页面末尾运行脚本以显示页面的真实内容):

检测是否有任何JavaScript函数正在运行


-1
如果您有一个名为 #bodyholder 的 div,那么您可以在 CSS 中将 display:none 放入其中,然后使用 jQuery 进行以下操作:
$(document).ready(function() {
     $('#body_holder').show();
});

我不明白为什么隐藏一个div会影响任何加载,因为它只是意味着它被隐藏了。然而,如果您使用了大量的jQuery,请确保将其包装在$(document).ready中,这将确保DOM在执行Javascript之前完全加载。

另一个要点是HTML/CSS是为渐进式加载而设计的,如果您正确地使用它,则可以为用户获得漂亮的内容逐步加载。我个人不希望我的用户在几秒钟内看到一个白屏,直到所有内容都加载完成。将您的Javascript移动到页面底部,以便它不会阻止加载,并尽快将内容放到屏幕上。


嗨。这与我的示例完全相同。CSS 只能在 DOM 准备就绪时隐藏 div。这是我第一次尝试使用 CSS 进行隐藏。问题显然仍然存在。我的 jQuery 更改了布局并隐藏了 div。例如,我使用 http://layout.jquery-dev.net/。show() 页面被搞砸了。我真的在寻找一种优雅的方式来覆盖包装器。 - Email
1
布局插件需要能够设置尺寸,因此隐藏主内容元素不是一个好的选择。 - charlietfl
@ charlietfl 谢谢,你是第一个考虑到这个问题的人。我现在已经在我的问题中加粗了它。 - Email

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