【问题标题】:Defer inline javascript execution? [duplicate]推迟内联javascript执行? [复制]
【发布时间】:2013-11-24 20:27:05
【问题描述】:

在我的网站中,我有许多内联 javascript sn-ps。他们中的大多数都需要 jquery 和类似的东西。

但我想将 jquery 加载推迟到页面呈现后。这意味着,我的内联 javascript 将在加载 jquery 之前执行。我能做些什么吗?我正在寻找易于实施的解决方案(我也无法移动我的内联 javascript,因为它是在为用户准备页面时自动生成的)。

【问题讨论】:

  • 你能举一个例子来说明你所说的内联吗?实际上是在HTML元素里面吗?或者你的意思是每个都有自己的<script>
  • 另外,听起来您可以控制 javascript(因为您与 jquery 执行顺序有冲突)。我怀疑这可以通过另一种方式解决......

标签: javascript jquery html


【解决方案1】:

如果您可以将您的 javascript 放在文档的末尾会更好。使用小型内联 javascript sn-ps 洒在您的源代码上是页面性能的杀手。

也就是说,您可以创建一个数组并在该数组上推送函数。然后,在页面的最后,在加载 jquery 之后,循环遍历数组并执行每个函数。

例如:

<html>
  ...
  <script>window.loadEvents = [];</script>
  ...
  <script>loadEvents.push(function() { alert("inline code here"); });</script>
  ...
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script>$.each(loadEvents, function(_,f) { f(); });</script>
</html>

但是 - 正如我所说 - 将所有脚本元素推送到页面底部会更好,而不是在 html 和 javascript 之间来回切换。这样做会严重降低渲染性能。

【讨论】:

  • 你能举个例子吗! :D
  • 对我来说,我必须在回调中添加第二个参数,它保存实际值而不是索引...例如&lt;script&gt;$.each(loadEvents, function(i, f) { f(); });&lt;/script&gt;
【解决方案2】:

您可以通过将内联脚本的type 设置为像text/example 这样的浏览器无法处理的脚本来模拟延迟,并在文档末尾克隆这些脚本,将type 替换为text/javascript.

处理所有text/examples的代码真的很简单:

window.addEventListener("load", function() {

    var arr = document.querySelectorAll("script[type='text/example']");
    for (var x = 0; x < arr.length; x++) {
        var cln = arr[x].cloneNode(true);
        cln.type = "text/javascript";
        document.querySelectorAll("body")[0].appendChild(cln);
    }

});

或者如果您更喜欢使用 jQuery(您必须在 之后添加此脚本,包括 jQuery 文件):

$(function() {
    $("script[type='text/example']").each(function() {
        $(this).clone().attr("type","text/javascript").appendTo("body"); 
    });
});

此代码等待页面加载完毕,然后选择所有类型为text/example 的脚本,并将它们复制到body 的末尾,类型为text/javascript,以便它们正常执行。

例如:

...
<script type="text/example">
    console.log("I am before the h1");
</script>

<h1>Page Title</h1>

<script type="text/javascript">
    console.log("I am after the h1");
</script>
...

将在控制台中产生这些消息:

我在h1之后

我在h1之前

你可以在这个 JSFiddle 上看到一个正在运行的演示:http://jsfiddle.net/rqckwc79/


此解决方案的优点:

  • 这是一个跨浏览器的解决方案。
  • 代码是有效的 HTML/JavaScript。
  • 它在严格模式下工作。

此解决方案的缺点:

  • 您需要控制内联脚本才能更改type
  • 正如 troelskn 所说,性能会比将所有代码移到底部更差(但我知道在某些情况下这是不可能的)。
  • 它不适用于旧 IE 版本(尽管可以修改代码以支持它们)。

【讨论】:

  • 我知道我对这个问题有点迟到了,但我看到other users 提出了相关问题并被推荐到这里。只是为了让他们有另一个选项,不需要更改页眉/页脚来推迟内联脚本
  • 这是一个非常好的延迟 JavaScript 的解决方案,尤其是在 Pagespeed 友好的方式中。谢谢。旧版 IE,我猜你的意思是低于 8 版?!
  • 是的。此解决方案使用仅受 IE 版本 8 支持的querySelectorAll(并且仅部分支持该特定版本)。我还有一个版本也可以在 IE 6 和 7 上运行,但它更复杂(而且有点 hacky
  • 我想通了。 IE8 是我目前的基线;如果你再往下走,那就太痛苦了。
猜你喜欢
  • 2017-05-14
  • 1970-01-01
  • 2011-12-01
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 2012-02-15
  • 2014-08-03
  • 2018-02-25
相关资源
最近更新 更多