Почему использование ссылок с протоколом javascript: - плохая практика?

В 1990-х годах была мода помещать код Javascript непосредственно в атрибуты <a> href, например:

<a href="javascript:alert('Hello world!')">Press me!</a>

И вдруг я остановился, чтобы это увидеть. Все они были заменены такими вещами, как:

<a href="#" onclick="alert('Hello world!')">Press me!</a>

Почему для ссылки, единственной целью которой является запуск кода Javascript и не имеет реальной href цели, рекомендуется использовать свойство onclick вместо свойства href?


person zneak    schedule 19.03.2010    source источник
comment
это не устарело .. просто плохая практика .. как и использование атрибута onclick .. поиск unobtrusive javascript и progressive enhancement, чтобы найти лучшие практики ..   -  person Gabriele Petrioli    schedule 19.03.2010
comment
@Gaby: в чем разница между плохой практикой и устаревшей?   -  person zneak    schedule 19.03.2010
comment
Устарело означает, что эти функции, скорее всего, не будут поддерживаться в будущем.   -  person Gabriele Petrioli    schedule 19.03.2010
comment
@Gaby: ладно, исправь заголовок.   -  person zneak    schedule 19.03.2010
comment
Я бы даже подумал о плохой привычке (или практике?) Использовать тег <a>, чтобы притвориться ссылкой на страницу, когда на самом деле это всего лишь триггер для действия JS. Я бы подумал об использовании <span class="js-trigger">Press me</span> и отделении соответствующего кода javascript, поместив его в отдельный файл JS.   -  person Adrien Be    schedule 23.04.2014


Ответы (10)


Контекст выполнения отличается, чтобы убедиться в этом, попробуйте вместо этого использовать следующие ссылки:

<a href="javascript:alert(this.tagName)">Press me!</a> <!-- result: undefined -->
<a href="#" onclick="alert(this.tagName)">Press me!</a> <!-- result: A -->

javascript: выполняется в глобальном контексте, а не как метод элемента, который обычно вам нужен. В большинстве случаев вы делаете что-то с элементом, над которым вы действовали, или по отношению к нему, лучше выполнить это в этом контексте.

Кроме того, он намного чище, хотя я бы вообще не стал использовать встроенный скрипт. Ознакомьтесь с любыми фреймворками для более четкого управления этими вещами. Пример в jQuery:

$('a').click(function() { alert(this.tagName); });
person Nick Craver    schedule 19.03.2010
comment
просто краткое пояснение - когда вы вызываете javascript: this из атрибута href, это ссылка на объект DOM окна. - person matt lohkamp; 19.03.2010
comment
Спасибо, что объяснили разницу, а затем предложили лучший способ. - person zneak; 19.03.2010
comment
Мне показалось интересным, что основной упор в ответе, который одобряет сообщество и который был выбран, сосредоточен на неудобствах, которые использование протокола javascript: создает для разработчика, а не на его влиянии на качество результаты ... заставляют меня думать об испытании лифта; codinghorror.com/blog/ 2007/09 / - person Richard JP Le Guen; 19.03.2010
comment
@Richard - Это также имеет то преимущество, что он находится во внешнем и кешированном файле, а не загружается как часть страницы каждый раунд ... Я бы сказал, что по многим причинам это лучше как для качества, так и для удобства разработчика. - person Nick Craver; 19.03.2010
comment
@Nick Craver - это правда ... Я думал не меньше, чем о содержании; Мне кажется, что это прозвучало как сноска / запоздалое примечание. Не сказать, что я не согласен ни с одним из ваших пунктов :) - person Richard JP Le Guen; 20.03.2010

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

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

person Levi Hackwith    schedule 19.03.2010

Пара причин:

  1. Практика плохого кода:
    Тег HREF указывает на то, что существует гиперссылка на другое место. Использование одного и того же тега для функции javascript, которая на самом деле никуда не ведет пользователя, является плохой практикой программирования.

  2. Проблемы с поисковой оптимизацией:
    Я думаю, что поисковые роботы используют тег HREF для сканирования всего веб-сайта и связывания всех связанных частей. Добавляя javascript, мы нарушаем эту функциональность.

  3. Нарушает доступность:
    Я думаю, что некоторые программы чтения с экрана не смогут выполнить javascript и могут не знать, как работать с javascript, ожидая гиперссылки. Пользователь будет ожидать увидеть ссылку в строке состояния браузера при наведении курсора на ссылку, в то время как он увидит строку вроде: «javascript:», которая может их сбить с толку и т. Д.

  4. Вы все еще находитесь в 1990-х:
    Основной совет - иметь свой javascript в отдельном файле, а не смешивать с HTML страницы, как это было в 1990-х.

HTH.

person Sunny    schedule 19.03.2010
comment
Я не верю, что SEO - веский аргумент, поскольку они очень хорошо умеют определять, по каким ссылкам можно переходить, а по каким - нет. Я куплюсь на ваш аргумент о программах чтения с экрана (я бы очень хотел услышать, как компьютерный голос читает вслух код Javascript), но строка состояния кажется мне преувеличенной. - person zneak; 19.03.2010
comment
@zneak - возможно, я должен заменить комментарий в строке состояния, может сбить их с толку или раздражать. По личному опыту, мне нравится нажимать Shift + щелкать / Ctrl + щелкать ссылки, чтобы открывать их в новом окне, когда я не хочу убирать текущую страницу, и когда это ломается, я хочу найти разработчика, который сломал ее в первое место :) - person Sunny; 19.03.2010
comment
+1 за плохой код, тег href не был создан для указания триггера JS-кода. - person Adrien Be; 23.04.2014

Я открываю множество ссылок в новых вкладках - только для того, чтобы увидеть javascript: void (). Значит, вы меня раздражаете, как и себя (потому что Google увидит то же самое).

Другая причина (также упомянутая другими) заключается в том, что разные языки должны быть разделены в разных документах. Почему? Хорошо,

  • Смешанные языки плохо поддерживаются большинством IDE и валидаторов. Встраивание CSS и JS в HTML-страницы (или что-то еще в этом отношении) в значительной степени уничтожает возможности статической проверки правильности встроенного языка. Иногда также используется язык встраивания. (Документ PHP или ASP не является допустимым HTML.) Вы не хотите, чтобы синтаксические ошибки или несоответствия отображались только во время выполнения.
  • Другая причина состоит в том, чтобы иметь более четкое разделение между типами вещей, которые вам нужно указать: HTML для контента, CSS для макета, JS обычно для большего макета и внешнего вида. Они не сопоставляются один в один: обычно вы хотите применить макет ко всем категориям элементов содержимого (отсюда и CSS), а также к внешнему виду (отсюда jQuery). Они могут изменяться в разное время, когда меняются элементы контента (на самом деле контент часто создается на лету) и разными людьми. Так что есть смысл хранить их и в отдельных документах.
person reinierpost    schedule 19.03.2010
comment
Проголосовали в основном за первый балл. Попытка открыть ссылку в новой вкладке только для того, чтобы увидеть javascript:void(0) в адресной строке, сводит меня с ума сумасшедшим. - person Tyler McHenry; 19.03.2010
comment
Я больше говорил о коде Javascript, который влияет только на вызывающую страницу. Я тоже не люблю видеть javascript:void(0). - person zneak; 19.03.2010

Краткий ответ: Встроенный Javascript плох по той же причине, что и встроенный CSS.

person leepowers    schedule 19.03.2010

Использование протокола javascript: влияет на доступность, а также вредит SEO-дружественности вашей страницы.

Обратите внимание, что HTML означает Hypter Text something something ... Hyper Text обозначает текст со ссылками и ссылками в нем, для чего используется элемент привязки <a>.

Когда вы используете javascript: 'протокол', вы неправильно используете элемент привязки. Поскольку вы неправильно используете элемент <a>, такие вещи, как Google Bot и программа чтения с экрана Jaws, будут иметь проблемы с «пониманием» вашей страницы, поскольку они не очень заботятся о вашем JS, но очень заботятся о Hyper Text ML, обращая особое внимание якоря hrefs.

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

Вы можете подумать: «Но у скольких людей сейчас отключен JavaScript?» но мне нравится формулировать эту идею в большей степени: «Скольким потенциальным клиентам я готов отвергнуть только из-за флажка в настройках их браузеров?»

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

person Richard JP Le Guen    schedule 19.03.2010
comment
Это язык гипертекстовой разметки. При этом я не согласен почти со всем в вашем сообщении, кроме последнего абзаца. Итак, я объясню почему в еще двух комментариях. - person zneak; 19.03.2010
comment
Для аргумента SEO это всего лишь обработка протокола. Я почти уверен, что поисковые системы знают, является ли ссылка HTTP-ссылкой или нет, и использование неизвестного протокола их точно не испортит. Я совершенно уверен, что использование ссылки mailto: на моей странице не заставит Google ненавидеть мою страницу только потому, что он не может перейти по ней. - person zneak; 19.03.2010
comment
Кроме того, когда ссылка используется только для запуска сценария, вы всегда будете неправильно использовать <a>, поскольку вы должны поставить несвязанный href. И в этих случаях, не является ли более дружелюбным по отношению к UA с отключенным Javascript использовать протокол javascript :? Он просто ничего не сделает, вместо того, чтобы, скажем, вернуться к началу страницы, предполагая, что несвязанная, но необходимая привязка - это #. (Это, очевидно, предполагает, что ссылка не делает ничего, кроме запуска действия Javascript.) - person zneak; 19.03.2010
comment
@zneak - я знаю, что означает ML; кое-что должно было обозначить, что в рамках моего ответа HT была важной частью;) Люди склонны сосредотачиваться на ML больше, чем на HT. Что касается SEO, вы правы; Google не будет ненавидеть вашу страницу, но и не сделает ее похожей на нее; вы даете ему информацию, которую он может только отбросить. Зачем беспокоиться? Что касается вашего аргумента о дружелюбии, я также добавлю несколько комментариев в цепочку! - person Richard JP Le Guen; 19.03.2010
comment
Прошу прощения, что это немного жестковато, но использование протокола javascript: кажется ленивым способом добиться такого удобства для пользователей без JS. Я также чувствую, что вы очень сильно привязаны к использованию <a> с href в качестве элемента, на который пользователь должен щелкнуть, и, следовательно, думаете, что пользователь получит указательный курсор для этого элемента. Таким образом, пользователь без JS наведет указатель мыши на ваш элемент, увидит указательный палец, думает, что я могу взаимодействовать с этим щелчком, и тогда ничего не произойдет ... - person Richard JP Le Guen; 19.03.2010
comment
... если вы беспокоитесь о прыжках, удалите href и нацелите свойство cursor:pointer CSS на элемент. Таким образом, ваш якорь никуда не уйдет (например, вверху страницы) и останется заостренным пальцем. Ваш пользователь без JS не будет прыгать или что-либо еще на странице, когда он нажимает на якорь. Еще лучше, когда вы определяете свой onclick во внешнем JS, примените атрибут class к элементу, на который нацелено ваше свойство cursor, чтобы ваш пользователь без JS не получил ничего, что могло бы предложить ему вообще потрудиться, нажав на него! (сохраните слова "нажмите здесь", хе-хе-хе) - person Richard JP Le Guen; 19.03.2010

Худшая проблема, вероятно, заключается в том, что он нарушает ожидаемую функциональность.
Например, как указывали другие, открыть в новом окне / вкладка = мертвая ссылка = раздраженные / сбитые с толку пользователи.

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

Таким образом, вы получаете такое же поведение для кликов, новой вкладки / окна и даже закладок / отправленных ссылок, и все не становится дурацким, если JS отключен.

Другими словами, примерно так (очень упрощенно):

Для ссылки:

onclick = "doStuff()"

href = "#dostuff"

Для страницы:

onLoad = if(hash="dostuff") doStuff();
person MatsSvensson    schedule 09.11.2010

Кроме того, поскольку мы говорим об устаревании и семантике, вероятно, стоит отметить, что «</a>» не означает «кликабельно» - это означает «привязка» и подразумевает ссылку на другую страницу. Таким образом, имеет смысл использовать этот тег для переключения на другое «представление» в вашем приложении, но не для выполнения вычислений. Тот факт, что у вас нет URL-адреса в вашем атрибуте href, должен быть признаком того, что вы не должны использовать тег привязки.

Вы также можете назначить действие события щелчка практически любому элементу html - может быть, <h1>, <img> или <p> было бы более подходящим? В любом случае, как уже упоминали другие люди, добавьте еще один атрибут (возможно, «id»), который javascript может использовать в качестве «крючка» (document.getElementById), чтобы добраться до элемента и назначить onclick. Таким образом, вы можете разделить представление контента (HTML) (CSS) и интерактивность (JavaScript). И миру не конец.

person matt lohkamp    schedule 19.03.2010
comment
Возможно, <span> будет более подходящим, чем <h1>, поскольку это семантически бессмысленно. Но я понял. - person zneak; 19.03.2010

Обычно у меня есть целевая страница с названием «EnableJavascript.htm», на которой написано большое сообщение: «Чтобы эта функция работала, необходимо включить Javascript». А затем я настраиваю свои якорные теги вот так ...

<a href="EnableJavascript.htm" onclick="funcName(); return false;">

Таким образом, якорь имеет законное место назначения, которое по возможности будет перезаписано вашей функциональностью Javascript. Это будет изящно ухудшаться. Хотя сейчас я обычно создаю веб-сайты с полной функциональностью, прежде чем решу добавить в смесь немного Javascript (что в совокупности устраняет необходимость в подобных привязках).

Использование атрибута onclick непосредственно в разметке - это совсем другая тема, но я бы порекомендовал ненавязчивый подход с такой библиотекой, как jQuery.

person Josh Stodola    schedule 19.03.2010

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

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

Не забудьте добавить return false; до конца вашей ссылки, чтобы страница не перескакивала вверх для пользователя (если только это не то поведение, которое вы ищете).

person RDL    schedule 19.03.2010