使用Express的Node.js:在Jade视图中使用脚本标记导入客户端JavaScript?

我有一个运行Jade模板引擎的node.js express服务器。

我有一个布局的翡翠文件,导入个人意见的正文像这样:

!!! html head title= title || 'Title not set.' body #header h1 Header. #content!= body //- this renders the body of an individual view #footer p Footer. 

例如,下面的索引页面:

 p Welcome to the front page. p This page serves as a now.js test. 

这工作正常。 不过,我现在想包含两个客户端JavaScript库专门为此索引页(因此不是每个页面,这就是为什么我不能把它放在布局的头)。

这工作:

 //- 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. 

但是,这将脚本加载到完整页面的主体,这是不正确的HTML,对不对?

据我所知,脚本应该加载到头部,如果我想正确地做,但头部由布局文件处理。

那么,我将如何正确地将这些客户端JavaScript库专门包含在某个视图/页面中呢?

我使用这个线程的解决scheme做了同样的事情:

http://groups.google.com/group/express-js/browse_thread/thread/8c2006dc7bab37b1/f9a273c836e0a2ac

您可以将“脚本”variables声明为视图选项:

app.js:

 app.set('view options', { locals: { scripts: ['jquery.js'] } }); // You can declare the scripts that you will need to render in EVERY page 

比你可以有一个助手,将脚本标签呈现在布局的头部

renderScriptTags()助手代码:

 app.helpers({ renderScriptTags: function(scripts) { return scripts.map(function(script) { return '<script src="scripts/' + script + '"></script>'; }).join('\n '); 

进入头部的布局模板,您将拥有:

 - renderScriptTags(scripts) 

现在,要在head标签上添加一个脚本,您只需将脚本推送到您的jade内容模板(正文模板)上的“scripts”variables中:

 - scripts.push('myscript.js'); 

通过这种方式,页面将呈现jquery.js和myscript.js到页面的头部

UPDATE

看起来,最新的快递版本以不同的方式处理当地人,为了使这个工作正常,你可以做到这一点(我不知道这是最佳的解决scheme,但我需要挖掘一点)

您可以像以前一样在布局模板中使用前一个方法的renderScriptTags()助手。

但是不要将脚本variables设置为locals,而应该创build一个dynamic助手来使脚本variables在我们的模板中可用:

 app.dynamicHelpers({ scripts: function(req, res){ return ['jquery.js']; //this will be available in all views } }); 

然后,从你的body模板中添加一个特定的脚本(和以前一样):

 - scripts.push('myscript.js'); 

现在,对于这个特定的视图,你应该正确地呈现jquery.js和myscript.js

您可以在布局上指定它们,并指定在“控制器”上加载哪些库。

 // 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. 

而你的“控制器”:

 // app.js app.get('/', function (req, res) { res.render({ scripts: ['jquery.min.js', '/nowjs/now.js'] } } 

可以在最新的Jade(0.28.1)中使用正确的方法(tm),方法是将其全部保存在模板/视图中,而不会在其他地方篡改页面内容(脚本链接):

  • 将头部声明为模板中的命名块:
文档types5
 HTML
  头
     //命名的块允许我们在每个页面附加自定义头条目
    块头
         title = title
        链接(rel ='stylesheet',href ='/ css / style.css')
         script(type =“text / javascript”,src =“/ js / some-default-script.js”)
  身体
    阻止内容
  • 在您的视图中追加您的页面特定的头元素(包括脚本标签):
扩展布局

 //这里我们引用模板头并追加到它
块附加头
     meta(name =“something”,content =“blah”)
     link(href =“/ css / another.css”,rel =“stylesheet”,type =“text / css”)
    样式
         div.foo {
            位置:绝对;
         }
    脚本(src =“/ js / page-specific-script.js”)

阻止内容
     #页面内容,如下

我认为这个问题(从简单的读这个)是你不是“冲洗”数组,设置其长度为0删除旧的值,所以每个请求可能只是推动越来越多的string

这是一个替代方法(使用ShadowCloud的答案)。 通过概括一下,您可以指定本地脚本和远程脚本,然后将它们推迟到页面加载之后:

app.js:

 app.dynamicHelpers({ scripts: function() { //scripts to load on every page return ['js/jquery.min.js','js/jquery-ui.min.js','js/all.js']; } }); 

那么,您可以在视图内的任意位置添加本地或远程脚本

 //- 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:(我把它放在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; 

我不确定到目前为止的方法是什么。 对我来说,做下面的事情要干净得多。

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:

 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') 

这样,放置块的.jade页面中的任何位置都无关紧要,它们将始终呈现在正确的位置。