使用templatetags时如何将JavaScript放在Django页面的底部?

时间:2010-11-04 21:12:54

标签: javascript django templatetags

雅虎的Best Practices for Speeding Up Your Website州:

  

将脚本放在底部

我的Django应用程序中有两种类型的脚本:

  1. 我的基础(例如继承)模板中包含的脚本;和
  2. 在templatetags实例化的模板内编写的脚本
  3. 支持UI控件的脚本必然是模板的一部分,用于支持模板标记处理诸如唯一ID之类的内容并将相关代码保持在一起。

    问题在于,如果我遵循雅虎的建议并将库(#1)放在页面底部,则内联(#2)中包含的100%脚本将会失败,因为尚未加载和解析库爱好。

    我无法在我的基本模板中扩展{%block%}元素,因为我在templatetag的上下文中做的任何事情都不会传播到它之外 - 设计,以避免变量名称冲突(根据Django的文档) )。

    有没有人知道如何将我的模板标签模板中的JavaScript推迟到我的基本模板底部进行渲染?

3 个答案:

答案 0 :(得分:3)

我通常有这样的基本模板设置。

<html>
<head>

{% block js-head %} Tags that need to go up top  {% endblock js-head %}

</head>
<body>
{% block header %}  Header {% endblock header %}

{% block body %} Body goes here {% endblock body %}

{% block footer %}  Footer {% endblock footer %}

{% block js-foot %}  All other javascript goes here {% endblock js-foot %}
</body>
</html>

然后我可以扩展这个基本模板,只覆盖我关心的块。我把所有不必要的javascript放在js-foot的标题中,因为它位于模板的底部,它将最后加载。如果你必须移动你的javascript加载你只需要在基本模板中移动js-foot块。

没什么特别的,但它确实有效。

答案 1 :(得分:1)

将您内嵌的脚本包裹在

  

jQuery(function(){...});

当DOM准备好并且下载了脚本时,将执行该操作。

另一种选择可能是创建某种自定义模板标记,如:

{% inlinescript %}
// some javascript code.
{% endinlinescript %}

随着执行的进行,您可以使用它来聚合内联脚本。您需要在解析模板时聚合此数据 - 这会变得棘手,因为模板标记具有不同的上下文,这是您希望在自定义变量中存储在全局上下文中的内容,比如inline_scripts

我将看看Django在默认模板库中实现各种with ... as ..构造的方式,以获取如何将自己的变量添加到上下文的示例。

然后在页面底部,您可以{{inline_scripts}}。

最简单的解决方案是jQuery.ready(function(){}) / jQuery(function(){ })(这两种方法是同义的)。

或者您可能想重新考虑雅虎的建议。关于内联你的javascript有积极的一面 - 它可以减少FOUC / FOUBC(不受欢迎的内容的Flash)。雅虎往往会变得有点迂腐 - (只需看看YUI API;)。如果您需要重写部分应用程序以获得适度可感知的性能改进,那么可能不值得。


进行脚本聚合(最初基于django-snippets上的captureas):

@register.tag(name='aggregate')
def do_aggregate(parser, token):
    try:
        tag_name, args = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError("'aggregate' node requires a variable name.")
    nodelist = parser.parse(('endaggregate',))
    parser.delete_first_token()
    return AggregateNode(nodelist, args)

class AggregateNode(Node):
    def __init__(self, nodelist, varname):
        self.nodelist = nodelist
        self.varname = varname

    def render(self, context):
        output = self.nodelist.render(context)
        if context.has_key(self.varname):
            context[self.varname] += output
        else:
            context[self.varname] = output
        return ''

用法:

{% aggregate inline_scripts %}
var foo = 'bar';
{% endaggregate %}

... template code

{% aggregate inline_scripts %}
var baz = 'bar';
{% endaggregate %}

... somewhere near the bottom of your page

{{ inline_scripts }}

答案 2 :(得分:0)

只有

的应用程序django-sekizai