Django/jQuery:处理模板继承和 JS 文件加载

Posted

技术标签:

【中文标题】Django/jQuery:处理模板继承和 JS 文件加载【英文标题】:Django/jQuery: handling template inheritence and JS files loading 【发布时间】:2015-09-21 01:34:50 【问题描述】:

在 Django 中,如何处理需要等待加载 JS 文件才能真正使用它的事实?

让我们看看这个例子的问题:

base.html

<!DOCTYPE html>
<html>

<head>...</head>
<body>
    % include "content.html" %

    <script src="jquery.js"></script>
    <script src="awesome-script.js"></script>
</body>
</html>

content.html

<script>
    $(document).ready(function()
        ...
    );
</script>

这在逻辑上失败了 ($ is undefined)。我可以在调用脚本之前加载 jQuery,但我试图避免在我的主要内容之前加载 JS 文件,以尽可能快地加载网站。

那么,我该怎么办?谢谢。

【问题讨论】:

我真的不理解您发布的代码。 content.htmlbase.html 有什么关系?如果它提供了% block main-content %,那么显然在加载 jQuery 之前调用了脚本。 是的,当然它之前被调用过(我用一个更明显的例子更新了代码)关键是我们需要在调用 JS 之前加载内容(为了不让页面变慢)但是在调用 content.html 中的脚本之前,我们必须等待所有 JS 加载完毕。 或者如果 jquery 是在内容之前加载的唯一脚本,也许没关系? 你不能清楚地期望 jQuery 脚本在 jQuery 被加载之前被执行。您必须更改脚本顺序。更新了答案。 当然,如果我加载 jquery,然后是我的内容,然后是我的脚本,这会很好。但问题是:在加载我的内容之前加载 BIG javascript 文件是否可以接受?我想这不是一个好习惯,我希望有更好的解决方案,我想我错了:) 【参考方案1】:

扩展 Wtower 的建议 - 让他接受。

我真的会坚持在他的示例中使用基于模板继承的方法。我想为该方法介绍更多元素,以涵盖其他一些常见需求:

<!DOCTYPE html>
<html>
<head>% block scripts-head %% endblock %</head>
<body>
    % block content %% endblock %
    % block scripts %
        <script src="jquery.js"></script>
    % endblock %
    <script>% block script-inline %% endblock %</script>
</body>
</html>

这里有3个想法:

在标题中添加一个占位符,以防您在某些时候需要脚本。不言自明。

在基本文件中包含常用脚本。如果它们很常见,则属于基本文件,您不必在每个模板中重复自己。然而你把它放在块内,所以它可以沿着层次结构被覆盖。

% extends "base.html" %
% block scripts %
     block.super 
    <script src="a-local-lib.js"></script>
% endblock %

关键在于使用 block.super  来引入在父模板中定义的任何脚本。当您的模板中有多个继承级别时,它尤其适用。您可以控制脚本是在继承的脚本之前还是之后。当然,如果您愿意,您可以完全覆盖该块,不包括  block.super 

基本相同的想法,但使用原始 javascript。您可以以同样的方式使用它:每个需要包含一些内联 javascript 的模板都有其 block script-inline ,并且将以 block.super 开头,因此无论父级放入其中的内容仍然包含在内。

例如,我在我的项目中使用 Ember,并且有几个初始化程序来设置项目设置和加载引导数据。我的基础应用加载模板有一个全局项目设置初始化程序,子模板定义本地设置和数据。

【讨论】:

非常感谢,@spectras 让我度过了愉快的一天。 同上。这正是我想要的。【参考方案2】:

由于您的脚本使用 jQuery,您可以简单地使用 jQuery 的 $(document).ready()$(window).load() 函数分别在 DOM 准备好和所有窗口内容已加载的事件上绑定一个函数。

如果你不使用 jQuery,看看这些相关问题,了解如何用纯 JS 模仿上述行为:

pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it Javascript - How to detect if document has loaded

编辑 1:包含顺序很重要。在执行任何需要 jQuery 的脚本之前,您必须包含 jQuery 脚本。

编辑 2:您可以通过将脚本与主要内容分开来更好地组织模板,或者使用第二个模板:

base.html

<!DOCTYPE html>
<html>

<head>...</head>
<body>
    % include "content.html" %
    % include "js.html" %
</body>
</html>

js.html

<script src="jquery.js"></script>
<script src="awesome-script.js"></script>
<script>
    $(document).ready(function()
        ...
    );
</script>

(在这种情况下你渲染base.html

或使用(推荐):

base.html

<!DOCTYPE html>
<html>

<head>...</head>
<body>
    % block content %% endblock %
    % block scripts %% endblock %
</body>
</html>

content.html

% extends 'base.html' %
% block content %
    ...
% endblock %
% block scripts %
    <script src="jquery.js"></script>
    <script src="awesome-script.js"></script>
    <script>
        $(document).ready(function()
            ...
        );
    </script>
% endblock %    

(在这种情况下你渲染content.html

【讨论】:

谢谢。我确实使用了 jQuery,但它尚未加载,因此在调用 $(document) 时未定义“$” 欢迎您,您只需在脚本之前包含 jquery 脚本即可。 已经是这样了。在 base.html 中,加载了 Jquery,然后加载了我的脚本。但是进入我的主要内容时,根本没有加载任何JS(这很正常) “进入主要内容”是什么意思?请张贴包含 jquery 的行。

以上是关于Django/jQuery:处理模板继承和 JS 文件加载的主要内容,如果未能解决你的问题,请参考以下文章

使用 Node.js、Handlebars 和 Express 进行模板继承

加载静态文件,父模板的继承和扩展

加载静态文件,父模板的继承和扩展

加载静态文件,父模板的继承和扩展

加载静态文件,父模板的继承和扩展

加载静态文件,父模板的继承和扩展