В чем разница между различными методами размещения кода JavaScript в <a>?

Я видел следующие методы размещения JavaScript-кода в теге <a>:

function DoSomething() { ... return false; }
  • <a href="javascript:;" onClick="return DoSomething();">link</a>
  • <a href="javascript:DoSomething();">link</a>
  • <a href="javascript:void(0);" onClick="return DoSomething();">link</a>
  • <a href="#" onClick="return DoSomething();">link</a>

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

Мне лично нравится вариант 2, так как он позволяет вам увидеть, что будет запущено – особенно полезно при отладке, когда параметры передаются функции. Я использовал его совсем немного и не нашел проблем с браузером.

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

Есть ли тот, который не поддерживает или действительно плохо, когда вы знаете, что у пользователя включен JavaScript?

Связанный с этим вопрос: Ссылка для ссылок на JavaScript: "#" или "javascript: void (0)" ?.

Ответ 1

Мне очень нравится Matt Kruse Javascript Best Practices article. В нем он утверждает, что использование раздела href для выполнения кода JavaScript - плохая идея. Несмотря на то, что вы заявили, что у ваших пользователей должен быть включен JavaScript, нет причин, по которым у вас не может быть простой HTML-страницы, на которой все ваши ссылки на JavaScript могут указывать на их раздел href в случае, если кто-то отключит JavaScript после вход в систему. Я бы настоятельно рекомендовал вам по-прежнему разрешить этот резервный механизм. Что-то вроде этого будет придерживаться "лучших практик" и достичь вашей цели:

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>

Ответ 2

Зачем вам это делать, когда вы можете использовать addEventListener/attachEvent? Если нет href -эквивалента, не используйте <a>, используйте <button> и соответствующим образом настройте его.

Ответ 3

Вы забыли другой метод:

5: <a href="#" id="myLink">Link</a>

С кодом JavaScript:

document.getElementById('myLink').onclick = function() {
    // Do stuff.
};

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

Ответ 4

<a href="#" onClick="DoSomething(); return false;">link</a>

Я сделаю это или:

<a href="#" id = "Link">link</a>
(document.getElementById("Link")).onclick = function() {
    DoSomething();
    return false;
};

В зависимости от ситуации. Для более крупных приложений второй вариант лучше всего, потому что тогда он объединяет ваш код события.

Ответ 5

Метод № 2 имеет синтаксическую ошибку в FF3 и IE7. Я предпочитаю методы # 1 и # 3, потому что # 4 загрязняет URI с помощью '#', хотя вызывает меньше ввода текста... Очевидно, что, как отметили другие ответы, лучшим решением является отдельный html из обработки событий.

Ответ 6

Только современные браузеры

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }
    doc.addEventListener('click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault();
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

Кросс-браузер

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var cb_addEventListener = function(obj, evt, fnc) {
        // W3C model
        if (obj.addEventListener) {
            obj.addEventListener(evt, fnc, false);
            return true;
        } 
        // Microsoft model
        else if (obj.attachEvent) {
            return obj.attachEvent('on' + evt, fnc);
        }
        // Browser don't support W3C or MSFT model, go on with traditional
        else {
            evt = 'on'+evt;
            if(typeof obj[evt] === 'function'){
                // Object already has a function on traditional
                // Let wrap it with our own function inside another function
                fnc = (function(f1,f2){
                    return function(){
                        f1.apply(this,arguments);
                        f2.apply(this,arguments);
                    }
                })(obj[evt], fnc);
            }
            obj[evt] = fnc;
            return true;
        }
        return false;
    };
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }

    cb_addEventListener(doc, 'click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault ? e.preventDefault() : e.returnValue = false;
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

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

Источники:

Ответ 7

Одна разница, которую я заметил между этим:

<a class="actor" href="javascript:act1()">Click me</a>

и это:

<a class="actor" onclick="act1();">Click me</a>

заключается в том, что если в любом случае у вас есть:

<script>$('.actor').click(act2);</script>

то для первого примера act2 будет выполняться до act1, а во втором примере это будет наоборот.