繁体   English   中英

Node.js with Express:在Jade视图中使用脚本标签导入客户端javascript?

[英]Node.js with Express: Importing client-side javascript using script tags in Jade views?

我有一个运行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,对吧?

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

那么,我如何正确地包含这些客户端javascript库专门用于某个视图/页面?

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

// 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']
  }
}

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

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

您可以在视图选项中声明“脚本”变量:

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

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

- renderScriptTags(scripts)

现在,要在head标记上添加脚本,您只需将脚本推送到jade内容模板(body模板)上的“scripts”变量中:

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

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

UPDATE

似乎最新的快递版本以不同的方式处理本地人,为了使这项工作正常,你可以这样做(我不确定它是最佳的解决方案,但我需要稍微挖掘一下)

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

但是不要将脚本变量设置为本地,而是创建一个动态帮助器,使我们的模板中的脚本变量可用:

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

然后,从您的身体模板添加特定脚本(与之前完全一样):

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

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

通过将所有内容保存在模板/视图中,可以在最新的Jade(0.28.1)中执行正确的方法(tm),而无需在其他地方黑客页面内容(脚本链接):

  • 将头部声明为模板中的命名块:
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
  • 在视图中附加特定于页面的头元素(包括脚本标记):
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

我假设问题(从简要阅读这个)是你没有“刷新”数组,将其.length设置为0以删除旧值,因此每个请求可能只是推动越来越多的字符串

这是另一种方法(使用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页面中放置块的位置并不重要,它们总是在正确的位置渲染。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM