推迟内联javascript执行?

时间:2013-11-24 20:27:06

标签: javascript jquery html

在我的网站上,我有很多内联的javascript片段。他们中的大多数都需要jquery和类似的东西。

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

2 个答案:

答案 0 :(得分:10)

如果您可以将javascript放在文档的末尾,那会好得多。使用小型内联javascript片段为您的源代码填充是页面性能的杀手锏。

也就是说,你可以在这个数组上创建一个数组并推送函数。然后,在页面的末尾,在加载jquery之后,遍历数组并执行每个函数。

E.g:

<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之间来回切换。如果你这样做,渲染性能将严重下降。

答案 1 :(得分:7)

您可以通过将内联脚本的type设置为浏览器不会像text/example那样处理的脚本来模拟延迟,并在文档末尾克隆这些脚本替换typetext/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版本(尽管可以修改代码以支持它们)。