只有在Meteor中100%准备好DOM后才能加载脚本?

时间:2015-06-05 08:01:29

标签: meteor

我使用的是Bootstrap模板,他们的HTML和他们的CSS / JS加载顺序是这样的:

<!DOCTYPE html>
<!--[if IE 8]>          <html class="ie ie8"> <![endif]-->
<!--[if IE 9]>          <html class="ie ie9"> <![endif]-->
<!--[if gt IE 9]><!-->  <html> <!--<![endif]-->
    <head>
        <meta charset="utf-8" />
        <title>Atropos - Responsive Multipurpose</title>
        <meta name="keywords" content="HTML5,CSS3,Template" />
        <meta name="description" content="" />
        <meta name="Author" content="Dorin Grigoras [www.stepofweb.com]" />

        <!-- mobile settings -->
        <meta name="viewport" content="width=device-width, maximum-scale=1, initial-scale=1, user-scalable=0" />

        <!-- WEB FONTS -->
        <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700,800" rel="stylesheet" type="text/css" />

        <!-- CORE CSS -->
        <link href="assets/plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
        <link href="assets/css/font-awesome.css" rel="stylesheet" type="text/css" />
        <link href="assets/plugins/owl-carousel/owl.carousel.css" rel="stylesheet" type="text/css" />
        <link href="assets/plugins/owl-carousel/owl.theme.css" rel="stylesheet" type="text/css" />
        <link href="assets/plugins/owl-carousel/owl.transitions.css" rel="stylesheet" type="text/css" />
        <link href="assets/plugins/magnific-popup/magnific-popup.css" rel="stylesheet" type="text/css" />
        <link href="assets/css/animate.css" rel="stylesheet" type="text/css" />
        <link href="assets/css/superslides.css" rel="stylesheet" type="text/css" />

        <!-- REVOLUTION SLIDER -->
        <link href="assets/plugins/revolution-slider/css/settings.css" rel="stylesheet" type="text/css" />

        <!-- THEME CSS -->
        <link href="assets/css/essentials.css" rel="stylesheet" type="text/css" />
        <link href="assets/css/layout.css" rel="stylesheet" type="text/css" />
        <link href="assets/css/layout-responsive.css" rel="stylesheet" type="text/css" />
        <link href="assets/css/color_scheme/orange.css" rel="stylesheet" type="text/css" /><!-- orange: default style -->
        <!--<link id="css_dark_skin" href="assets/css/layout-dark.css" rel="stylesheet" type="text/css" />--><!-- DARK SKIN -->

        <!-- styleswitcher - demo only -->
        <link href="assets/css/color_scheme/orange.css" rel="alternate stylesheet" type="text/css" title="orange" />
        <link href="assets/css/color_scheme/red.css" rel="alternate stylesheet" type="text/css" title="red" />
        <link href="assets/css/color_scheme/pink.css" rel="alternate stylesheet" type="text/css" title="pink" />
        <link href="assets/css/color_scheme/yellow.css" rel="alternate stylesheet" type="text/css" title="yellow" />
        <link href="assets/css/color_scheme/darkgreen.css" rel="alternate stylesheet" type="text/css" title="darkgreen" />
        <link href="assets/css/color_scheme/green.css" rel="alternate stylesheet" type="text/css" title="green" />
        <link href="assets/css/color_scheme/darkblue.css" rel="alternate stylesheet" type="text/css" title="darkblue" />
        <link href="assets/css/color_scheme/blue.css" rel="alternate stylesheet" type="text/css" title="blue" />
        <link href="assets/css/color_scheme/brown.css" rel="alternate stylesheet" type="text/css" title="brown" />
        <link href="assets/css/color_scheme/lightgrey.css" rel="alternate stylesheet" type="text/css" title="lightgrey" />
        <!-- /styleswitcher - demo only -->



        <!-- STYLESWITCHER - REMOVE ON PRODUCTION/DEVELOPMENT -->
        <link href="assets/plugins/styleswitcher/styleswitcher.css" rel="stylesheet" type="text/css" />     

        <!-- Morenizr -->
        <script type="text/javascript" src="assets/plugins/modernizr.min.js"></script>
    </head>
    <body><!-- Available classes for body: boxed , pattern1...pattern10 . Background Image - example add: data-background="assets/images/boxed_background/1.jpg"  -->

- 此处有很多HTML -

    <!-- JAVASCRIPT FILES -->
    <script type="text/javascript" src="assets/plugins/jquery-2.0.3.min.js"></script>
    <script type="text/javascript" src="assets/plugins/jquery.easing.1.3.js"></script>
    <script type="text/javascript" src="assets/plugins/jquery.cookie.js"></script>
    <script type="text/javascript" src="assets/plugins/jquery.appear.js"></script>
    <script type="text/javascript" src="assets/plugins/jquery.isotope.js"></script>
    <script type="text/javascript" src="assets/plugins/masonry.js"></script>

    <script type="text/javascript" src="assets/plugins/bootstrap/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="assets/plugins/magnific-popup/jquery.magnific-popup.min.js"></script>
    <script type="text/javascript" src="assets/plugins/owl-carousel/owl.carousel.min.js"></script>
    <script type="text/javascript" src="assets/plugins/stellar/jquery.stellar.min.js"></script>
    <script type="text/javascript" src="assets/plugins/knob/js/jquery.knob.js"></script>
    <script type="text/javascript" src="assets/plugins/jquery.backstretch.min.js"></script>
    <script type="text/javascript" src="assets/plugins/superslides/dist/jquery.superslides.min.js"></script>
    <script type="text/javascript" src="assets/plugins/styleswitcher/styleswitcher.js"></script><!-- STYLESWITCHER - REMOVE ON PRODUCTION/DEVELOPMENT -->
    <script type="text/javascript" src="assets/plugins/mediaelement/build/mediaelement-and-player.min.js"></script>

    <!-- REVOLUTION SLIDER -->
    <script type="text/javascript" src="assets/plugins/revolution-slider/js/jquery.themepunch.plugins.min.js"></script>
    <script type="text/javascript" src="assets/plugins/revolution-slider/js/jquery.themepunch.revolution.min.js"></script>
    <script type="text/javascript" src="assets/js/slider_revolution.js"></script>


    <script type="text/javascript" src="assets/js/scripts.js"></script>


    <!-- Google Analytics: Change UA-XXXXX-X to be your site's ID. Go to http://www.google.com/analytics/ for more information. -->
    <!--<script>
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

        ga('create', 'UA-XXXXX-X', 'domainname.com');
        ga('send', 'pageview');
    </script>
    -->

</body>

底部有相当多的JS,只有在浏览器中100%准备好DOM之后才需要加载。

不幸的是我很难让时机正确 - 我的页面仍然没有像演示那样起作用 - 滑块没有出现,视差无法正常工作,而且我&# 39;我确定很多事情也没有用,我没有注意到。我确定这种情况正在发生,因为当Meteor加载JS(通常全部加载在底部)时,一些DOM节点还不存在。

以下是我尝试的内容:

注意:我还想把很多这些JS文件直接放到client/javascripts中,以便我可以利用Meteor的自动缩小和捆绑功能进行制作

1。我认为在渲染布局模板之后是DOM应该准备好的时候,所以我会在渲染布局后将脚本标签附加到主体,但这不起作用。

Template.layout.onRendered(function() {

    console.log('layout rendered');

    var appendToHead = function(array){
        for (index in array){
            $('head').append(array[index]);
        };
    };

    var array = [
      // an array of all the script tags
      '<script type="text/javascript" src="assets/plugins/jquery-2.0.3.min.js"></script>',
      '<script type="text/javascript" src="assets/plugins/jquery.easing.1.3.js"></script>'
      // etc...
    ];

    appendToHead(array);

});
  1. 我已尝试在Tracker.afterFlush()中包装此功能,但这也不起作用。

  2. 我已尝试将此功能放入main.js,但该功能无效。

  3. 我已经尝试将其包装在Meteor.startup()中并且无法正常工作。

  4. 我甚至尝试将其包装在$('document').ready()中,但它没有用。

  5. 我要走出困境,说即使把所有东西都放到自己的包里也不行,因为包只能根据它对其他的依赖来控制包加载顺序JS文件,但没有能力根据DOM状态控制加载顺序,对吗?

  6. 顺便说一句,我在每次尝试旁边放置了控制台日志,这是他们被解雇的顺序。

    code inside Tracker.afterFlush has been fired
    code inside main.js has been fired
    code inside jQuery document.ready() has been fired
    code inside layout.onRendered has been fired
    

    部分困难是Meteor的碎片模板性质。一段JS代码(让我们说是幻灯片)需要一个DOM元素才能运行。在渲染布局时加载代码是没有意义的,因为布局只是布局而没有DOM元素。幻灯片显示所需的DOM元素包含在{{> intro}}{{> photos}}{{> videos}}模板中。

    但编写为这三个独立模板分别加载幻灯片JS三次的代码也很乏味......

    如果您正在使用八种不同的第三方JS脚本,该怎么办?一个模板使用四个,另一个使用八个,另一个使用一个,另一个使用六个。要完全定义要在每个单独模板的onRendered回调中加载哪些脚本,一遍又一遍,这将是一件非常痛苦的事。

1 个答案:

答案 0 :(得分:1)

您可以使用主模板的rendered()方法按给定顺序加载所需的JS脚本。假设您的主模板(或顶级模板)命名为appLayout,那么您可以定义render()方法,如下所示。

将所有JS文件放在流星应用程序的public\js文件夹中。

&#13;
&#13;
Template.appLayout.rendered = function() {
  if (!window.allScriptsLoaded) {
    var scripts = [
      // list of JS files to be loaded.
      'js/libs/jquery-2.1.1.min.js',
      'js/libs/jquery-ui-1.10.3.min.js',
      'js/plugin/jquery-touch/jquery.ui.touch-punch.min.js',
      'js/bootstrap/bootstrap.min.js'
    ];

    function loadNext() {
      var src = scripts.shift();
      if (typeof src === 'undefined')
        return;

      var s = document.createElement("script");

      s.setAttribute('src', src);
      if (s.addEventListener) {
        s.addEventListener("load", loadNext, false);
      } else if (s.readyState) {
        s.onreadystatechange = loadNext;
      }
      document.body.appendChild(s);
    };

    loadNext();
    window.allScriptsLoaded = true;
  }
}
&#13;
&#13;
&#13;

通过这种方式,您可以准确控制文件的加载顺序。