Функция JavaScript в href vs. onclick
Я хочу запустить простую функцию JavaScript на клик без перенаправления.
Есть ли какая-то разница или польза между вызовом JavaScript в href
атрибут (как это:
<a href="javascript:my_function();window.print();">....</a>
) вместо того, чтобы положить его в onclick
атрибут (привязка к onclick
событие)?
19 ответов
Помещение onclick в href оскорбит тех, кто твердо верит в отделение контента от поведения / действия. Аргумент заключается в том, что ваш HTML-контент должен оставаться сфокусированным исключительно на контенте, а не на представлении или поведении.
Типичный путь в эти дни - использовать библиотеку javascript (например, jquery) и создать обработчик событий, используя эту библиотеку. Это будет выглядеть примерно так:
$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );
плохой:
<a id="myLink" href="javascript:MyFunction();">link text</a>
хорошо:
<a id="myLink" href="#" onclick="MyFunction();">link text</a>
лучше:
<a id="myLink" href="#" onclick="MyFunction();return false;">link text</a>
еще лучше 1:
<a id="myLink" title="Click to do something"
href="#" onclick="MyFunction();return false;">link text</a>
еще лучше 2:
<a id="myLink" title="Click to do something"
href="PleaseEnableJavascript.html" onclick="MyFunction();return false;">link text</a>
Почему лучше? так как return false
запретит браузеру переходить по ссылке
Лучший:
Используйте jQuery или другую подобную инфраструктуру, чтобы прикрепить обработчик onclick по идентификатору элемента.
$('#myLink').click(function(){ MyFunction(); return false; });
С точки зрения JavaScript, одно отличие состоит в том, что this
Ключевое слово в onclick
обработчик будет ссылаться на элемент DOM, чей onclick
атрибут это (в этом случае <a>
элемент), тогда как this
в href
атрибут будет ссылаться на window
объект.
С точки зрения презентации, если href
атрибут отсутствует в ссылке (т.е. <a onclick="[...]">
), то по умолчанию браузеры будут отображать text
курсор (а не часто желаемый pointer
курсор), так как он лечит <a>
как якорь, а не ссылка.
С точки зрения поведения, при указании действия с помощью навигации через href
браузер обычно поддерживает открытие href
в отдельном окне с помощью ярлыка или контекстного меню. Это невозможно при указании действия только через onclick
,
Однако, если вы спрашиваете, каков наилучший способ получить динамическое действие от щелчка объекта DOM, тогда лучше всего присоединить событие с использованием JavaScript, отдельного от содержимого документа. Вы можете сделать это несколькими способами. Распространенным способом является использование библиотеки javascript, такой как jQuery, для привязки события:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<a id="link" href="http://example.com/action">link text</a>
<script type="text/javascript">
$('a#link').click(function(){ /* ... action ... */ })
</script>
Я использую
Click <a nohref style="cursor:pointer;color:blue;text-decoration:underline"
onClick="alert('Hello World')">HERE</a>
Долгий путь, но он выполняет свою работу. используйте стиль A для упрощения, тогда он становится:
<style> A {cursor:pointer;color:blue;text-decoration:underline; } </style>
<a nohref onClick="alert('Hello World')">HERE</a>
Главный ответ - очень плохая практика, никогда не следует ссылаться на пустой хеш, так как это может создать проблемы в будущем.
Лучше всего связать обработчик события с элементом, как заявили многие другие люди, <a href="javascript:doStuff();">do stuff</a>
отлично работает в любом современном браузере, и я широко использую его при рендеринге шаблонов, чтобы избежать необходимости повторной привязки для каждого экземпляра. В некоторых случаях такой подход обеспечивает лучшую производительность. YMMV
Еще одна интересная новость....
onclick
& href
имеют различные поведения при вызове JavaScript непосредственно.
onclick
пройдет this
контекст правильно, тогда как href
не будет, или другими словами <a href="javascript:doStuff(this)">no context</a>
не будет работать, тогда как <a onclick="javascript:doStuff(this)">no context</a>
будут.
Да я пропустил href
, Хотя это не соответствует спецификации, оно будет работать во всех браузерах, хотя в идеале оно должно включать href="javascript:void(0);"
для хорошей меры
Лучший способ сделать это с:
<a href="#" onclick="someFunction(e)"></a>
Проблема заключается в том, что это добавит хеш (#) к концу URL-адреса страницы в браузере, что потребует от пользователя дважды нажать кнопку "Назад", чтобы перейти на страницу раньше вашей. Учитывая это, вам нужно добавить некоторый код, чтобы остановить распространение событий. У большинства наборов инструментов JavaScript уже есть функция для этого. Например, инструментарий Dojo использует
dojo.stopEvent(event);
сделать это.
В дополнение ко всему, href отображается в строке состояния браузера, а onclick - нет. Я думаю, что не удобно показывать там код JavaScript.
Это работает
<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>
У меня получилось использовать эту строку кода:
<a id="LinkTest" title="Any Title" href="#" onclick="Function(); return false; ">text</a>
Имеющий javascript:
в любом атрибуте, который не предназначен специально для сценариев, является устаревшим методом HTML. Хотя технически это работает, вы все равно назначаете свойства javascript атрибуту, не относящемуся к сценарию, что не является хорошей практикой. Он может даже потерпеть неудачу в старых браузерах или даже в некоторых современных (гугл-сообщение на форуме, похоже, указывает на то, что Opera не любит URL 'javascript:').
Лучшей практикой будет второй способ поместить ваш javascript в onclick
атрибут, который игнорируется, если нет доступных функций сценариев. Поместите действительный URL-адрес в поле href (обычно "#"), чтобы использовать его как запасной вариант для тех, у кого нет JavaScript.
Во-первых, имея URL в href
лучше всего потому, что позволяет пользователям копировать ссылки, открывать в другой вкладке и т. д.
В некоторых случаях (например, на сайтах с частыми изменениями HTML) нецелесообразно привязывать ссылки каждый раз, когда происходит обновление.
Типичный метод связывания
Нормальная ссылка:
<a href="https://www.google.com/">Google<a/>
И как-то так для JS:
$("a").click(function (e) {
e.preventDefault();
var href = $(this).attr("href");
window.open(href);
return false;
});
Преимущества этого метода - чистое разделение разметки и поведения, и не нужно повторять вызовы функций в каждой ссылке.
Метод без привязки
Однако, если вы не хотите связываться каждый раз, вы можете использовать onclick и передать элемент и событие, например:
<a href="https://www.google.com/" onclick="return Handler(this, event);">Google</a>
И это для JS:
function Handler(self, e) {
e.preventDefault();
var href = $(self).attr("href");
window.open(href);
return false;
}
Преимущество этого метода заключается в том, что вы можете загружать новые ссылки (например, через AJAX) в любое время, не беспокоясь о привязке каждый раз.
Ответ, получивший наибольшее количество голосов, сегодня устарел
Я бы рекомендовал прямо противоположное, смотрите пошагово с причинами:
хороший:
<a id="myLink" href="javascript:MyFunction();">link text</a>
Это зависит от того, может быть, и хорошо, потому что поисковые роботы следуют за целями href, и если есть какой-либо значимый контент, созданный
MyFunction()
(динамическая ссылка), за ней следуют с большей вероятностью, чем в событии клика, у которого может быть несколько прослушивателей или ни одного.
плохо :
<a id="myLink" href="#" onclick="MyFunction();">link text</a>
#
означает бессмысленную ссылку, поисковые роботы часто интересуются только первыми x ссылками, поэтому это может помешать им перейти по некоторым значимым ссылкам позже на странице.
худший:
<a id="myLink" href="#" onclick="MyFunction();return false;">link text</a>
То же, что и предыдущий плюс
return false
мешает перейти по ссылке. Если какие-то другие скрипты захотят добавить еще одного слушателя и обновить цель (скажем, перенаправить через прокси), они не смогут этого сделать, не изменив onclick (хорошо, это всего лишь небольшая неудача, поскольку такие варианты использования скорее теоретические).
худший:
Используйте jQuery или другую подобную структуру, чтобы прикрепить обработчик onclick по идентификатору элемента.
$('#myLink').click(function(){ MyFunction(); return false; });
jQuery устарел в 2020+ и не должен использоваться в новых проектах.
События в href
Обработчик атрибута href не получает объект события, поэтому обработчик неявно не видит, какая ссылка была источником. Вы можете добавить его в обработчик onclick, который срабатывает до перехода к href:
<a href="javascript:my_function()" onclick="myModule.event=event">
JS based link
</a>
<script>
myModule = {};
function my_function() {
console.log(myModule.event.target); // the source of the click
if(something) location.href = ...; // dynamic link
}
</script>
Лично меня раздражает размещение вызовов javascript в теге HREF. Я обычно не особо обращаю внимание на то, является ли что-то ссылкой на JavaScript или нет, и часто хочу открыть что-то в новом окне. Когда я пытаюсь сделать это с одним из этих типов ссылок, я получаю пустую страницу, на которой ничего нет, и javascript в моей адресной строке. Тем не менее, это немного обойти с помощью onlick.
Еще одна вещь, которую я заметил, когда использовал "href" с javascript:
Скрипт в атрибуте "href" не будет выполнен, если разница во времени между двумя кликами была достаточно короткой.
Например, попробуйте запустить следующий пример и дважды щелкните (быстро!) На каждой ссылке. Первая ссылка будет выполнена только один раз. Вторая ссылка будет выполнена дважды.
<script>
function myFunc() {
var s = 0;
for (var i=0; i<100000; i++) {
s+=i;
}
console.log(s);
}
</script>
<a href="javascript:myFunc()">href</a>
<a href="#" onclick="javascript:myFunc()">onclick</a>
Воспроизводится в Chrome (двойной щелчок) и IE11 (с тройным щелчком). В Chrome, если вы нажмете достаточно быстро, вы можете сделать 10 кликов и выполнить только одну функцию.
Firefox работает нормально.
<hr>
<h3 class="form-signin-heading"><i class="icon-edit"></i> Register</h3>
<button data-placement="top" id="signin_student" onclick="window.location='signup_student.php'" id="btn_student" name="login" class="btn btn-info" type="submit">Student</button>
<div class="pull-right">
<button data-placement="top" id="signin_teacher" onclick="window.location='guru/signup_teacher.php'" name="login" class="btn btn-info" type="submit">Teacher</button>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#signin_student').tooltip('show'); $('#signin_student').tooltip('hide');
});
</script>
<script type="text/javascript">
$(document).ready(function(){
$('#signin_teacher').tooltip('show'); $('#signin_teacher').tooltip('hide');
});
</script>
<a href="#" onclick="try{FUNCTION_YOU_WANT()}catch(e){}return false">click here</a>
Мне показалось, что javascript: hrefs не работал, когда страница была встроена в функцию веб-страницы Outlook, где вместо почтовой папки вместо URL отображается URL-адрес.
Я не могу поверить, что +13 лет спустя все эти ответы семантически неверны! Якорный элемент<a>
:
... со своим атрибутом href создает гиперссылку на веб-страницы, файлы, адреса электронной почты, местоположения на той же странице или что-либо еще, к чему может обращаться URL- адрес.
Содержимое каждого из них должно указывать на назначение ссылки . Если присутствует атрибут href, нажатие клавиши ввода при фокусе на элементе активирует его.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
Таким образом, используяhref=
для javascript - плохая практика и плохая веб-семантика. Вам лучше использовать атрибут обработчика событий наbutton
элемент, как:
Элемент HTML — это интерактивный элемент, активируемый пользователем с помощью мыши, клавиатуры, пальца, голосовой команды или другой вспомогательной технологии. После активации он выполняет запрограммированное действие, такое как отправка формы или открытие диалогового окна.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button
и обработчик событияonclick=
:
Все атрибуты обработчика событий принимают строку. Строка будет использоваться для синтеза функции JavaScript, такой как имя функции (/args/) {body}, где name — это имя атрибута, а body — значение атрибута.
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#event_handler_attributes
Поскольку вы не переходите к URL-адресу или месту назначения ссылки, а скорее запускаете функцию Javascript, правильный способ сделать это - использоватьonclick
. И если вам нужен стиль тега привязки на кнопке, просто используйте CSS.
Суть в том, что если вы можете это сделать, это не значит, что вы должны это делать.
Это тоже работает
<a (click)='myFunc()'>Click Here </a>
(onclick) не работал у меня в проекте Angular с начальной загрузкой.