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

<a href="javascript:void(0)">Hello</a>

Или

<a id="hello" href="#">Hello</a>
<script type="text/javascript>
  $(document).ready(function() {
    $("#toto").click(function(){
      //...
      return false;
    });
  });
</script>

И даже :

<a id="hello" href="#">Hello</a>
<script type="text/javascript>
  $(document).ready(function() {
    $("#toto").click(function(event){
      event.preventDefault();          
      //...
    });
  });
</script>

Есть ли у вас какие-либо предпочтения? Почему ? в каких условиях?

PS: конечно, приведенные выше примеры предполагают, что вы используете jquery, но есть эквиваленты для mootools или прототипа.

75
Mike 17 Авг 2010 в 04:37

8 ответов

Лучший ответ

Переплет:

  • javascript: URL - это ужас, которого следует избегать всегда;
  • атрибуты встроенного обработчика событий тоже не блестящие, но хорошо для быстрой разработки / тестирования;
  • связывание из скрипта, оставляя разметку чистой, обычно считается лучшей практикой. jQuery поощряет это, но нет никаких причин, по которым вы не можете сделать это ни в одной библиотеке или обычном JS.

Ответы :

  • В jQuery return false означает и preventDefault, и stopPropagation, поэтому значение будет другим, если вы заботитесь о родительских элементах, получающих уведомление о событии;
  • jQuery скрывает это здесь, но preventDefault / stopPropagation обычно пишутся иначе в IE (returnValue / cancelBubble).

Однако:

  • У вас есть ссылка, которая не является ссылкой. Это не связывает нигде; это действие. <a> на самом деле не идеальная разметка для этого. Это пойдет не так, если кто-то попытается щелкнуть по нему средней кнопкой мыши или добавить в закладки, или любой другой доступ, который имеет ссылка.
  • В тех случаях, когда он действительно указывает на что-то, например, когда он открывает / закрывает другой элемент на странице, установите для ссылки указатель на #thatelementsid и используйте ненавязчивые сценарии, чтобы извлечь идентификатор элемента из имени ссылки. Вы также можете прослушать location.hash при загрузке документа, чтобы открыть этот элемент, чтобы ссылка стала полезной в других контекстах.
  • В противном случае для чего-то, что является чисто действием, было бы лучше пометить это как: <input type="button"> или <button type="button">. Вы можете стилизовать его с помощью CSS, чтобы он выглядел как ссылка вместо кнопки, если хотите.
  • Однако есть некоторые аспекты стиля кнопок, от которых вы не можете полностью избавиться в IE и Firefox. Обычно это несущественно, но если вам действительно нужен абсолютный визуальный контроль, компромиссом является использование <span>. Вы можете добавить свойство tabindex, чтобы сделать его доступным с клавиатуры в большинстве браузеров, хотя в действительности оно не стандартизировано должным образом. Вы также можете обнаружить нажатия клавиш, как пробел или Enter, чтобы активировать. Это несколько неудовлетворительно, но все еще довольно популярно (например, ТАК так делает).
  • Другая возможность - <input type="image">. Это дает преимущества доступности кнопки с полным визуальным контролем, но только для кнопок с чистым изображением.
68
Timo Huovinen 17 Май 2012 в 08:29

Единственное преимущество, которое я могу придумать, используя javascript:void(0), это то, что он будет поддерживаться даже самыми старыми браузерами. Тем не менее, я бы использовал один из других ненавязчивых подходов, которые вы упомянули:

  • В большинстве случаев event.preventDefault() и return false могут использоваться взаимозаменяемо.
  • event.preventDefault() предотвратит повторную загрузку страницы по желанию, но позволит событию щелчка всплыть над родителем. Если вы хотите остановить барботирование, вы можете использовать его вместе с event.stopPropagation.
  • return false дополнительно остановит всплывающее событие для родителя.

Я говорю «взаимозаменяемо» в первом пункте выше, потому что большую часть времени нам не важно, всплывет ли событие у родителя (ей). Однако, когда do нам нужна некоторая настройка, мы должны рассмотреть пункты два и три.

Рассмотрим следующий пример:

<div>Here is some text <a href="www.google.com">Click!</a></div>​

$("a").click(function(e) {
    e.preventDefault();
});

$("div").click(function() {
    $(this).css("border", "1px solid red");
});
​

Нажатие на якорь предотвратит запуск действия по умолчанию для события, поэтому браузер не будет перенаправлять на www.google.com. Тем не менее, событие все равно будет «всплывать» и вызывать событие щелчка div, что добавит границу вокруг него. Добавьте e.stopPropagation() или просто return false, и событие щелчка div не сработает. Вы можете возиться с этим здесь: http://jsfiddle.net/cMKsN/1/

18
karim79 17 Авг 2010 в 01:05

event.preventDefault() и return false; - это одно - они инструктируют браузер не обрабатывать действие по умолчанию для события (в этом случае, переходя к href тега привязки, по которому щелкнули). href=javascript: и тому подобное - что-то другое - они заставляют действие по умолчанию «ничего не делать».

Это вопрос стиля. Хотите ли вы выполнять всю свою работу в режиме onclick или вы хотите иметь возможность размещать действия как в onclick, так и в href и полагаться на возможности браузера для модуляции между ними?

1
Dan Davies Brackett 17 Авг 2010 в 00:46

Dreamweaver по умолчанию использует приятный трюк, который я начал использовать.

<a href='javascript:;'></a>

Он маленький, он не спотыкается и не привязывается, и он не зависит от библиотеки.

1
Whit 17 Авг 2010 в 00:41

Я предпочитаю использовать return false, так как это дает пользователю возможность выбрать, продолжать ли это действие, как показано здесь, в режиме quirksmode:

http://www.quirksmode.org/js/events_early.html#default

Это просто, это старо, но это работает хорошо, кросс-браузер, независимо от версии javascript.

1
James Black 17 Авг 2010 в 00:46

Мне нравится использовать href="javascript:void(0)" в ссылке, поскольку # подразумевает переход на верх страницы, и это на самом деле может произойти, если по какой-то причине ваше событие jQuery не загружается, например. Не удается загрузить JQuery.

Я также использую event.preventDefault();, так как он не будет переходить по ссылке, даже если возникла ошибка, прежде чем вернуть false; например:

HTML:

<a id="link" href="http://www.google.com">Test</a>

JQuery, пример 1:

$("#link").click(
    function(){
        alert("Hi");
        invalidCode();
        return false;
    }
);

JQuery, пример 2:

$("#link").click(
    function(event){
        event.preventDefault();
        alert("Hi");
        invalidCode();
        return false;
    }
);

Так как invalidCode(); выдаст ошибку, return false никогда не будет достигнут, и если используется пример 1 jQuery, пользователь будет перенаправлен в Google, тогда как в примере 2 jQuery он не будет.

1
Adam 17 Авг 2010 в 01:01

Я думаю, что я видел также javascript :; В то время как сеть развивается, трудно отследить хитрости, которые доступны там ... но это главным образом связано с доступностью (кроме javascript: void (0);) и просто небольшая поправка не является javascript: void (0) но javascript: void (0); что означает ничего не делать в значительной степени, как возвращать ложь; хотя не уверен, если javascript: вернуть false; делает то же самое ..

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

1.) Я использую его из-за того, что кто-то упоминал выше. Href = "#" не подходит, так как это может указывать на то, что нужно идти наверх, и даже в этом случае "#top" будет более подходящим для этого случая. Но также это может вызвать что-то еще в вашем коде, который использует # (хэши), поэтому другая причина состоит в том, чтобы избежать конфликтов с другим javascript, который может использовать #. И я склонен искать это при использовании плагина, например, и немедленно заменять их .. href = '#' to href = 'javascript: void (0);' или href = 'javascript :;'

2.) Если я хочу повторно использовать функцию для группы определенных тегов Anchor, я могу вызвать ее с помощью селектора для любого атрибута, не беспокоясь об обнаружении события click и предотвращая действие по умолчанию, и я делаю это, даже не задумываясь о это как предпочтение развития.

3.) В большинстве случаев, если вы делаете построение ссылок, используя javascript: void (0); пытается сделать так, чтобы ссылка не следовала как старая href = rel = nofollow, чтобы избежать индексации ссылок, являющихся действиями. Я не уверен в этом только потому, что слышал, что сканеры и роботы теперь могут читать даже Flash, поэтому не удивлюсь, если они смогут читать ссылки на JavaScript

4.) Ссылаясь на 2.) вы можете настроить таргетинг на класс как и забыть о предотвращении действия по умолчанию для события click, используя href = "javascript: void (0);" и затем нацеливание класса непосредственно от селектора в функции jQuery.

        jQuery(function($)
        {
            //from the rel
            $('a[rel="-your-rel-id"]') ... off('click').on('click',function()

            //from the class
            $('a.-the-class') ... off('click').on('click',function()

            //from the id

            $('a#-the-id').off('click').on('click',function()
            {
            --do something with this link
        });

}); 

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

$ (А # -Ваш - идентификатор ) .hasClass ( -yourclass- )

Или любую другую интересную комбинацию и влияют на многие ссылки .. поэтому я действительно не буду предлагать использовать A в качестве селектора исключительно ..

Обычно я вижу здесь следующее:

  jQuery(function($)
        {
            //from the rel
            $('a[rel="-your-rel-id"]').on('click',function(event)
            //do something
            //prevent the click as is passed to the function as an event
            event.preventDefault();
        });

});
1
Jean Paul A.K.A el_vete 20 Ноя 2012 в 21:09

Я бы предпочел не помещать JavaScript в href, потому что это не то, для чего он предназначен. Я предпочитаю что-то вроде

<a href="#" onclick="return handler();">Link</a>
0
casablanca 17 Авг 2010 в 00:49