Как поместить JavaScript внизу страниц Django при использовании тегов-шаблонов? - PullRequest
2 голосов
/ 05 ноября 2010

Yahoo Рекомендации по ускорению работы вашего сайта утверждает:

Поместите сценарии внизу

Что существует два типа сценариев вмое приложение Django:

  1. Скрипты, включенные в мой базовый (например, унаследованный) шаблон;и
  2. Сценарии, написанные внутри шаблонов, созданных с помощью templatetags

Сценарии для поддержки элементов управления пользовательского интерфейса обязательно являются частью шаблона для их поддерживающего тега шаблона для обработки таких вещей, как уникальные идентификаторы и для сохранения зависимостикод вместе.

Проблема в том, что, если я последую совету Yahoo и поставлю библиотеки (# 1) внизу страницы, 100% скриптов, включенных в строку (# 2), потерпит неудачу, потому что библиотеки не былизагружен и проанализирован.

Я не могу расширить элемент {% block%} в моем базовом шаблоне, потому что все, что я делаю в контексте тега шаблона, не будет распространяться за его пределы - по замыслу, чтобы избежатьконфликты имен переменных (согласно документации Django).

Кто-нибудь знает, как я могу отложить JavaScript из шаблонов моих шаблонных тегов для отображения в нижней части моего базового шаблона?

Ответы [ 3 ]

3 голосов
/ 21 июня 2011

У меня обычно есть базовая настройка шаблона, подобная этой.

<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 голос
/ 05 ноября 2010

Обернуть сценарии, которые вы включаете, встроенными в

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

, которые будут выполняться, когда DOMготово, и сценарии загружены.

Другой вариант может заключаться в создании какого-либо пользовательского тега шаблона, например:

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

, который можно использовать для объединения встроенных сценариев по мере выполнения.Вам нужно будет агрегировать эти данные, когда ваш шаблон анализируется, что сложно, потому что теги шаблона имеют разные контексты, и это то, что вы хотите сохранить в глобальном контексте в пользовательской переменной, скажем, inline_scripts.

Я бы посмотрел, как Django реализует различные конструкции with ... as .. в библиотеке шаблонов по умолчанию для примера того, как добавить свою собственную переменную в контекст.

Затем внизувашей страницы вы можете сделать {{inline_scripts}}.

Самое простое решение - это jQuery.ready(function(){}) / jQuery(function(){ }) (два метода являются синонимами).

Или вы можете пересмотреть рекомендации Yahoo.Есть положительные моменты в вставке вашего javascript - это может уменьшить FOUC / FOUBC (флэш-память необработанного контента).Yahoo имеет тенденцию становиться педантичным - (просто посмотрите на API YUI;).Если вам нужно переписать части вашего приложения для улучшения производительности, которое может быть умеренно ощутимым, оно может не стоить.


Выполнение агрегации сценариев (изначально основанной на перехватах на 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 }}
0 голосов
/ 29 сентября 2014

Существует приложение django-sekizai только для этого

...