Node.js with Express:在 Jade 视图中使用脚本标签导入客户端 javascript?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5605392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node.js with Express: Importing client-side javascript using script tags in Jade views?
提问by Tom
I've got a node.js express server running with the Jade template engine.
我有一个运行 Jade 模板引擎的 node.js express 服务器。
I've got a layout jade file which imports the body of individual views like so:
我有一个布局 jade 文件,它导入单个视图的主体,如下所示:
!!!
html
head
title= title || 'Title not set.'
body
#header
h1 Header.
#content!= body //- this renders the body of an individual view
#footer
p Footer.
For example, the following index page:
例如,以下索引页面:
p Welcome to the front page.
p This page serves as a now.js test.
This works fine. However, I now want to include two client-side javascript libraries specifically for this index page (and thus not very every page, which is why I cannot put it in the head of layout).
这工作正常。但是,我现在想要包含两个专门用于此索引页面的客户端 javascript 库(因此不是每个页面,这就是为什么我不能将它放在布局的头部)。
This works:
这有效:
//- import jquery
script(type='text/javascript', src='./jquery-1.5.2.min.js');
//- import now.js (hosts itself)
script(type='text/javascript', src='/nowjs/now.js')
//- import the chat client
script(type='text/javascript', src='./indexChatClient.js')
p Welcome to the front page.
p This page serves as a now.js test.
However, this loads the scripts to the body of the complete page, which is not valid HTML, right?
但是,这会将脚本加载到整个页面的正文中,这不是有效的 HTML,对吗?
As far as I know, the scripts should be loaded into the head if I want to do it properly, but the head section is handled by the layout file.
据我所知,如果我想正确地将脚本加载到头部,但头部部分由布局文件处理。
So, how would I properly include these client-side javascript libraries specifically for a certain view/page?
那么,我将如何正确地包含这些专门用于某个视图/页面的客户端 javascript 库?
采纳答案by BFil
I've done the same using the solution from this thread:
我使用这个线程中的解决方案做了同样的事情:
http://groups.google.com/group/express-js/browse_thread/thread/8c2006dc7bab37b1/f9a273c836e0a2ac
http://groups.google.com/group/express-js/browse_thread/thread/8c2006dc7bab37b1/f9a273c836e0a2ac
You can declare a "scripts" variable into view options:
您可以在视图选项中声明一个“脚本”变量:
app.js:
应用程序.js:
app.set('view options', { locals: { scripts: ['jquery.js'] } }); // You can declare the scripts that you will need to render in EVERY page
Than you can have an helper that renders the script tags into the head of the layout
比您可以有一个助手将脚本标签呈现到布局的头部
renderScriptTags() Helper code:
renderScriptTags() 帮助代码:
app.helpers({ renderScriptTags: function(scripts) {
return scripts.map(function(script) {
return '<script src="scripts/' + script + '"></script>';
}).join('\n ');
Into the layout template in the head section you will have:
进入 head 部分的布局模板,您将拥有:
- renderScriptTags(scripts)
Now, to add a script on the head tag, you'll just need to push the script into the "scripts" variable on your jade content template (body template):
现在,要在 head 标签上添加脚本,您只需将脚本推送到您的 jade 内容模板(主体模板)上的“脚本”变量中:
- scripts.push('myscript.js');
In this way the page will render jquery.js and myscript.js into the head of the page
这样页面就会将 jquery.js 和 myscript.js 渲染到页面的头部
UPDATE
更新
It seems that newest express version handles the locals in a different way, to make this work properly, you can do this (I'm not sure it is the optimal solution though, I'd need to dig this a little)
似乎最新的快递版本以不同的方式处理当地人,为了使其正常工作,您可以这样做(虽然我不确定这是最佳解决方案,但我需要稍微挖掘一下)
You can use the renderScriptTags()helper of the previous method in your layout template like before.
您可以像以前一样在布局模板中使用上一个方法的renderScriptTags()助手。
But don't set the scripts variables into locals, instead create a dynamic helper that will make a scriptsvariable available in our templates:
但是不要将脚本变量设置为本地变量,而是创建一个动态助手,使脚本变量在我们的模板中可用:
app.dynamicHelpers({
scripts: function(req, res){
return ['jquery.js']; //this will be available in all views
}
});
And then, to add a specific script, from your body template (exactly as before):
然后,从您的正文模板中添加特定脚本(与以前完全一样):
- scripts.push('myscript.js');
Now, for this specific view, you should have jquery.js and myscript.js rendered properly
现在,对于此特定视图,您应该正确呈现 jquery.js 和 myscript.js
回答by masylum
You can have them on the layout and specify which libraries to load on the "controllers".
您可以将它们放在布局上并指定要在“控制器”上加载哪些库。
// layout.jade
!!!
html
head
title= title || 'Title not set.'
-each script in scripts
script(type='text/javascript', src= script)
body
#header
h1 Header.
#content!= body //- this renders the body of an individual view
#footer
p Footer.
And your "controller":
还有你的“控制器”:
// app.js
app.get('/', function (req, res) {
res.render({
scripts: ['jquery.min.js', '/nowjs/now.js']
}
}
回答by Gilead
It's possible to do it The Right Way (tm) in the latest Jade (0.28.1) by keeping it all inside templates/views, without hacking page contents (script links) elsewhere:
在最新的 Jade (0.28.1) 中,通过将其全部保存在模板/视图中,而不在其他地方破解页面内容(脚本链接),可以在最新的 Jade (0.28.1) 中做到这一点:
- Declare the head as a named block in your template:
- 在模板中将头部声明为命名块:
doctype 5 html head // named block allows us to append custom head entries in each page block head title= title link( rel='stylesheet', href='/css/style.css' ) script( type="text/javascript", src="/js/some-default-script.js" ) body block content
- Append your page-specific head elements (including script tags) in your views:
- 在视图中附加页面特定的头部元素(包括脚本标签):
extends layout // here we reference the template head and append to it block append head meta( name="something", content="blah" ) link( href="/css/another.css", rel="stylesheet", type="text/css" ) style div.foo { position: absolute; } script( src="/js/page-specific-script.js" ) block content #page-contents-follows
回答by tjholowaychuk
I assume the problem (from briefly reading this) is that you are not "flushing" the array, setting its .length to 0 to remove old values, so each request could just be pushing more and more strings
我认为问题(从简要阅读本文)是您没有“刷新”数组,将其 .length 设置为 0 以删除旧值,因此每个请求可能只是推送越来越多的字符串
回答by jhoff
Here is an alternate way to do it ( using ShadowCloud's answer ). By generalizing a bit, you can specify both local and remote scripts, and then defer them until after page load:
这是一种替代方法(使用 ShadowCloud 的答案)。通过稍微概括一下,您可以指定本地和远程脚本,然后将它们推迟到页面加载之后:
app.js:
应用程序.js:
app.dynamicHelpers({
scripts: function() {
//scripts to load on every page
return ['js/jquery.min.js','js/jquery-ui.min.js','js/all.js'];
}
});
then, you can add local or remote scripts at any point inside a view
然后,您可以在视图内的任何点添加本地或远程脚本
//- local script
- scripts.push('js/myPage.js');
//- remote script ( note: this is a schemeless url. You can use http(s)? ones too )
- scripts.push('//platform.twitter.com/widgets.js')
layout.jade: ( I put it at the end of body to load the visible stuff first, but it can go anywhere really )
layout.jade:(我把它放在 body 的最后是为了先加载可见的东西,但它真的可以去任何地方)
//- Bring the scripts into a client-side array,
//- and attach them to the DOM one by one on page load
script
var page_scripts = !{'["' + scripts.join('","') + '"]'};
function loadJS() {
for(var i in page_scripts) {
var e = document.createElement("script");
e.src = page_scripts[i];
document.body.appendChild(e);
}
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", loadJS, false);
else if (window.attachEvent)
window.attachEvent("onload", loadJS);
else window.onload = loadJS;
回答by Stephen Collins
I'm not sure what the point of the approaches so far are. To me it is much cleaner to do the following...
我不确定到目前为止这些方法的重点是什么。对我来说,执行以下操作要干净得多......
layout.jade:
layout.jade:
doctype html
html
head
title= title
block headscripts // placeholder for scripts that need to be in the <head>
link(rel='stylesheet', href='/styles/style.css')
block styles // placeholder for styles
body
block content
script(src='/libs/jquery/dist/jquery.min.js') // this will render before all scripts in every page
block scripts // placeholder for scripts that go in the body
somepage.jade:
somepage.jade:
extends layout
block styles // this will render in the <head>
link(rel='stylesheet', href='/styles/films.css')
link(rel='stylesheet', href='/styles/pagination.css')
block headscripts // this will also render in the <head>
script(src='/js/somescript.js')
block content
h1= title
div.someotherstuff
block scripts // this will render at the end of the body
script(src='/js/libs/someotherscript.js')
scirpt(src='/libs/doT/doT.js')
This way it doesn't matter where in your .jade
pages you put your blocks, they will always render in the correct places.
这样,您在.jade
页面中放置块的位置无关紧要,它们将始终呈现在正确的位置。