Статьи

Ссылки в новом окне в мире, соответствующем стандартам

К большому огорчению веб-дизайнеров повсюду, рекомендации W3C по HTML 4.0 Strict и XHTML 1.0 Strict больше не включают атрибут target тега <a> . Переходные версии спецификаций все еще включают его, но по определению эти спецификации находятся на выходе.

Каковы бы ни были ваши личные ощущения на практике, наиболее распространенное приложение для этого атрибута — открытие ссылки в новом окне браузера с target="_blank" — все еще полезно в современном Интернете. Так что, если стандарты говорят, что мы не должны его использовать, как нам следует создавать ссылки в новом окне, следуя последним веб-стандартам?

Прикладной идеализм

Веб-стандарты написаны с учетом множества идеалов. Во многих случаях устоявшаяся практика отходит на второй план в пользу «правильного поведения». Один из идеалов, который выражается в удалении атрибута target из строгих стандартов, заключается в том, что (X) HTML должен касаться только информации, отображаемой в окне браузера.

Следовательно, как только мы начинаем говорить об открытии новых окон браузера, идеалистическим понятием является то, что мы превысили обязанности (X) HTML и вошли в мир сценариев на стороне клиента (то есть JavaScript).

Но прежде чем мы углубимся в код JavaScript, необходимый для открытия ссылки в новом окне браузера, нам еще предстоит решить фундаментальную проблему. Нам все еще нужен способ пометить ссылки, которые должны быть открыты в новом окне, и если мы не можем использовать для этого атрибут target , нам нужно найти какой-то другой способ — способ, который соответствует идеалам, стоящим за последними ( X) стандарты HTML.

Новые отношения

Спецификация HTML 4.0 target атрибут target , но добавила еще один атрибут: rel . Этот атрибут предназначен для указания взаимосвязи между документом, содержащим ссылку, и целью ссылки. Спецификация определяет набор стандартных значений для этого атрибута (например, next , previous , chapter , section ), большинство из которых связано со связями между небольшими разделами большого документа. Тем не менее, спецификация оставляет разработчику право использовать нестандартные значения для конкретных сайтов.

Здесь, в SitePoint, мы приняли пользовательское значение для rel чтобы пометить ссылки, ведущие на другие сайты. Это те самые ссылки, которые мы хотим открыть в новом окне браузера. Для этих ссылок мы устанавливаем атрибут rel как external .

Перед:

<a href="document.html" target="_blank" >external link</a>

После:

<a href="document.html" rel="external" >external link</a>

Итак, теперь, когда у нас есть ссылки на новое окно, помеченные в соответствии со стандартами, нам нужно написать JavaScript, который будет фактически открывать их в новом окне.

Деконструкция сценария

Работа нашего скрипта, который будет запущен после загрузки документа, будет заключаться в том, чтобы найти все гиперссылки в документе и изменить те, которые имеют наш специальный (но совместимый со стандартами!) Атрибут rel="external" , чтобы они открыть в новом окне.

Звучит устрашающе? Не волнуйтесь — код не так уж плох. Первый шаг — убедиться, что браузер справился с задачей:

if (!document.getElementsByTagName) return;

getElementsByTagName — удобный метод стандарта Document Object Model 1.0 (DOM1), поддерживаемый современными браузерами. Так как некоторые из старых браузеров, которые по-прежнему работают, такие как Netscape 4 и Internet Explorer 4, не поддерживают DOM1, мы должны отсеять их, проверив наличие этой функции. В этих браузерах мы просто возвращаемся и позволяем открывать внешние ссылки в одном и том же окне браузера — в большинстве случаев никаких больших потерь.

Далее мы используем метод getElementsByTagName чтобы получить список всех тегов <a> в документе:

var anchors = document.getElementsByTagName("a");

anchors будут содержать массив JavaScript после того, как метод выполнит свою работу. Каждый элемент в массиве будет представлять тег <a> в документе.

Теперь нам нужно просмотреть все теги <a> мы только что нашли, и изменить те, которые представляют ссылки в новом окне. Вы можете использовать цикл JavaScript for работы с каждым из тегов по очереди:

for (var i=0; i < anchors.length; i++) { var anchor = anchors[i];

Для каждого элемента в массиве anchors мы создаем переменную внутри цикла, называемую anchor чтобы изолировать тег, с которым мы сейчас имеем дело.

Теперь нам нужно проверить, представляет ли anchor ссылку в новом окне. Как я уверен, вы знаете, тег <a> используется не только для создания гиперссылок. С помощью атрибута name вы можете создать цель для ссылок, которые ведут в определенное место на странице. Только теги <a> с атрибутом href считаются гиперссылками. Поэтому наш код должен проверить, что anchor имеет атрибут href а также атрибут rel который имеет значение external .

if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external")

Теперь, когда мы подтвердили, что имеем дело со ссылкой в ​​новом окне, мы можем установить для ее target атрибута значение "_blank" :

anchor.target = "_blank";

И это должно сделать это! Читайте полный код и еще несколько слов о том, почему это решение приемлемо…

Тонкая линия

Как немного перфекционист, мой первый импульс, когда я узнал об этом решении, состоял в том, чтобы спросить: «Есть ли на самом деле разница?» И да, я часто разговариваю сам с собой во время исследования.

Я имею в виду, что если target атрибут тега <a> постепенно удаляется, действительно ли имеет значение, устанавливаем ли мы его с помощью JavaScript вместо HTML? Несомненно, страница будет проверяться на соответствие определениям типов документов HTML 4.0 Strict и XHTML 1.0 Strict, но разве мы не технически обманываем?

Ответ — нет. Объектная модель документа (DOM), которая управляет объектами и атрибутами документа, доступными для кода JavaScript, является совершенно отдельным стандартом от (X) HTML. Также учтите, что стандарт DOM 2.0, который был опубликован в январе 2003 года (намного позже XHTML 1.0, не говоря уже о HTML 4.0), все еще включает этот атрибут. Кажется очевидным, что, хотя этот атрибут планируется исключить из (X) HTML, он будет доступен для JavaScript через DOM в обозримом будущем.

В ряде других совместимых со стандартами сценариев ссылок для нового окна предлагается использовать window.open() для загрузки документа в новом окне. Хотя этот подход, как правило, хорошо работает на поверхности, его недостатком является то, что большинство браузеров неправильно отображают URL-адрес ссылки в запросе на новую страницу, что может быть серьезной проблемой, особенно в ссылках между сайтами.

Полный сценарий

Как и было обещано, вот полный сценарий. Обратите внимание на последнюю строку, которая назначает функцию externalLinks обработчику события onload окна. Это вызывает функцию, когда документ закончил загрузку.

function externalLinks() { if (!document.getElementsByTagName) return; var anchors = document.getElementsByTagName("a"); for (var i=0; i<anchors.length; i++) { var anchor = anchors[i]; if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external") anchor.target = "_blank"; } } window.onload = externalLinks;

Поскольку этот тип сценария вы хотите развернуть на всем сайте, вы должны скопировать этот код в отдельный файл (например, external.js ), а затем загрузить его на каждую страницу вашего сайта с помощью следующего кода, который должен появляться в <head> каждого документа:

<script type="text/javascript" src="/external.js"> </script>

Проблема решена!