Функция JavaScript в href vs. onclick

475

Я хочу запустить простую функцию JavaScript на клик без перенаправления.

Есть ли какая-либо разница или польза от помещения вызова JavaScript в hrefатрибут (например, так:

<a href="javascript:my_function();window.print();">....</a>

) против помещения его в onclickатрибут (связывание с onclickсобытием)?

SkunkSpinner
источник
5
Этот вопрос обсуждался ранее: stackoverflow.com/questions/245868/…
SolutionYogi

Ответы:

276

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

Типичный путь в эти дни - использовать библиотеку javascript (например, jquery) и создать обработчик событий, используя эту библиотеку. Это будет выглядеть примерно так:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );
Parand
источник
1
Или mootools, prototype, dojo ... или просто на javascript, но это было бы намного больше кода, но оно того стоило.
Райан Флоренс
15
Если вам не нужно ничего делать с объектом события, простой javascript довольно прост. Получите DOM-узел с помощью obj = document.getElementById (), затем установите obj.onclick = foo
Мэтт Бриджес
1
как насчет разделения контента, когда <a href> генерируется на лету, скажем, во всплывающем окне, и вам все еще нужно специальное поведение при щелчке?
Серж
6
Но разве не был вопрос, спрашивающий о разнице между включением вызова JS inline hrefи inline in onclick? Предполагая, что вы по какой-то причине собираетесь вставить его в строку, что вам следует использовать? (На практике я бы сделал то, что вы предложили, но вы, кажется, пропустили разницу между
nnnnnn
1
Единственный раз, когда я бы рекомендовал встроить вызов функции вместо наличия события onclick для ссылки, это если вы динамически создаете ссылки на странице, которые будут вызывать одну и ту же функцию, но могут не иметь уникальных идентификаторов. У меня есть веб-форма, где пользователь может добавлять и удалять элементы, и я помещаю щелчок мышью в href ссылок внутри динамически создаваемых элементов div, чтобы я мог быстрее начать обработку сценария, а не использовать что-то менее конкретное, например, относительный идентификатор или имя класса
MistyDawn
977

плохой:

<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; });
DEMP
источник
21
Было бы другое решение, которое было бы лучшим, если hrefне указано #иное, а есть реальная ссылка для браузеров noJS.
helly0d
6
Что если я скажу вам, что только первый (плохой) работает одинаково (правильно) во всех браузерах со средним кликом.
Vloxxity
14
Что плохого в <a id="myLink" href="javascript:MyFunction();">?
Ваддади Картик
6
Просто мои скромные 5 центов: «лучший» вариант - использовать кнопки для щелчков (события onclick?) И оставлять привязки со своими ссылками на то, что изначально было задумано в их первоначальном замысле: быть привязками для ссылок на другие страницы.
nidalpres
4
У привязки по щелчку с javascript есть один недостаток: позже, когда вы отлаживаете кому-то еще его форму, очень трудно найти, где и какой тип javascript связан с этим элементом.
Мартен Кифт
69

С точки зрения 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>
Адам
источник
9
Спасибо за подтверждение моего подозрения, что «this» отличается от «href» против «onclick».
joonas.fi
17

я использую

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>
Клиф Коллинз
источник
10
+1 Действительно здорово! :-) Я никогда не слышал об nohrefатрибутах раньше. Это наиболее логичный / элегантный способ обработки таких действий JavaScript. Это совместимо с FF12 и IE8. Поэтому я заменю все мои href="JavaScript:void(0);"на nohref. Большое спасибо. Приветствия.
olibre
7
это не поддерживается основными браузерами, почему мы должны использовать это? w3schools.com/tags/att_area_nohref.asp
hetaoblog
11
nohrefявляется частью areaтега, а не a! Ваш пример такой же, как<a onClick="alert('Hello World')">HERE</a>
nZeus
6
Просто еще одно "не делай этого предупреждения". Это совершенно нестандартный и плохой совет. nohrefне существует в aтеге.
Colin 't Hart,
11

В дополнение ко всему, href отображается в строке состояния браузера, а onclick - нет. Я думаю, что не удобно показывать там код JavaScript.

Kamarey
источник
10

лучший способ сделать это с:

<a href="#" onclick="someFunction(e)"></a>

Проблема в том, что это добавит хеш (#) к концу URL-адреса страницы в браузере, что потребует от пользователя дважды нажать кнопку «Назад», чтобы перейти на страницу раньше вашей. Учитывая это, вам нужно добавить некоторый код, чтобы остановить распространение событий. У большинства наборов инструментов JavaScript уже есть функция для этого. Например, инструментарий Dojo использует

dojo.stopEvent(event);

сделать это.

linusthe3rd
источник
9
Я хотел бы предупредить, что если вы используете href="#"браузер, который будет искать именованный тег привязки, и, поскольку он не найдет его, то он сделает окно для прокрутки вверх страницы, что может быть не заметно, если ты уже на вершине. Чтобы избежать такого поведения, используйте: href="javascript:;"вместо.
alonso.torres
1
@ alonso.torres Хорошая мысль, но именно поэтому я упомянул об использовании dojo.stopEvent () - он остановит распространение / всплытие событий и поведение по умолчанию при нажатии на якорь.
linusthe3rd
7
Вместо stopEvent, почему бы просто не вернуть false (onclick = "someFunction (e); return false;")
stracktracer
10

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

Лучше всего связать обработчик событий с элементом, как заявили многие другие люди, однако он <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);"себя

Эдуардо
источник
8

имеющий javascript: любого атрибута, который не предназначен специально для сценариев, является устаревшим методом HTML. Хотя технически это работает, вы все равно назначаете свойства javascript атрибуту, не относящемуся к сценарию, что не является хорошей практикой. Он может даже потерпеть неудачу в старых браузерах или даже в некоторых современных (гугл-сообщение на форуме, похоже, указывает на то, что Opera не любит URL 'javascript:').

Лучше было бы использовать второй способ - поместить ваш javascript в onclickатрибут, который игнорируется, если не доступны функции сценариев. Поместите действительный URL-адрес в поле href (обычно «#»), чтобы использовать его для тех, у кого нет JavaScript.

zombat
источник
1
Я не вижу никакой разницы между «javascript:» href и «#» href с атрибутом onclick. Оба одинаково бесполезны для браузеров без JS.
Harto
2
харто, это не совсем правильно. «#» - это указатель для именованной ссылки, а не идентификатор javascript. Это действительный URL, и он не требует распознавания JavaScript.
зомбат
8

это сработало для меня, используя эту строку кода:

<a id="LinkTest" title="Any Title"  href="#" onclick="Function(); return false; ">text</a>
Омар Яссин Карселен
источник
7

Это работает

<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>
TitusMix
источник
3
Добро пожаловать в переполнение стека! Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код. Также постарайтесь не переполнять ваш код пояснительными комментариями, так как это снижает удобочитаемость кода и пояснений!
До свидания, StackExchange
2
Этот код не работает. return: false недействителен. Должно быть возвращено false.
hbulens
5

Лично меня раздражает размещение вызовов javascript в теге HREF. Я обычно не особо обращаю внимание на то, является ли что-то ссылкой на JavaScript или нет, и часто хочется открыть что-то в новом окне. Когда я пытаюсь сделать это с одним из этих типов ссылок, я получаю пустую страницу, на которой ничего нет, и javascript в моей адресной строке. Тем не менее, это немного обойти с помощью onlick.

Питер
источник
3

Еще одна вещь, которую я заметил при использовании «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 работает нормально.

колобок
источник
3

Во-первых, hrefлучше всего использовать URL-адрес, поскольку он позволяет пользователям копировать ссылки, открывать другие вкладки и т. Д.

В некоторых случаях (например, на сайтах с частыми изменениями 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) в любое время, не беспокоясь о привязке каждый раз.

jchavannes
источник
1
 <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>   
Эндрю
источник
0

Мне показалось, что javascript: hrefs не работал, когда страница была встроена в функцию веб-страницы Outlook, где вместо почтовой папки вместо URL отображается URL-адрес.

Кристиан
источник