Meteor JS:如何使用外部脚本

47

有一些服务(例如类似于FB like或AddThis之类的)提供了一段代码片段。它看起来像是

<div class="service-name" data-something="x"></div>
<script type="text/javascript" src="http://example.com/service-name.js"></script>

好的,很棒,通常情况下你把它粘贴到HTML中就可以了,但Meteor不行。

这是我看到的:

  • <script>在模板/主体内没有加载 - 我在资源中没有看到它,Meteor中的某些东西实际上防止浏览器将其识别为JS文件
  • <head>可以工作

现在有以下问题和疑问:

  1. 我不想从<head>加载它 - 因为速度的原因
  2. 即使我从那里加载它 - 我们有QA和PROD环境。它们必须从不同的域(如service-domain-qa.exampleexample.com)加载此脚本

令人惊讶的是,不能<head>中使用模板助手/变量。

对于传统框架来说这根本不是问题 - 你可以在任何地方包含脚本并且它们只会加载;你可以在你的服务器模板的任何部分使用逻辑/变量。

那么,在Meteor中该怎么做呢? 让我重复一遍:

  • 我需要加载一些外部脚本(托管在第三方域上)到我的应用程序页面中
  • 将此脚本保存到我的项目文件夹中不是一个选项
  • 脚本路径取决于环境(我们已经有了设置系统),因此应该从代码向渲染它的模板传递一些数据的位置

我知道可以通过在Template.created上使用动态脚本加载(使用LAB.js或其他方式)来实现这一点,但是这太过繁琐了...


2
Meteor 1.2-rc.7(以及之前的版本)现在可以执行这些脚本。 - shovavnik
7个回答

25

我的解决方案是使用软件包。详见https://github.com/meteor/meteor/tree/master/packages/spiderable获取更多详情。

Package.describe({
  summary: "External script"
});

Package.on_use(function (api) {
  api.use(['templating'], 'client');

  api.add_files('external_script.html', 'client');
});



<head><script type="text/javascript" src=""//mc.yandex.ru/metrika/watch.js""></script></head>

25
在Meteor中,body或模板中的<script>标签不会被执行,而是由Meteor的模板系统解析和处理。你不能指望它们像普通HTML页面中一样起作用。
解决方法是使用Template事件(在其中可以手动将脚本标签附加到body或其他地方),或者像你所说的那样动态加载它。这并非多余,这正是Meteor的工作方式——请记住,没有传统的HTML页面或body,只有Meteor API,并且Meteor API指定,为了加载和执行外部脚本,必须使用适当的API方法。

35
说到底,它只是在浏览器中的HTML。很奇怪的是,在页面中插入一个脚本标签居然不能“正常工作”。更奇怪的是,你们认为这没问题 :) - Guard
22
因为有一个很好的原因 - Meteor完全为您管理DOM,根据反应性可能重新插入元素或移动事物。因此,仅将脚本放在body中并期望它能够工作是没有意义的;如果模板重新渲染,则会被重新执行并搞乱一切。这就是为什么您可以将其放在head中,并且它会以这种方式工作。或者,Meteor提供了我在答案中描述的替代方案。由你选择这两个选项之一。 - Rahul
1
所以,仅仅将脚本放在主体中并期望它能够工作是没有意义的;如果模板重新渲染,它会被重新执行并且会破坏一切。嗯,我听说过一个关于 {{#constant}} 的传说。 - Guard
15
有没有一个示例可以使用 Template.name.rendered 手动添加脚本标签? - huggie
9
我不明白为什么Meteor不会对未执行的标签发出警告。 - Pat
显示剩余7条评论

11

如果您正在使用IronRouter,您可以使用此软件包来加载外部脚本: https://github.com/DerMambo/wait-on-lib

Router.map( function () {
  this.route('codeEditor',{
    waitOn: IRLibLoader.load('https://some-external.com/javascript.js')
  });
});

1
附注:这需要 wait-on-lib 包(https://atmospherejs.com/manuelschoebel/wait-on-lib) - Ronin

8

1
这很棒,但我该怎么做才能在服务器端实现类似的功能?(使用此方法,我会收到“$ 未定义”的错误提示,我猜测是因为 jQuery 在服务器上不可用。) - Ruben Martinez Jr.
1
添加一个庞大的外部库来实现核心功能是不可行的。 - MattiSG
@RuneJeppesen,他们更改了文档措辞。对于Underscore和其他几个包,它曾经有一个红色警告,大致是“即使该库已被框架包含,您也应选择加入它,因为我们可能会更改它”。 - MattiSG

3
你可以使用类似yepnope这样的工具来异步加载脚本。我使用它来按需加载leaflet。我开始通过yepnope加载更多的脚本,以便在初始页面加载时呈现最少的应用程序内容。我将yepnope的内容放置在Template.created中。

甜蜜的建议!+1 添加 :) - praneybehl
yepnope已被弃用。 - shovavnik

2

我曾使用iframe和公共目录的技巧来嵌入脚本代码。在这种情况下,我是为了谷歌广告代码而这样做的,并将其放在我的主HTML模板中:

<iframe src="/gads.html?v={{{unique}}}" seamless width="160" height="600"
 scrolling="no" frameborder="0" marginheight="0" marginwidth="0"
 style="margin:0;padding:0;border:none;width:160px;height:600px"></iframe>

然后在公共目录中放置一个gads.html文件,并添加我的Google AdWords代码,如下所示:

<html>
<head>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div>
<script type="text/javascript"><!--
google_ad_client = "ca-pub-54*********";
google_ad_slot = "66******";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</body>
</html>

这种方式可以让代码出现在页面上,但远非理想(首先,我认为这违反了谷歌的服务条款)。


1
HTML如何通过<iframe src="/gads.html?v={{{unique}}}">接收您传递的unique参数? - Dan Dascalescu

1
我正在使用METEOR 1.0。我已经将所有外部SCRIPT标签放在布局模板中紧挨着标签之前的一个DIV元素内。Meteor能够无问题地识别它们,并且浏览器会加载它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接