У чому різниця між різними методами розміщення коду JavaScript у <a>?


87

Я бачив наступні методи розміщення коду JavaScript у <a>тезі:

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

Я розумію ідею спроби встановити дійсну URL-адресу замість просто коду JavaScript, на випадок, якщо у користувача не ввімкнено JavaScript. Але для цілей цього обговорення мені потрібно припустити, що JavaScript увімкнено (вони не можуть увійти без нього).

Мені особисто подобається варіант 2, оскільки він дозволяє побачити, що буде запущено - особливо корисно при налагодженні, де параметри передаються функції. Я використовував його досить багато і не знайшов проблем із браузером.

Я читав, що люди рекомендують 4, тому що це дає користувачеві реальне посилання для переходу, але насправді, # не є "реальним". Це піде абсолютно нікуди.

Чи є такий, який не підтримує або насправді поганий, коли ви знаєте, що у користувача ввімкнено JavaScript?

Пов’язане запитання: Href для посилань на JavaScript: “#” чи “javascript: void (0)”? .


Невелика проблема синтаксису: Вибір №2 повинен бути - <a href="javascript:DoSomething();"> посилання </a> без "повернення"
DRosenfeld

Будь ласка, змініть прийняту відповідь на відповідь @eyelidlessness. Я вважаю, що це найкращий підхід, оскільки він дбає про семантику.
Міхал Перлаковський,

Відповіді:


69

Мені дуже подобається стаття найкращих практик Javascript від Метта Круза . У ньому він заявляє, що використання hrefрозділу для виконання коду JavaScript - погана ідея. Незважаючи на те, що ви заявили, що у ваших користувачів повинен бути ввімкнений JavaScript, немає жодної причини, що у вас не може бути простої HTML-сторінки, на яку можуть посилатись усі ваші посилання JavaScript для свого hrefрозділу, якщо хтось вимкне JavaScript після входу в систему. Я настійно закликаю вас досі дозволити цей резервний механізм. Щось подібне дотримуватиметься "найкращих практик" і досягтиме вашої мети:

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

4
як значення href буде показано користувачеві в рядку стану? (рядок внизу). Я б хотів використати трохи більш зручне посилання, наприклад. "js.html? doSomething" сторінка все ще може бути статичним html. Таким чином користувач чітко побачить різницю між посиланнями.
Gene

7
Ви можете замінити це значення атрибутом title, наприклад, <a href="javascript_required.html" title="Does Something" onclick="doSomething(); return false;"> go </a>
помітний компілятор

Це має бути найкращою практикою реєструвати запити на сторінці javascript_required.html та реєструвати функцію, яка спричинила помилку.
Тимо Хуовінен

2
Ви думали про наслідки для SEO?
DanielBlazquez

Виглядає, що javascripttoolbox.com Метта Круза не в мережі та продається.
showdev

10

Чому ви робите це, коли можете використовувати addEventListener/ attachEvent? Якщо немає href-еквівалента, не використовуйте <a>, використовуйте a <button>та стилізуйте його відповідно.


9
використання кнопки замість посилання у багатьох випадках не є можливим.
nickf

2
Бо це виглядає негарно. Ви можете додати піктограму біля посилання. Їх важко форматувати однаково в браузерах. І загалом люди переходять до посилань замість кнопок - подивіться на більшу частину стека.
Дарріл Хайн,

2
Виглядає негарно? Це схоже на те, як ви хочете, щоб це виглядало. Насправді, я думаю, що кнопки насправді мають більшу гнучкість стилю, ніж посилання, оскільки вони є вбудованими, але можуть належним чином заповнювати відступи між браузерами. Все, що можна зробити за допомогою посилання, можна зробити за допомогою кнопки, що стосується CSS.
безвічність

2
Розмах не можна орієнтувати на клавіатуру.
bobince

3
І кнопка (задихається) семантично правильна. Розмах семантично безглуздий. Кнопка - це саме те, що автор має намір використовувати семантично.
безвічність

5

Ви забули інший метод:

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

За допомогою коду JavaScript:

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

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


7
Якщо у вас є 20 або 30 різних посилань з JS, це може стати досить нудним і в кінцевому підсумку з великою кількістю JS.
Дарріл Хайн,

це не більш нудно, ніж перебирати HTML, щоб змінити javascript. ... або ви можете використати щось на зразок jQuery, який може легко змінювати події одночасно на декількох елементах ... $ ('# menu a'). click (function () {..})
nickf

1
@JKirchartz Я не розумію, як це проповідує, якщо за цією відповіддю є причини. Якщо ви прочитаєте питання, це справді "який із цих 4 найкращих", і я просто зазначив, що є ще один варіант, який він не розглядав.
nickf

Не хвилюйся, трололо, коли вибираєш між ABC і D, не обираєш E.
JKirchartz

3
@JKirchartz Так, я не думаю, що тоді ви справді досягли мети Stack Overflow. Якщо хтось запитує: "Для чого краще створити веб-програму: Кобол чи Фортран?" Прийнятно сказати цій людині, що вона не врахувала всі можливості. Питання явно не задається питанням "що з цих чотирьох речей найкраще".
nickf

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

Я зроблю це, або:

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

Залежно від ситуації. Для більших додатків найкращим є другий, оскільки тоді він консолідує ваш код події.


Якщо у вас є 20 або 30 різних посилань з JS, це може стати досить нудним і в кінцевому підсумку з великою кількістю JS.
Дарріл Хайн,

а помилки, які проникають у ваш код, можуть бути ДУЖЕ важкими для налагодження. Ці помилки з’являються дуже легко, про що свідчить ваш перший приклад. :)
nickf

1

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


Спосіб №2 чого? Запитання не залишаються в тому ж порядку, як коли ВИ бачили їх.
Діодей - Джеймс Макфарлейн,

Спосіб No4 не заплутує URI, якщо ви це обов’язково зробите return false. З цієї причини метод No4, мабуть, найкращий (з перерахованих).
Már Örlygsson

2
@Diodeus, я вважаю, що П'єр мав на увазі нумерований список у питанні , який насправді був там з моменту розміщення запитання.
безвічність

1

Я помітив між цим одну різницю:

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

і це:

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

якщо в обох випадках у вас є:

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

тоді для першого прикладу act2буде працювати до, act1а у другому прикладі буде навпаки.


1

Тільки сучасні браузери

<!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's 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>

Ви можете запустити це до того, як документ буде готовий, натискання кнопок спрацює, оскільки ми додаємо подію до документа.

Джерела:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.