在Chrome内容脚本中使用模板的建议方法是什么?

时间:2013-01-10 03:06:22

标签: javascript google-chrome google-chrome-extension

我在Chrome内容脚本中使用了几个模板elements我正在添加到匹配的网页。

目前我将这些模板存储为脚本中的string,但我想知道是否有更好的方法可以做到这一点。

1 个答案:

答案 0 :(得分:3)

tl;博士回答 - 是的,您可以将它们存储在<script type="text/html">标记中,也可以通过ajax动态加载它们。示例here(来自KnockoutJS)和here。将它们存储在具有适当扩展名的文件中,并使用ID为X的空标记,然后$("#X").load("/path/to/template", function() { renderX(); })

通过富有洞察力的想法回答很长的问题,继续阅读...

请确保您系统的模板/视图或相关GUI组件位于单独的文件中(继续阅读以了解原因)

作为一名前端工程师,我学会了尽可能地分层;这有助于您的团队更好地理解您的代码并使其更易于维护。在模块中分离您的图层,然后通过&#34;组装&#34;机制可能是软件工程中的最佳实践之一。这种做法的一些好处包括:

  • 可维护性:多个开发人员可以浏览和编辑代码的单个部分,以便创建更强大的软件。
  • 可读性:根据周围的语言数量,您不能指望每个人都能理解这些X或Y语言的所有语法;在单个文件中混合语言只是让代码审阅者感到困惑的一步,并使他花费的时间超过了所需的时间。
  • 辅助功能:例如,html,jade,haml,smarty,twig,erb或其他模板文件。这些文件应始终使用适当的扩展名命名,以帮助编辑代码和IDE语法高亮显示。开发人员只需要浏览一个文件夹就可以知道这些文件应该做什么。脚本或机器人只能通过扩展程序提供重要信息。

通过将视图保存在单独的文件中,其他编码人员可以查看它们并理解系统的重要层,而无需了解整个应用程序;当开发人员只需要查看这些特定文件时,甚至协作也会变得更容易。通过抨击或编写脚本,甚至是拥有数千个视图的大型建筑系统。可以过滤类似文件,以便输出需要审核的内容。

(现在我希望我说服你从你的代码中删除你的字符串并在那里创建一个新文件,否则我真的需要提高我的写作技巧)

因此,在我们将模板移至外部文件后,我们接下来要做什么?

关于Javascript和Chrome扩展程序的一句话

Javascript没有默认的模板功能(哎呀,它甚至没有模块化功能,虽然有些聪明的人正在研究ECMAScript Ed.6,yay!),这意味着我们需要使用模板库。让我们假设你正在使用相似的东西的Mustache,Underscore模板,从而使用它的库来渲染它。

这些模板引擎中的大多数都使用了臭名昭着的eval,它可以为您的代码提供一个漏洞,Chrome扩展程序不喜欢这个漏洞。 Chrome扩展程序开发团队甚至强制执行manifest.json文件的新版本以禁止eval,并允许开发人员选择使用Sandboxing Pages来执行此操作。对我们来说幸运的是,他们决定放松一些政策,我们可以继续使用manifest.json中适当的CSP定义。

这意味着我们需要解决两个问题,而不仅仅是一个问题:&#34;加载模板&#34;一个和#34;以一种方式渲染模板,如果Chrome扩展开发团队改变了他们的想法,将会使CSP的新传入版本变得惊慌失措。

加载模板

加载模板,幸运的是,可以通过AJAX通过XML HTTP请求来完成。只需将url指向文件名,您就可以将该模板作为字符串接收,这可能是您原来的设置。这是我用KnokcoutJS做的一个例子:

 $("#aiesecTemplate").load('js/libs/aiesec/aiesecTemplate.html', function() {
      ko.applyBindings(AIESECViewModel);
 });

#aiesecTemplate<script type="text/html">标记,浏览器不会将其作为DOM的一部分呈现。您可以将其与其他模板机制一起使用,以便实际组装您的DOM。如果您已经有了解决方案,这可能就是答案的结束,您可以继续生活。如果您想知道我们如何从那里渲染代码,请继续阅读。

渲染模板

Chrome Dev团队建议我们使用Sandbox渲染过程,因为大多数模板引擎库都不符合CSP(AngularJS是个例外)。这里是Sandbox页面代码的摘录。

iframe.contentWindow.postMessage(message, '*');

其中iframe是沙箱页面中的特定DOM Iframe元素,其页面的src属性具有模板引擎; message之前已加载了字符串模板,因此在发布消息后,iframe内的window.addEventListener message可以呈现它而不会出现问题。有关沙盒评估的更多信息,请参阅here

结论

如果你到了这里,真棒!我的答案可能不那么无聊。作为最后一点,您可能会想到&#34; AMD或RequireJS怎么样?&#34 ;;说实话,我还没有尝试过,但是really smart people认为AMD并不是最好的方法。通过XML HTTP请求加载可能不会更好,但如果您认为它会影响您的性能(我已在我的应用程序中使用它并且它没有),您可以始终使用一些Event Pages 和{{3用那个。