Неправильно ли размещать тег <script> после тега </ body>?

219

Насколько неправильно размещать тег script после закрывающего тега body ( </body>). ?

<html>
  ....
  <body>
     ....
  </body>
  <script type="text/javascript" src="theJs.js"></script>
</html>
DanC
источник
1
Есть ли поддержка для этого в современных браузерах.
Xdrone

Ответы:

191

Он не будет проверен вне тегов <body>or <head>. Это также не будет иметь большого значения - если вы не выполняете DOM-манипуляции, которые могут сломать IE до полной загрузки элемента body, - чтобы поместить его непосредственно перед закрытием </body>.

<html>
  ....
  <body>
     ....
     <script type="text/javascript" src="theJs.js"></script>
  </body>
</html>
Энди Э
источник
13
@epalla: если вы поместите скрипт прямо в конец тега body, то к тому времени, когда он туда попадет, не останется никакого другого контента для загрузки, поэтому не должно быть большой разницы между размещением его снаружи или только внутри. Затем вы получаете дополнительное преимущество от проверки своей страницы, о чем я и хотел сказать в своем ответе.
Энди Э
1
Да, я был согласен с вами, так как ваш ответ хороший. Я просто хотел добавить, что есть причина для размещения JS внизу страницы, а не в голове, как мы это делали в течение долгого времени.
Мэтт Брунмайер
3
@PHPst: неправильный код может вызывать побочные эффекты в некоторых браузерах. В любом случае, я не вижу, как его отступ на одну ширину табуляции меньше, чем в приведенном выше коде, делает его более чистым.
Энди Э
1
@PHPst: Я ожидаю, что браузеры справятся с этим, если вы действительно хотите писать свой код таким образом. Однако я бы порекомендовал написать ваш код для проверки.
Энди Э
1
@technosaurus: всегда есть <script src="..." defer>, который работает во всех основных браузерах (хотя с потенциально опасной ошибкой в ​​IE9 и ниже).
Энди Э,
89

Да. Только комментарии и конечный тег для элемента html допускаются после конечного тега для тела.

Браузеры могут выполнять восстановление после ошибок, но вы никогда не должны зависеть от этого.

Quentin
источник
12
Это лучший ответ. Слишком много новых браузеров с мобильными устройствами вступают в игру, чтобы рисковать делать это неправильно, когда все, что вам нужно, это вырезать и вставить один закрывающий тег.
Эрик Реппен
33

Как сказал Энди, документ будет недействительным, но, тем не менее, сценарий все равно будет интерпретирован. Смотрите фрагмент из WebKit, например:

void HTMLParser::processCloseTag(Token* t)
{
    // Support for really broken html.
    // we never close the body tag, since some stupid web pages close it before 
    // the actual end of the doc.
    // let's rely on the end() call to close things.
    if (t->tagName == htmlTag || t->tagName == bodyTag 
                              || t->tagName == commentAtom)
        return;
    ...
Виталий Федоренко
источник
11
«Поддержка действительно сломанного HTML.» - Думаю, этим все сказано.
Диого Коллросс
8

IE больше не позволяет этого (начиная с версии 10, я полагаю) и будет игнорировать такие сценарии. FF и Chrome все еще терпят их, но есть вероятность, что когда-нибудь они откажутся от этого как от нестандартного.

Бронкс
источник
1
И все же Google делает это в своем примере того, как выполнить вход в G +, с «последним обновлением 10 апреля 2014 года». Я получил его из версии для Java на сервере ( developers.google.com/+/quickstart/java ), но, вероятно, это один и тот же HTML + js для всех.
Том
2

Процедурно вставить «скрипт элемента» после того, как «тело элемента» является «ошибкой синтаксического анализа» по рекомендованному W3C процессу . В «Tree Construction» создайте ошибку и запустите «tokenize again» для обработки этого содержимого. Так что это как дополнительный шаг. Только тогда может быть запущено «Выполнение скрипта» - см. Схему процесса .

Все остальное "ошибка разбора". Переключите «режим вставки» на «в теле» и повторно обработайте токен.

Технически в браузере это внутренний процесс, как они маркируют и оптимизируют его.

Я надеюсь, что я кому-то помог.

Б.Г. Бруно
источник
0

Да. Но если вы добавите код за его пределы, скорее всего, это не конец света, так как большинство браузеров исправят его, но все равно это плохая практика.

Тейлор Сатула
источник
0

Google фактически рекомендует это в отношении «CSS Optimization». Они рекомендуют встраивать критические стили выше сгиба и откладывать остальное (файл CSS).

Пример:

<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>

См .: https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery.

Дональд Портер
источник
8
Вы не должны помещать вещи вне bodyэлемента. Эта статья Google никому не советует делать подобные вещи.
ChaseMoskal
2
Я боюсь, что страница Google говорит на самом деле просто точно.
10
6
Похоже , что в свое время, что страница сделала рекомендовать такую вещь, но не больше. (Теперь есть некоторая динамическая загрузка с помощью javascript.) Немецкая версия не устарела и все еще содержит старый пример кода.
Бодо
1
«элемент noscript» должен быть в RFC внутри «element html» и «body элемента» тоже
BG Bruno
0

Современные браузеры принимают теги сценариев в теле следующим образом:

<body>
    <script src="scripts/main.js"></script>
</body>

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

<head>
    <script src="scripts/main.js" defer></script>
</head>
Рекламная благотворительность
источник
Что было бы полезно, если бы у scriptтегов был eventатрибут, который можно было бы определить, чтобы определить, когда анализировать скрипт. Таким образом, у вас есть event="load" event="DOMContentLoaded"для запуска сценария после создания DOM или event="beforeunload"по beforeunloadсобытию окна . Пример <script src="scripts/main.js" event="DOMContentLoaded"></script>.
1,21 гигаватт