Bagaimana cara menghentikan halaman web agar tidak bergulir ke atas saat link yang memicu JavaScript diklik?

140

Ketika saya memiliki tautan yang terhubung dengan acara jQuery atau JavaScript seperti:

<a href="#">My Link</a>

Bagaimana cara mencegah halaman bergulir ke atas? Ketika saya menghapus atribut href dari jangkar, halaman tidak menggulir ke atas tetapi tautan tampaknya tidak dapat diklik.

Achilles
sumber

Jawaban:

199

Anda perlu mencegah tindakan default untuk kejadian klik (yaitu menavigasi ke target tautan) terjadi.

Ada dua cara untuk melakukannya.

Pilihan 1: event.preventDefault()

Panggil .preventDefault()metode objek acara yang diteruskan ke penangan Anda. Jika Anda menggunakan jQuery untuk mengikat penangan Anda, peristiwa itu akan menjadi instance jQuery.Eventdan itu akan menjadi versi jQuery .preventDefault(). Jika Anda menggunakan addEventListeneruntuk mengikat penangan Anda, itu akan menjadi Eventdan versi DOM mentah dari .preventDefault(). Either way akan melakukan apa yang Anda butuhkan.

Contoh:

$('#ma_link').click(function($e) {
    $e.preventDefault();
    doSomething();
});

document.getElementById('#ma_link').addEventListener('click', function (e) {
    e.preventDefault();
    doSomething();
})

Pilihan 2: return false;

Di jQuery :

Menampilkan false dari event handler akan secara otomatis memanggil event.stopPropagation () dan event.preventDefault ()

Jadi, dengan jQuery, Anda dapat menggunakan pendekatan ini sebagai alternatif untuk mencegah perilaku tautan default:

$('#ma_link').click(function(e) {
     doSomething();
     return false;
});

Jika Anda menggunakan peristiwa DOM mentah, ini juga akan berfungsi di browser modern, karena spesifikasi HTML 5 menentukan perilaku ini. Namun, versi spesifikasi yang lebih lama tidak melakukannya, jadi jika Anda memerlukan kompatibilitas maksimum dengan browser lama, Anda harus memanggil .preventDefault()secara eksplisit. Lihat event.preventDefault () vs. return false (tanpa jQuery) untuk detail spesifikasi.

Paolo Bergantino
sumber
9
Memposting
Dalam kasus ini, Achilles hanya melakukan ini karena dia ingin tautan tersebut muncul sebagai dapat diklik, yang mana dia tidak perlu menggunakan href = "#" sama sekali. Lihat jawaban saya untuk info lebih lanjut.
achecopar
167

Anda dapat menyetel href menjadi #!sebagai ganti#

Sebagai contoh,

<a href="#!">Link</a>

tidak akan melakukan pengguliran saat diklik.

Awas! Ini masih akan menambahkan entri ke riwayat browser saat diklik, artinya setelah mengeklik tautan Anda, tombol kembali pengguna tidak akan membawa mereka ke halaman sebelumnya. Untuk alasan ini, mungkin lebih baik menggunakan .preventDefault()pendekatan tersebut, atau menggunakan keduanya dalam kombinasi.

Berikut ini adalah Fiddle yang menggambarkan hal ini (cukup geser ke bawah browser Anda sampai Anda mendapatkan scrollbar):
http://jsfiddle.net/9dEG7/


Untuk kutu buku spesifikasi - mengapa ini berfungsi:

Perilaku ini ditentukan dalam spesifikasi HTML5 di bawah bagian Menavigasi ke pengenal fragmen . Alasan link dengan a href "#"menyebabkan dokumen menggulir ke atas adalah karena perilaku ini secara eksplisit ditetapkan sebagai cara untuk menangani pengenal fragmen kosong:

2. Jika fragidstring kosong, maka bagian dokumen yang ditunjukkan adalah bagian atas dokumen

Menggunakan href dari "#!"malah berfungsi hanya karena menghindari aturan ini. Tidak ada keajaiban tentang tanda seru - ini hanya membuat pengenal fragmen yang nyaman karena sangat berbeda dengan fragid biasa dan tidak mungkin cocok dengan idatau namedari elemen di halaman Anda. Memang, kita bisa meletakkan hampir semua hal setelah hash; satu-satunya fragid yang tidak cukup adalah string kosong, kata 'top', atau string yang cocok nameatau idatribut elemen pada halaman.

Lebih tepatnya, kita hanya membutuhkan pengenal fragmen yang akan menyebabkan kita gagal ke langkah 8 dalam algoritme berikut untuk menentukan bagian yang ditunjukkan dari dokumen dari fragid:

  1. Terapkan algoritme pengurai URL ke URL, dan biarkan fragid menjadi komponen fragmen dari URL yang diurai.

  2. Jika fragidstring kosong, maka bagian dokumen yang ditunjukkan adalah bagian atas dokumen; hentikan algoritme di sini.

  3. Membiarkan fragid bytesmenjadi hasil decoding persen fragid.

  4. Membiarkan decoded fragidmenjadi hasil penerapan algoritma dekoder UTF-8 ke fragid bytes. Jika dekoder UTF-8 mengeluarkan kesalahan dekoder, batalkan dekoder dan lompat ke langkah berlabel no decoded fragid.

  5. Jika ada elemen di DOM yang memiliki ID yang sama persis dengan decoded fragid, maka elemen pertama dalam urutan hierarki adalah bagian dokumen yang ditunjukkan; hentikan algoritme di sini.

  6. Tidak ada fragid yang didekodekan : Jika ada elemen di DOM yang memiliki atribut nama yang nilainya persis sama dengan fragid( bukandecoded fragid ), maka elemen pertama dalam urutan hierarki adalah bagian yang ditunjukkan dari dokumen; hentikan algoritme di sini.

  7. Jika fragid adalah pencocokan tidak peka huruf besar / kecil ASCII untuk string tersebut top, maka bagian dokumen yang ditunjukkan adalah bagian atas dokumen; hentikan algoritme di sini.

  8. Jika tidak, tidak ada bagian dokumen yang ditunjukkan.

Selama kita mencapai langkah 8 dan tidak ada bagian dokumen yang ditunjukkan , aturan berikut mulai berlaku:

Jika tidak ada bagian yang ditunjukkan ... maka agen pengguna tidak boleh melakukan apa pun.

itulah sebabnya browser tidak menggulir.

Matt Crinklaw-Vogt
sumber
4
Tidak masalah jika Anda meletakkan '!' atau nilai lainnya, selama id tersebut bukan bagian dari DOM.
Gopinath
3
Setelah menjadi pendukung metode ini, saya telah melakukan 180 kali dan menyarankan agar tidak melakukannya. Hati-hati: link seperti ini masih akan mengubah URL halaman, menghasilkan entri tambahan dalam riwayat browser dan menyebabkan tombol "kembali" untuk menghapus fragmen dari URL dan tidak melakukan apa yang diharapkan pengguna. Jadi solusi ini sendiri, saat menjawab pertanyaan seperti yang ditanyakan, biasanya bukanlah alternatif yang diinginkan untuk digunakan preventDefault()dalam handler klik - sayangnya.
Mark Amery
1
Mengapa tidak menggunakan href = "javascript :;" sebagai gantinya? Sejauh yang saya tahu itu tidak akan mengubah riwayat browser. Diposting tentang itu di jawaban saya.
achecopar
Ini harus menjadi jawaban yang diterima
Aman
32

Pendekatan yang mudah adalah dengan memanfaatkan kode ini:

<a href="javascript:void(0);">Link Title</a>

Pendekatan ini tidak memaksa penyegaran halaman, sehingga scrollbar tetap di tempatnya. Selain itu, ini memungkinkan Anda untuk mengubah acara onclick secara terprogram dan menangani pengikatan acara sisi klien menggunakan jQuery.

Untuk alasan ini, solusi di atas lebih baik daripada:

<a href="javascript:myClickHandler();">Link Title</a>
<a href="#" onclick="myClickHandler(); return false;">Link Title</a>

di mana solusi terakhir akan menghindari masalah gulir-lompat jika dan hanya jika metode myClickHandler tidak gagal.

phreeskier.dll
sumber
12

Mengembalikan false dari kode yang Anda panggil akan berfungsi dan dalam beberapa situasi adalah metode yang disukai tetapi Anda juga bisa melakukannya

<a href="javascript:;">Link Title</a>

Ketika datang ke SEO, itu sangat tergantung pada apa tautan Anda akan digunakan untuk. Jika Anda benar-benar akan menggunakannya untuk menautkan ke beberapa konten lain maka saya setuju idealnya Anda menginginkan sesuatu yang berarti di sini tetapi jika Anda menggunakan tautan untuk tujuan fungsionalitas mungkin seperti yang dilakukan Stack Overflow untuk bilah alat pos (tebal, miring, hyperlink , dll) maka itu mungkin tidak masalah.

Dekan
sumber
10

Anda harus mengubah

<a href="#">My Link</a>

untuk

<a href="javascript:;">My Link</a>

Dengan cara ini ketika link diklik halaman tidak akan bergulir ke atas. Ini lebih bersih daripada menggunakan href = "#" dan kemudian mencegah acara default berjalan.

Saya punya alasan bagus untuk ini pada jawaban pertama untuk pertanyaan ini , seperti return false;tidak akan dieksekusi jika fungsi yang dipanggil membuat kesalahan, atau Anda dapat menambahkan return false;ke doSomething()fungsi dan kemudian lupa menggunakanreturn doSomething();

achecopar
sumber
7

Coba ini:

<a href="#" onclick="return false;">My Link</a>
mikeluby.dll
sumber
4

Jika Anda dapat mengubah hrefnilainya, Anda harus menggunakan:

<a href="javascript:void(0);">Link Title</a>

Solusi rapi lain yang baru saja saya buat adalah menggunakan jQuery untuk menghentikan tindakan klik terjadi dan menyebabkan halaman bergulir, tetapi hanya untuk href="#"tautan.

<script type="text/javascript">
    /* Stop page jumping when links are pressed */
    $('a[href="#"]').live("click", function(e) {
         return false; // prevent default click action from happening!
         e.preventDefault(); // same thing as above
    });
</script>
dazbradbury
sumber
Tentunya return falseharus setelah preventDefault()baris, jika tidak, Anda tidak akan pernah sampai ke baris kedua ini?
hobailey
3

Tautkan ke sesuatu yang lebih masuk akal daripada bagian atas halaman. Kemudian batalkan acara default.

Lihat aturan 2 dari peningkatan progresif pragmatis .

Quentin
sumber
Ini juga membuat situs Anda lebih ramah SEO.
Frankie
3

Selain itu, Anda dapat menggunakan event.preventDefault di dalam atribut onclick .

<a href="#" onclick="event.preventDefault(); doSmth();">doSmth</a>

Tidak perlu menulis acara klik exstra.

efirat
sumber
0

Anda juga dapat menulis seperti ini: -

<a href="#!" onclick="function()">Delete User</a>
pengguna2436792
sumber
0

Saat memanggil fungsi, ikuti dengan return false contoh:

<input  type="submit" value="Add" onclick="addNewPayment();return false;">
buddhi weerasinghe
sumber
0

Buat halaman yang berisi dua tautan - satu di atas dan satu lagi di bawah. Saat mengklik link atas, halaman tersebut harus menggulir ke bawah ke bagian bawah halaman di mana terdapat link bawah. Saat mengklik link bawah, halaman harus menggulir ke atas ke bagian atas halaman.

Damini
sumber
0
<a onclick="yourfunction()">

ini akan bekerja dengan baik. tidak perlu menambahkan href = "#"

Varaj Vignesh
sumber
0

Anda mungkin ingin memeriksa CSS Anda. Dalam contoh di sini: https://css-tricks.com/the-checkbox-hack/ ada position: absolute; top: -9999px;. Ini sangat konyol di Chrome, sepertionclick="whatever" masih melompat ke posisi absolut dari elemen yang diklik.

Menghapus position: absolute; top: -9999px;, display: none;mungkin bisa membantu.

Scott Phillips
sumber
0

Untuk Bootstrap 3 untuk penciutan, jika Anda tidak menentukan data-target pada jangkar dan mengandalkan href untuk menentukan target, kejadian tersebut akan dicegah. Jika Anda menggunakan target data, Anda harus mencegah acara tersebut sendiri.

<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#demo">Collapse This</button>

<div id="demo" class="collapse"> 
<p>Lorem ipsum dolor sit amet</p>
</div>
doug
sumber