如何在添加脚本标记之前等待DOM加载?

时间:2013-10-06 05:59:46

标签: javascript jquery dom meteor

我正在将这个来自themeforest的Developr theme实现为Meteor app。

我目前正在通过将javascripts置于/public并使用jQuery追加它们来实现这一目标:

Meteor.startup(function() {
  $('head').append('<script src="/template_stuff.js"></script>');
  // .. all 7 scripts or so
});

如果所需脚本放在/client/js/中,则表明它们要么运行得太早,要么在加载完DOM之前运行。如果它们直接放在主html文件的标题中,它们似乎会以同样的方式出错。

我在这里遗漏了什么 - 在DOM加载后是否有一种更优雅的方式来加载脚本?

3 个答案:

答案 0 :(得分:1)

有几种方法可以等到DOM加载后才能注入脚本:

  • Meteor.startup(如图所示)
  • jQuery的文档准备就绪:$(function () { ... })
  • 布局模板底部的脚本标记

关于优雅,我使用了一个把手助手,因为它允许我在一个地方合并所有“后身”代码。然后根据需要使用jQuery的文档。

例如,

// in client/handlebars.js

Handlebars.registerHelper('afterBody', function(name, options) {

  function isMobileSafari() {
    return navigator.userAgent.match(/(iPod|iPhone|iPad)/) &&
           navigator.userAgent.match(/AppleWebKit/)
  }

  if (isMobileSafari()) {
    $(function () {
      FastClick.attach(document.body)
    })
  }

  //// load scripts however you want...
  // $(function () {
  //   $.getScript as Daniel suggests
  //   $('body').append as you have
  //   pure js: document.createElement('script')
  // })

})


// in client/main.html (using mini-pages router)

<template name="layout_no_header">
  {{{yield}}}

  {{afterBody}}
</template>

<template name="layout">
  {{> header}}

  {{{yield}}}

  {{afterBody}}
</template>

答案 1 :(得分:0)

使用jQuery getScript()

(function ($) {
    $.getScript("/template_stuff.js");
})(jQuery);

答案 2 :(得分:0)

我想你可能会遇到不同的问题。听起来第三方代码被包装在一个闭包中并且无法正常工作。尝试将它们放在client/compatibility文件夹中。这将防止它被包裹在一个闭包中,这可以解决第三方问题。确保此处的加载顺序正确,它在文件夹内按字母顺序加载文件。 (load order

如果这不起作用,找出代码执行的位置并注释掉调用。然后将html加载到模板中,即使它只是一个包含所有html的“页面”模板。为模板创建一个js文件,并在模板渲染的回调中调用方法。

// Execute this function when myPage template is rendered
Template.myPage.rendered = function() {
  stuff.init();
  stuff2.run();
};

注意,要调用stuff2等,您可能需要在兼容性文件夹中包含该脚本,以便从template_stuff.js访问命名空间。