可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've got a template that I downloaded:
http://halibegic.com/projects/merlin/
I want to use it in Meteor and I'm having major issues with
<script src="assets/js/script.js"></script>
at the bottom on line 444 not loading in the right order. When the page loads, none of the 4 functions specified in this js file work.
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. They are not in the lib
directory which loads before everything else.
I think it's because the script is somehow loading before the DOM is loaded, so it has no DOM to apply things to.
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.
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.
回答1:
All you need to do is to load the javascript after the template is rendered.
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. You could run them in the promise of $getScript as well. This is your case:
$.getScript('assets/js/script.js', function() {
initNavbar();
initPortfolio();
initAnimations();
initTwitterFeed();
$(".loader .fading-line").fadeOut();
$(".loader").fadeOut("slow");
});
回答2:
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.
回答3:
Thanks to imslavko for the answer!
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.
So I put this into my client/views/application/layout.js. It uses the jQuery $.getScript, so you have to make sure that jQuery is loaded before you try this:
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.
回答4:
It's clear from here: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. 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
After sorting as described above, all files under directories named lib are moved before everything else, preserving their order.
main.*
All files that match main.* are moved after everything else, preserving their order.
回答5:
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({