Apa perbedaan antara metode yang berbeda dalam meletakkan kode JavaScript di <a>?

87

Saya telah melihat metode berikut untuk menempatkan kode JavaScript di <a>tag:

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>

Saya memahami gagasan untuk mencoba menempatkan URL yang valid alih-alih hanya kode JavaScript, untuk berjaga-jaga jika pengguna tidak mengaktifkan JavaScript. Tetapi untuk tujuan diskusi ini, saya perlu berasumsi JavaScript diaktifkan (mereka tidak dapat masuk tanpanya).

Saya pribadi menyukai opsi 2 karena memungkinkan Anda untuk melihat apa yang akan dijalankan - terutama berguna saat men-debug di mana ada parameter yang diteruskan ke fungsi. Saya telah menggunakannya cukup lama dan tidak menemukan masalah browser.

Saya telah membaca bahwa orang merekomendasikan 4, karena memberi pengguna tautan nyata untuk diikuti, tetapi sebenarnya, # tidak "nyata". Ini sama sekali tidak akan pergi kemana-mana.

Apakah ada yang tidak mendukung atau benar-benar buruk, ketika Anda mengetahui pengguna telah mengaktifkan JavaScript?

Pertanyaan terkait: Href untuk tautan JavaScript: “#” atau “javascript: void (0)”? .

Darryl Hein
sumber
Masalah sintaksis kecil: Pilihan # 2 harus - <a href="javascript:DoSomething();"> tautan </a> tanpa "return"
DRosenfeld
Harap ubah jawaban yang diterima menjadi jawaban @eyelidlessness. Saya pikir itu pendekatan terbaik, karena peduli dengan semantik.
Michał Perłakowski

Jawaban:

69

Saya cukup menikmati artikel Praktik Terbaik Javascript Matt Kruse . Di dalamnya, dia menyatakan bahwa menggunakan hrefbagian untuk mengeksekusi kode JavaScript adalah ide yang buruk. Meskipun Anda telah menyatakan bahwa pengguna Anda harus mengaktifkan JavaScript, tidak ada alasan Anda tidak dapat memiliki halaman HTML sederhana yang dapat ditunjukkan oleh semua tautan JavaScript Anda untuk hrefbagian mereka jika seseorang mematikan JavaScript setelah masuk. Saya akan sangat menganjurkan Anda untuk tetap mengizinkan mekanisme fallback ini. Sesuatu seperti ini akan mematuhi "praktik terbaik" dan mencapai tujuan Anda:

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>
cowgod
sumber
4
karena nilai href akan ditampilkan kepada pengguna di bilah status? (bilah di bagian bawah) Saya akan mempertimbangkan untuk menggunakan tautan yang lebih ramah pengguna misalnya. "js.html? doSomething" halaman masih dapat berupa html statis. Dengan cara ini pengguna akan melihat dengan jelas perbedaan antara tautan.
Gene
7
Anda dapat mengganti nilai ini dengan atribut judul, misalnya <a href="javascript_required.html" title="Does Something" onclick="doSomething(); return false;"> go </a>
Conspicuous Compiler
Praktik terbaiknya adalah mencatat permintaan ke halaman javascript_required.html dan mencatat fungsi yang menyebabkan kesalahan.
Timo Huovinen
2
Pernahkah Anda memikirkan tentang konsekuensi SEO?
DanielBlazquez
Javascripttoolbox.com Matt Kruse tampaknya sedang offline dan untuk dijual.
showdev
10

Mengapa Anda melakukan ini saat Anda bisa menggunakan addEventListener / attachEvent? Jika tidak ada href-equivalent, jangan gunakan <a>, gunakan a <button>dan beri gaya yang sesuai.

kelopak mata
sumber
9
menggunakan tombol alih-alih tautan bukanlah opsi yang layak dalam banyak kasus.
nickf
2
Karena terlihat jelek. Anda dapat menambahkan ikon di samping tautan. Mereka sulit untuk memformat yang sama di seluruh browser. Dan umumnya, orang-orang beralih ke tautan alih-alih tombol - lihat sebagian besar tumpukan berlebih.
Darryl Hein
2
Ini terlihat jelek? Terlihat seperti apa pun yang Anda inginkan. Faktanya, menurut saya tombol sebenarnya memiliki fleksibilitas gaya yang lebih besar daripada tautan, karena tombol tersebut sebaris tetapi dapat mengambil padding dengan baik di seluruh browser. Apa pun yang dapat dilakukan dengan tautan dapat dilakukan dengan sebuah tombol, berkaitan dengan CSS.
Kelopak mata
2
Span tidak dapat difokuskan pada keyboard.
bobince
3
Dan tombol (terkesiap) benar secara semantik. Rentang secara semantik tidak berarti. Tombol persis seperti yang ingin digunakan penulis, secara semantik.
Kelopak mata
5

Anda lupa metode lain:

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

Dengan kode JavaScript:

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

Saya tidak dapat berkomentar tentang opsi mana yang memiliki dukungan terbaik atau mana yang secara semantik terbaik, tetapi saya hanya akan mengatakan bahwa saya lebih suka gaya ini karena memisahkan konten Anda dari kode JavaScript Anda. Itu membuat semua kode JavaScript bersama-sama, yang jauh lebih mudah untuk dipertahankan (terutama jika Anda menerapkan ini ke banyak tautan), dan Anda bahkan dapat meletakkannya di file eksternal yang kemudian dapat dikemas untuk mengurangi ukuran file dan di-cache oleh browser klien.

nickf
sumber
7
Jika Anda memiliki 20 atau 30 tautan berbeda dengan JS, ini bisa sangat membosankan dan berakhir dengan banyak JS.
Darryl Hein
itu tidak lebih membosankan daripada mengarungi HTML untuk mengubah javascript. ... atau Anda dapat menggunakan sesuatu seperti jQuery yang dapat dengan mudah mengubah kejadian pada beberapa elemen sekaligus ... $ ('# menu a'). click (function () {..})
nickf
1
@JKirchartz Saya tidak melihat bagaimana itu berkhotbah jika ada alasan di balik jawabannya. Jika Anda membaca pertanyaannya, itu benar-benar "yang mana dari 4 yang terbaik", dan saya hanya menunjukkan bahwa ada opsi lain yang tidak dia pertimbangkan.
nickf
Tidak peduli, trololo, ketika memilih antara ABC dan D, seseorang tidak memilih E.
JKirchartz
3
@JKirchartz Ya, saya rasa Anda belum benar-benar memahami tujuan Stack Overflow. Jika seseorang bertanya "Mana yang lebih baik untuk membuat aplikasi web di: Cobol atau Fortran?" Dapat diterima untuk memberi tahu orang itu bahwa mereka belum mempertimbangkan semua kemungkinan. Pertanyaannya jelas bukan menanyakan "mana dari empat hal ini yang terbaik".
nickf
3
<a href="#" onClick="DoSomething(); return false;">link</a>

Saya akan melakukan ini, atau:

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

Tergantung situasinya. Untuk aplikasi yang lebih besar, yang kedua adalah yang terbaik karena ini menggabungkan kode acara Anda.

Anik Islam Abhi
sumber
Jika Anda memiliki 20 atau 30 tautan berbeda dengan JS, ini bisa sangat membosankan dan berakhir dengan banyak JS.
Darryl Hein
dan bug yang menyusup ke dalam kode Anda bisa SANGAT sulit untuk di-debug. Bug ini muncul dengan sangat mudah, seperti yang dibuktikan dengan contoh pertama Anda. :)
nickf
1

Metode # 2 memiliki kesalahan sintaks di FF3 dan IE7. Saya lebih suka metode # 1 dan # 3, karena # 4 mengotori URI dengan '#' meskipun menyebabkan lebih sedikit pengetikan ... Jelas, seperti dicatat oleh tanggapan lain, solusi terbaik adalah memisahkan html dari penanganan acara.

Pier Luigi
sumber
Metode # 2 dari apa? Pertanyaannya tidak tetap dalam urutan yang sama seperti saat ANDA melihatnya.
Diodeus - James MacFarlane
Metode # 4 tidak akan mengacaukan URI jika Anda yakin melakukannya return false. Untuk alasan itu metode # 4 mungkin yang terbaik (dari yang terdaftar).
Már Örlygsson
2
@ Diodeus, saya yakin Pier mengacu pada daftar bernomor dalam pertanyaan , yang sebenarnya sudah ada sejak pertanyaan itu diposting di tempat pertama.
Kelopak mata
1

Satu perbedaan yang saya perhatikan antara ini:

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

dan ini:

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

adalah jika dalam kedua kasus Anda memiliki:

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

lalu untuk contoh pertama act2akan berjalan sebelum act1dan pada contoh kedua akan berjalan sebaliknya.

JoelFan
sumber
1

Hanya browser modern

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

Lintas browser

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

Anda dapat menjalankan ini sebelum dokumen siap, mengklik tombol akan berfungsi karena kami melampirkan acara ke dokumen.

Sumber:

Timo Huovinen
sumber