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

7gyucuyw  于 2022-10-22  发布在  Java
关注(0)|答案(4)|浏览(123)

雅虎的Best Practices for Speeding Up Your Website声明:
将脚本放在底部
我的Django应用程序中有两种类型的脚本:
1.我的基本(例如继承的)模板中包含的脚本;和
1.在templatetags示例化的模板中编写的脚本
支持UI控件的脚本必须是模板的一部分,因为它们支持模板标记来处理诸如唯一ID之类的东西,并将依赖代码保持在一起。
问题是,如果我按照雅虎的建议,将库(#1)放在页面底部,则包含的所有脚本(#2)都将失败,因为库尚未加载和解析。
我不能在我的基本模板中扩展{%block%}元素,因为我在templatetag上下文中所做的任何事情都不会传播到它之外,这是为了避免变量名冲突(根据Django的文档)。
有人知道我如何将JavaScript从templatetags的模板延迟到基本模板的底部吗?

tvz2xvvm

tvz2xvvm1#

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

<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脚块即可。
没什么特别的,但它很管用。

kyvafyod

kyvafyod2#

Package 内联包含的脚本
jQuery(函数(){…});
它将在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片段上的字幕):

@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 }}
dly7yett

dly7yett3#

有一个应用程序django-sekizai就是为了这个

xzv2uavs

xzv2uavs4#

这对我很管用,等dom加载。。。

<script>
document.addEventListener("DOMContentLoaded", function (event) {
   {% if my_var %}
      doSomething({{myVar}});
   {% endif %}
});
</script>

相关问题