javascript - Cara menonaktifkan tautan HTML


Saya memiliki tombol tautan di dalam <td> yang harus saya nonaktifkan. Ini bekerja di IE tetapi tidak berfungsi di Firefox dan Chrome.

Saya sudah mencoba semua hal berikut tetapi tidak berhasil di Firefox (menggunakan js 1.4.2):

$(".myLink").attr('disabled', 'disabled');

$(".myLink").attr('disabled', true);

$(".myLink").attr('disabled', 'true');

Catatan - Saya tidak dapat membatalkan pendaftaran fungsi klik untuk tag anchor karena itu didaftarkan secara dinamis. DAN SAYA HARUS MENAMPILKAN LINK DALAM MODE NONAKTIF.

Jawaban #1

Anda tidak bisa menonaktifkan tautan (dengan cara yang portabel). Anda bisa menggunakan salah satu dari teknik ini (masing-masing memiliki keuntungan dan kerugiannya sendiri).

cara CSS

Ini seharusnya cara yang benar (tetapi lihat nanti) untuk melakukannya ketika sebagian besar browser akan mendukungnya:

a.disabled {
    pointer-events: none;
}

Itu adalah apa yang, misalnya, dilakukan oleh Bootstrap 3.x. Saat ini (2016) ini hanya didukung dengan baik oleh Chrome, FireFox, dan Opera (19+). Internet Explorer mulai mendukung ini dari versi 11 tetapi tidak untuk tautan, namun tersedia di elemen luar seperti:

span.disable-links {
    pointer-events: none;
}

Dengan :

<span class="disable-links"><a href="#">...</a></span>

Solusi sementara

Kita, kemungkinan, perlu mendefinisikan kelas CSS untuk pointer-events: none tetapi bagaimana jika kita menggunakan kembali atribut disabled daripada kelas CSS? Secara teknis disabled tidak didukung untuk <a> tetapi browser tidak akan mengeluh terhadap atribut tidak dikenal. Dengan menggunakan atribut disabled, IE akan mengabaikan pointer-events tetapi akan menghormati atribut disabled khusus IE; browser lain yang mematuhi CSS akan mengabaikan atribut disabled yang tidak dikenal dan menghormati pointer-events. Lebih mudah untuk menulis daripada menjelaskan:

a[disabled] {
    pointer-events: none;
}

Pilihan lain untuk IE 11 adalah mengatur display dari elemen tautan menjadi block atau inline-block:

<a style="pointer-events: none; display: inline-block;" href="#">...</a>

Perlu dicatat bahwa ini mungkin merupakan solusi portabel jika Anda perlu mendukung IE (dan Anda dapat mengubah HTML Anda) tetapi...

Dengan semua yang telah dikatakan, harap dicatat bahwa pointer-events hanya menonaktifkan...event pointer. Tautan masih dapat dinavigasi melalui keyboard sehingga Anda juga perlu menerapkan salah satu teknik lain yang dijelaskan di sini.

Fokus

Bersamaan dengan teknik CSS yang dijelaskan di atas, Anda dapat menggunakan tabindex dengan cara non-standar untuk mencegah suatu elemen mendapatkan fokus:

<a href="#" disabled tabindex="-1">...</a>

Saya tidak pernah memeriksa kompatibilitasnya dengan banyak browser, jadi Anda mungkin ingin mengujinya sendiri sebelum menggunakannya. Ini memiliki keuntungan dapat bekerja tanpa JavaScript. Sayangnya (tetapi tentu saja) tabindex tidak dapat diubah dari CSS.

Mencegat klik

Gunakan href ke fungsi JavaScript, periksa kondisinya (atau atribut disabled itu sendiri) dan jangan lakukan apa-apa jika demikian.

$("td > a").on("click", function(event){
    if ($(this).is("[disabled]")) {
        event.preventDefault();
    }
});

Untuk menonaktifkan tautan, lakukan ini:

$("td > a").attr("disabled", "disabled");

Untuk mengaktifkan kembali mereka:

$("td > a").removeAttr("disabled");

Jika Anda ingin, alih-alih .is("[disabled]") Anda bisa menggunakan .attr("disabled") != undefined (jQuery 1.6+ akan selalu mengembalikan undefined ketika atribut tidak diatur) tetapi is() jauh lebih jelas (terima kasih kepada Dave Stewart untuk tip ini). Harap dicatat di sini saya menggunakan atribut disabled dengan cara yang tidak standar, jika Anda mempermasalahkan ini maka ganti atribut dengan kelas dan ganti .is("[disabled]") dengan .hasClass("disabled") (menambah dan menghapus dengan addClass() dan removeClass()).

Zoltán Tamási mencatat dalam sebuah komentar bahwa "dalam beberapa kasus, peristiwa klik sudah terkait dengan beberapa fungsi 'riil' (misalnya menggunakan knockoutjs). Dalam hal ini, urutan penanganan peristiwa bisa menimbulkan masalah. Oleh karena itu, saya mengimplementasikan link yang dinonaktifkan dengan mengaitkan penanganan return false pada peristiwa touchstart, mousedown, dan keydown pada link. Hal ini memiliki beberapa kekurangan (akan mencegah pengguliran sentuhan yang dimulai pada link)", tetapi menangani peristiwa keyboard juga memiliki manfaat untuk mencegah navigasi keyboard.

Perhatikan bahwa jika href tidak dibersihkan, pengguna bisa saja secara manual mengunjungi halaman tersebut.

Bersihkan tautan

Hapus atribut href. Dengan kode ini Anda tidak menambahkan pengelola acara tetapi mengubah tautan itu sendiri. Gunakan kode ini untuk menonaktifkan tautan:

$("td > a").each(function() {
    this.data("href", this.attr("href"))
        .attr("href", "javascript:void(0)")
        .attr("disabled", "disabled");
});

Dan yang ini untuk mengaktifkannya kembali:

$("td > a").each(function() {
    this.attr("href", this.data("href")).removeAttr("disabled");
});

Secara pribadi saya tidak terlalu menyukai solusi ini (jika Anda tidak harus melakukan lebih banyak dengan tautan yang dinonaktifkan) tetapi ini mungkin lebih kompatibel karena berbagai cara untuk mengikuti tautan.

Penangan klik palsu

Tambahkan/hapus fungsi onclick di mana Anda return false, tautan tidak akan diikuti. Untuk menonaktifkan tautan:

$("td > a").attr("disabled", "disabled").on("click", function() {
    return false; 
});

Untuk mengaktifkan kembali mereka:

$("td > a").removeAttr("disabled").off("click");

Saya tidak berpikir ada alasan untuk memilih solusi ini dibandingkan yang pertama.

Gaya

Penataan bahkan lebih sederhana, apa pun solusi yang Anda gunakan untuk menonaktifkan tautan, kami telah menambahkan atribut disabled sehingga Anda dapat menggunakan aturan CSS berikut:

a[disabled] {
    color: gray;
}

Jika Anda menggunakan kelas daripada atribut:

a.disabled {
    color: gray;
}

Jika Anda menggunakan kerangka kerja UI, Anda mungkin melihat bahwa tautan disabled tidak ditata dengan benar. Bootstrap 3.x, misalnya, menangani skenario ini dan tombol ditata dengan benar baik dengan atribut disabled maupun dengan kelas .disabled. Jika, sebagai gantinya, Anda menghapus tautan (atau menggunakan salah satu teknik JavaScript lainnya) Anda juga harus menangani penataan karena <a> tanpa href masih terlihat seperti aktif.

Aplikasi Internet Kaya yang Dapat Diakses (ARIA)

Jangan lupa juga untuk menyertakan atribut aria-disabled="true" bersama dengan atribut/kelas disabled.

Jawaban #2

Mendapatkan perbaikan di CSS.

td.disabledAnchor a{
       pointer-events: none !important;
       cursor: default;
       color:Gray;
}

CSS di atas ketika diterapkan pada tag anchor akan menonaktifkan event klik.

Untuk detailnya cek link ini

Jawaban #3

Terima kasih kepada semua orang yang memposting solusi (terutama @AdrianoRepetti), saya menggabungkan beberapa pendekatan untuk memberikan beberapa fungsionalitas disabled yang lebih canggih (dan ini bekerja di berbagai browser). Kodenya ada di bawah ini (baik berbasis ES2015 maupun coffeescript sesuai preferensi Anda).

Ini menyediakan beberapa tingkat pertahanan sehingga Anchors yang ditandai sebagai nonaktif benar-benar berperilaku demikian. Dengan menggunakan pendekatan ini, Anda mendapatkan sebuah anchor yang tidak dapat Anda:

  • klik
  • tab ke dan tekan return
  • menekan tab ke sana akan memindahkan fokus ke elemen yang dapat difokuskan berikutnya
  • itu sadar jika jangkar kemudian diaktifkan

Bagaimana caranya

  1. Sertakan CSS ini, karena ini adalah garis pertahanan pertama. Ini mengasumsikan selector yang Anda gunakan adalah a.disabled

    a.disabled {
      pointer-events: none;
      cursor: default;
    }
    
  2. Selanjutnya, buat instance dari kelas ini saat siap (dengan selector opsional):

      new AnchorDisabler()
    

Kelas ES2015

npm install -S key.js
import {Key, Keycodes} from 'key.js'

export default class AnchorDisabler {
  constructor (config = { selector: 'a.disabled' }) {
    this.config = config
    $(this.config.selector)
      .click((ev) => this.onClick(ev))
      .keyup((ev) => this.onKeyup(ev))
      .focus((ev) => this.onFocus(ev))
  }

  isStillDisabled (ev) {
    //  since disabled can be a class or an attribute, and it can be dynamically removed, always recheck on a watched event
    let target = $(ev.target)
    if (target.hasClass('disabled') || target.prop('disabled') == 'disabled') {
      return true
    }
    else {
      return false
    }
  }

  onFocus (ev) {
    //  if an attempt is made to focus on a disabled element, just move it along to the next focusable one.
    if (!this.isStillDisabled(ev)) {
      return
    }

    let focusables = $(':focusable')
    if (!focusables) {
      return
    }

    let current = focusables.index(ev.target)
    let next = null
    if (focusables.eq(current + 1).length) {
      next = focusables.eq(current + 1)
    } else {
      next = focusables.eq(0)
    }

    if (next) {
      next.focus()
    }
  }

  onClick (ev) {
    // disabled could be dynamically removed
    if (!this.isStillDisabled(ev)) {
      return
    }

    ev.preventDefault()
    return false
  }

  onKeyup (ev) {
    // We are only interested in disabling Enter so get out fast
    if (Key.isNot(ev, Keycodes.ENTER)) {
      return
    }

    // disabled could be dynamically removed
    if (!this.isStillDisabled(ev)) {
      return
    }

    ev.preventDefault()
    return false
  }
}

Kelas Coffeescript:

class AnchorDisabler
  constructor: (selector = 'a.disabled') ->
    $(selector).click(@onClick).keyup(@onKeyup).focus(@onFocus)

  isStillDisabled: (ev) =>
    ### since disabled can be a class or an attribute, and it can be dynamically removed, always recheck on a watched event ###
    target = $(ev.target)
    return true if target.hasClass('disabled')
    return true if target.attr('disabled') is 'disabled'
    return false

  onFocus: (ev) =>
    ### if an attempt is made to focus on a disabled element, just move it along to the next focusable one. ###
    return unless @isStillDisabled(ev)

    focusables = $(':focusable')
    return unless focusables

    current = focusables.index(ev.target)
    next = (if focusables.eq(current + 1).length then focusables.eq(current + 1) else focusables.eq(0))

    next.focus() if next


  onClick: (ev) =>
    # disabled could be dynamically removed
    return unless @isStillDisabled(ev)

    ev.preventDefault()
    return false

  onKeyup: (ev) =>

    # 13 is the js key code for Enter, we are only interested in disabling that so get out fast
    code = ev.keyCode or ev.which
    return unless code is 13

    # disabled could be dynamically removed
    return unless @isStillDisabled(ev)

    ev.preventDefault()
    return false

Artikel terkait