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.html
与 base.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 文件加载的主要内容,如果未能解决你的问题,请参考以下文章