简体   繁体   English

在Meteor JS中,如何控制与DOM加载顺序相关的Javascript加载顺序? 对于动画

[英]In Meteor JS, how to control Javascript load order in relation to DOM load order? For animations

I've got a template that I downloaded: 我有一个下载的模板:

http://halibegic.com/projects/merlin/ http://halibegic.com/projects/merlin/

I want to use it in Meteor and I'm having major issues with 我想在Meteor中使用它,我遇到了重大问题

<script src="assets/js/script.js"></script>

at the bottom on line 444 not loading in the right order. 在444行的底部没有按正确的顺序加载。 When the page loads, none of the 4 functions specified in this js file work. 页面加载时,此js文件中指定的4个函数都不起作用。

initNavbar(); initPortfolio(); initAnimations(); initTwitterFeed();

I have all the css, fonts, images, and js files in my public folder and they are all correctly referenced in the HTML. 我在public文件夹中包含所有css,fonts,images和js文件,并且它们都在HTML中正确引用。 They are not in the lib directory which loads before everything else. 它们不在 lib目录中,而是在其他所有目录之前加载。

I think it's because the script is somehow loading before the DOM is loaded, so it has no DOM to apply things to. 我认为这是因为脚本在加载DOM之前以某种方式加载,所以它没有DOM来应用。

Things I've tried: 我试过的事情:

  • When I change the name of script.js to main.js and change line 444 to <script src="assets/js/main.js"></script> the animations still don't work. 当我将script.js的名称更改为main.js并将第444行更改为<script src="assets/js/main.js"></script> ,动画仍然无效。

  • When I add this into the script file it still doesn't load correctly: 当我将其添加到脚本文件中时,它仍然无法正确加载:

    $(document).ready(function () { initNavbar(); initPortfolio(); initAnimations(); initTwitterFeed(); });

  • I can do 我可以

    Template.layout.rendered/created = function () { add in all the function code and call them here }

    but this seems like an uncredibly, INCREDIBLY messy and inefficient way to do this. 但这似乎是一种难以置信,令人难以置信的混乱和低效的方式。 I need to specify the load order of individual files , not code. 我需要指定单个文件的加载顺序,而不是代码。 I have around five .js files in this template and I don't want to have to cut out their code and paste it all into one Template.layout.rendered/created function. 我在这个模板中有大约五个.js文件,我不想删除它们的代码并将它们全部粘贴到一个Template.layout.rendered/created函数中。

All you need to do is to load the javascript after the template is rendered. 您需要做的就是在呈现模板后加载javascript。

Template.yourLayout.created = function() {
  $('head').append('<script type="text/javascript" src="assets/js/script.js">');
}

If you have scripts loaded in $(window).load() or $(document).ready(), remember to get that out as well. 如果您在$(window).load()或$(document).ready()中加载了脚本,请记住也要这样做。 You could run them in the promise of $getScript as well. 您也可以在$ getScript的承诺中运行它们。 This is your case: 这是你的情况:

$.getScript('assets/js/script.js', function() {
      initNavbar();
      initPortfolio();
      initAnimations();
      initTwitterFeed();
      $(".loader .fading-line").fadeOut();
      $(".loader").fadeOut("slow");
});

None of the above answers worked for me, so I kept hacking away until finally the following worked: 上述答案都不适合我,所以我一直在黑客攻击,直到最后工作:

Template.layout.rendered = function() {
  // hack: these third party header animation scripts must be inserted at the bottom of body
  $('body').append('<script type="text/javascript" src="assets/js/classie-main.js">');
  $('body').append('<script type="text/javascript" src="assets/js/cbpAnimatedHeader.js">');
};

I put this in my layout.js file. 我把它放在我的layout.js文件中。

Thanks to imslavko for the answer! 感谢imslavko的答案!

http://docs.meteor.com/#meteor_startup http://docs.meteor.com/#meteor_startup

On a server, the function will run as soon as the server process is finished starting. 在服务器上,只要服务器进程完成启动,该函数就会运行。 On a client, the function will run as soon as the DOM is ready. 在客户端上,该函数将在DOM准备就绪后立即运行。

So I put this into my client/views/application/layout.js. 所以我把它放到我的client / views / application / layout.js中。 It uses the jQuery $.getScript, so you have to make sure that jQuery is loaded before you try this: 它使用jQuery $ .getScript,因此在尝试此操作之前必须确保加载了jQuery:

Meteor.startup( function () {
  $.getScript("assets/js/jquery.min.js");
  $.getScript("assets/js/bootstrap.min.js");
  $.getScript("assets/js/isotope.pkgd.min.js");
  $.getScript("assets/js/imagesloaded.min.js");
  $.getScript("assets/js/jquery.scrollTo.min.js");
  $.getScript("assets/js/jquery.nav.min.js");
  $.getScript("assets/js/jquery.appear.min.js");
  $.getScript("assets/js/twitterFetcher.min.js");
  $.getScript("assets/js/script.js");
});

So all of these files will now load AFTER the DOM loads, and therefore animations work. 因此,所有这些文件现在将在DOM加载后加载,因此动画可以工作。

It's clear from here: Meteor Docs 从这里可以清楚地看到: Meteor Docs

It is best to write your application in such a way that it is insensitive to the order in which files are loaded, for example by using Meteor.startup, or by moving load order sensitive code into packages, which can explicitly control both the load order of their contents and their load order with respect to other packages. 最好以对文件加载顺序不敏感的方式编写应用程序,例如使用Meteor.startup,或将加载顺序敏感代码移动到包中,这可以显式控制加载顺序他们的内容和他们的负载顺序相对于其他包。 However sometimes load order dependencies in your application are unavoidable. 但是,有时您的应用程序中的加载顺序依赖性是不可避免的。

When not using special filenames and directories: 不使用特殊文件名和目录时:

Files in subdirectories are loaded before files in parent directories, so that files in the deepest subdirectory are loaded first, and files in the root directory are loaded last. 子目录中的文件在父目录中的文件之前加载,因此最先加载最深子目录中的文件,最后加载根目录中的文件。 - Within a directory, files are loaded in alphabetical order by filename. - 在目录中,文件按文件名的字母顺序加载。 Below is a complete list of special file and directory names that control file load order: 以下是控制文件加载顺序的特殊文件和目录名称的完整列表:

lib LIB

After sorting as described above, all files under directories named lib are moved before everything else, preserving their order. 在如上所述排序之后,名为lib的目录下的所有文件都在其他所有文件之前被移动,从而保留它们的顺序。

main.* 主要。*

All files that match main.* are moved after everything else, preserving their order. 所有匹配main。*的文件都会在其他所有文件后移动,并保留其顺序。

I've used this pattern 我用过这种模式

Template.layout.created = function() {
    var jsLibs = [
        'vendors/Flot/jquery.flot.js',
        'vendors/Flot/jquery.flot.pie.js',
        'vendors/Flot/jquery.flot.pie.js',
        'vendors/Flot/jquery.flot.pie.js',
        'vendors/Flot/jquery.flot.pie.js',
        'vendors/Flot/jquery.flot.pie.js',
        'vendors/Flot/jquery.flot.pie.js',
        'vendors/Flot/jquery.flot.pie.js',
        'vendors/Flot/jquery.flot.time.js',
        'vendors/Flot/jquery.flot.stack.js',
        'vendors/Flot/jquery.flot.resize.js',
        'js/flot/jquery.flot.orderBars.js',
        'js/flot/curvedLines.js',
        'js/flot/date.js',
        'js/flot/jquery.flot.spline.js',
        'js/flot/curvedLines.js',

        'vendors/bootstrap/dist/js/bootstrap.min.js',
        'vendors/bootstrap/dist/js/bootstrap.min.js',
        'vendors/fastclick/lib/fastclick.js',
        'vendors/nprogress/nprogress.js',
        'vendors/Chart.js/dist/Chart.min.js',
        'vendors/bernii/gauge.js/dist/gauge.min.js',
        'vendors/bootstrap-progressbar/bootstrap-progressbar.min.js',
        'vendors/iCheck/icheck.min.js',
        'vendors/skycons/skycons.js',
        'js/maps/jquery-jvectormap-2.0.3.min.js',
        'js/moment/moment.min.js',
        'js/datepicker/daterangepicker.js',
        'build/js/custom.min.js',
        'js/maps/jquery-jvectormap-world-mill-en.js',
        'js/maps/jquery-jvectormap-us-aea-en.js',
        'js/maps/gdp-data.js'
    ];

    jsLibs.forEach((lib) => {
        $('head').append(`<script type="text/javascript" src="${lib}">`);
    });
}

Then move all the $(document).ready() calls into Template.layout.onRendered and the click events into Template.layout.events({ 然后将所有$(document).ready()调用移动到Template.layout.onRendered ,并将click事件移动到Template.layout.events({

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM