Acara pada input yang dinonaktifkan

234

Rupanya orang cacat <input>tidak ditangani oleh peristiwa apa pun

Apakah ada cara untuk mengatasi masalah ini?

<input type="text" disabled="disabled" name="test" value="test" />
$(':input').click(function () {
    $(this).removeAttr('disabled');
})

Di sini, saya perlu mengklik input untuk mengaktifkannya. Tetapi jika saya tidak mengaktifkannya, input tidak boleh diposting.

Pierre de LESPINAY
sumber
Berikut ini adalah blog
Anda dapat menggunakan CSS-pretend-disable dan lewati input di onSubmit handler, nonaktifkan yang tidak diaktifkan secara nyata.
ptrk

Jawaban:

267

Elemen yang dinonaktifkan tidak memecat acara mouse. Sebagian besar browser akan menyebarkan acara yang berasal dari elemen yang dinonaktifkan di atas pohon DOM, sehingga penangan acara dapat ditempatkan pada elemen kontainer. Namun, Firefox tidak menunjukkan perilaku ini, ia tidak melakukan apa-apa ketika Anda mengklik elemen yang dinonaktifkan.

Saya tidak bisa memikirkan solusi yang lebih baik tetapi, untuk kompatibilitas lintas browser lengkap, Anda dapat menempatkan elemen di depan input yang dinonaktifkan dan menangkap klik pada elemen itu. Berikut ini contoh yang saya maksud:

<div style="display:inline-block; position:relative;">
  <input type="text" disabled />
  <div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div>
</div>​

jq:

$("div > div").click(function (evt) {
    $(this).hide().prev("input[disabled]").prop("disabled", false).focus();
});​

Contoh: http://jsfiddle.net/RXqAm/170/ (diperbarui untuk menggunakan jQuery 1.7 dengan propalih - alih attr).

Andy E
sumber
2
Hal kecil: jika Anda menggunakan disabledatribut tanpa nilai, itu menyiratkan HTML daripada XHTML, dalam hal ini slash penutup tidak diperlukan.
Tim Down
11
@Tim: memang tidak perlu, tapi itu masih HTML yang valid. Itu hanya kekuatan kebiasaan dan saya merasa itu terlihat lebih baik.
Andy E
1
Terima kasih Andy, ini cukup pintar. Apakah tidak ada yang lebih sederhana? Apakah Anda tahu mengapa input yang difabel tidak dapat ditangani?
Pierre de LESPINAY
2
Ini tidak masuk akal: elemen html lainnya menangani peristiwa mouse, mengapa tidak elemen yang dinonaktifkan (mis. mouseenter, Dll.)
Augustin Riedinger
7
Anda dapat menghentikan elemen yang dinonaktifkan dari "membuang" klik Anda dengan memasukkan input[disabled] {pointer-events:none}CSS Anda. Kemudian klik berperilaku seolah-olah Anda mengklik elemen induk. IMHO ini adalah solusi paling sederhana dan terbersih, tetapi sayangnya ini hanya berfungsi untuk browser yang mendukung pointer-eventsproperti CSS: caniuse.com/#search=pointer-events
Doin
70

Mungkin Anda bisa membuat bidang hanya baca dan kirim menonaktifkan semua bidang hanya baca

$(".myform").submit(function(e) {
    $("input[readonly]", this).attr("disabled", true);
});

dan input (+ skrip) seharusnya

<input type="text" readonly="readonly" name="test" value="test" />

$('input[readonly]').click(function () {
    $(this).removeAttr('readonly');
})
Tokimon
sumber
5
+1, ini adalah saran alternatif yang layak. Satu-satunya downside adalah bahwa kotak input tidak akan mengambil styling dinonaktifkan, yang bervariasi antara browser sehingga akan sulit untuk membuatnya terlihat konsisten dengan harapan pengguna dari input yang dinonaktifkan.
Andy E
benar. Mungkin ini bisa diselesaikan dengan CSS? Tapi ya itu tidak akan memiliki tampilan yang sama dengan bidang input yang diaktifkan normal
Tokimon
Solusi alternatif yang sangat baik. Saya suka yang ini lebih baik karena Anda dapat melakukan styling yang diperlukan dengan CSS (yaitu membuatnya TERLIHAT dinonaktifkan) namun masih ada acara yang tersedia.
Joshua
62

Elemen yang dinonaktifkan "memakan" klik di beberapa browser - mereka tidak meresponsnya, atau membiarkannya ditangkap oleh penangan acara di mana pun baik pada elemen atau salah satu wadahnya.

IMHO cara termudah dan terbersih untuk "memperbaiki" ini (jika Anda memang perlu menangkap klik pada elemen yang dinonaktifkan seperti OP) adalah hanya dengan menambahkan CSS berikut ke halaman Anda:

input[disabled] {pointer-events:none}

Ini akan membuat klik pada input yang dinonaktifkan jatuh ke elemen induk, di mana Anda dapat menangkapnya secara normal. (Jika Anda memiliki beberapa input yang dinonaktifkan, Anda mungkin ingin memasukkan masing-masing ke dalam wadah tersendiri, jika belum ditata seperti itu - tambahan <span>atau <div>, katakanlah - hanya untuk memudahkan membedakan input yang dinonaktifkan mana yang diklik).


Kelemahannya adalah bahwa trik ini sayangnya tidak akan berfungsi untuk browser lama yang tidak mendukung pointer-eventsproperti CSS. (Ini harus bekerja dari IE 11, FF v3.6, Chrome v4): caniuse.com/#search=pointer-events

Jika Anda perlu mendukung browser lama, Anda harus menggunakan salah satu jawaban lain!

Lakukan
sumber
Saya tidak yakin apakah input[disabled]juga akan mencocokkan elemen yang dinonaktifkan oleh JavaScript ( element.disabled = true;) tetapi sepertinya itu cocok. Lagi pula, saya menemukan input:disabledpembersih.
Martin
Ini sepertinya solusi yang bagus, tidak bekerja untuk saya di IE11! Anda juga mengatakan FF 38+ dan Chrome 31+ tetapi tautan caniuse Anda mengatakan FF 3.6+ dan Chrome 4+?
user764754
@ user764754 ... kesalahan saya, saya tidak menyadari bahwa saya perlu mengklik "Tampilkan Semua" pada halaman caniuse untuk mendapatkan versi browser yang lebih lama! Telah memperbaikinya. Sedangkan untuk IE11, saya baru saja mengujinya, dan berfungsi dengan baik (lihat jsfiddle.net/7kkszq1c/1 untuk kode tersebut, meskipun untuk beberapa alasan situs jsFiddle tidak bekerja untuk saya di IE11, saya harus menempelkannya ke dalam. bukan file htm)
Lakukan
Terima kasih atas pembaruannya! Sementara itu saya juga mengamati bahwa itu berfungsi di situs web di IE11 tetapi tidak dengan jsfiddle. Mungkin karena jsfiddle iframe ...
user764754
2
@Protectorone: disabled adalah pseudo-class sejak CSS 3: w3.org/TR/css3-selectors/#UIstates
Martin
15

Saya akan menyarankan alternatif - gunakan CSS:

input.disabled {
    user-select : none;
    -moz-user-select : none;
    -webkit-user-select : none;
    color: gray;
    cursor: pointer;
}

alih-alih atribut yang dinonaktifkan. Kemudian, Anda dapat menambahkan atribut CSS Anda sendiri untuk mensimulasikan input yang dinonaktifkan, tetapi dengan kontrol lebih.

Ron Reiter
sumber
4
hanya bekerja dengan ie10, terlalu banyak pengguna memiliki ie9 / 8. jadi bukan alternatif yang dapat diandalkan.
mengkodekan
Ini masih menyebabkan bidang untuk diposting ketika formulir dikirimkan, yang tidak diinginkan dalam banyak kasus.
cimmanon
7

$(function() {

  $("input:disabled").closest("div").click(function() {
    $(this).find("input:disabled").attr("disabled", false).focus();
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<div>
  <input type="text" disabled />
</div>

Rejeesh Prarath
sumber
5
Tapi ini tidak berhasil pada FireFox - dan itulah intinya!
GarethOwen
6

Alih-alih disabled, Anda bisa mempertimbangkan untuk menggunakan readonly. Dengan beberapa CSS tambahan, Anda dapat mendesain input sehingga tampak seperti disabledbidang.

Sebenarnya ada masalah lain. Peristiwa changehanya memicu ketika elemen kehilangan fokus, yang tidak logis mempertimbangkan disabledbidang. Mungkin Anda mendorong data ke bidang ini dari panggilan lain. Untuk membuat ini berfungsi, Anda dapat menggunakan acara 'bind'.

$('form').bind('change', 'input', function () {
    console.log('Do your thing.');
});
Nykac
sumber
Masukan yang hanya dibaca akan tetap dikirimkan dengan formulir jika saya tidak salah
Pierre de LESPINAY
Itu benar. Kemudian harus dikombinasikan dengan @npth anwsner.
Nykac
Terima kasih, itu cerdas dan optimal untuk kasus saya.
Sultanos
4

ATAU lakukan ini dengan jQuery dan CSS!

$('input.disabled').attr('ignore','true').css({
    'pointer-events':'none',
     'color': 'gray'
});

Dengan cara ini Anda membuat elemen terlihat dinonaktifkan dan tidak ada peristiwa pointer akan menyala, namun memungkinkan propagasi dan jika dikirimkan Anda dapat menggunakan atribut 'abaikan' untuk mengabaikannya.

sidonaldson
sumber
@Precastic, itu benar, tetapi ia bekerja untuk hampir semua browser lain pada saat ini dan Anda dapat menggunakan polyfill yaitu <11 . sidonaldson, mengapa tidak menggunakan CSS langsung untuk menerapkan gaya?
KyleMit
@KyleMit Anda bisa menambahkan kelas daripada mengatur gaya, tapi bukan itu yang dimaksud dengan utas ini! Saya hanya menyarankan peristiwa pointer yang masih merupakan jawaban yang baik dan benar tergantung pada matriks peramban yang sedang Anda buat. Dan terima kasih untuk semua yang telah menandai jawaban ini yang agak menyebalkan karena tidak ada yang salah di sini: /
sidonaldson
1
@idonaldson, Ini jawaban yang bagus jadi saya juga berharap peringkatnya juga lebih tinggi. Saya tidak yakin apa yang dilakukan atribut abaikan . Tetapi poin saya tentang CSS adalah bahwa saya tidak berpikir kita perlu jQuery untuk menjadi alat untuk menerapkan CSS. Anda bisa saja mengatur aturan CSS yang menargetkan pemilih yang sama dan juga menonaktifkan acara pointer. Dalam biola ini , jQuery dan CSS harus melakukan hal yang sama, tetapi CSS akan jauh lebih hebat.
KyleMit
@KyleMit ah, dengan asumsi formulir dikirimkan, Anda harus entah bagaimana memberitahu backend untuk mengabaikan bidang itu jika berisi nilai (karena kami spoofing dinonaktifkan).
sidonaldson
Saya setuju CSS bisa lebih kuat karena Anda dapat menggunakan pemilih berdasarkan atribut! Lihat demo ini tempat saya mencocokkan bidang chrom
sidonaldson
0

Kami memiliki masalah hari ini seperti ini, tetapi kami tidak ingin mengubah HTML. Jadi kami menggunakan acara mouseenter untuk mencapai itu

var doThingsOnClick = function() {
    // your click function here
};

$(document).on({
    'mouseenter': function () {
        $(this).removeAttr('disabled').bind('click', doThingsOnClick);
    },
    'mouseleave': function () {
        $(this).unbind('click', doThingsOnClick).attr('disabled', 'disabled');
    },
}, 'input.disabled');
Raul Sanchez
sumber
-1

Saya menemukan solusi lain:

<input type="text" class="disabled" name="test" value="test" />

Elemen "cacat" elemen cacat dinonaktifkan dengan opacity:

<style type="text/css">
    input.disabled {
        opacity: 0.5;
    }
</style>

Dan kemudian membatalkan acara jika elemen dinonaktifkan dan menghapus kelas:

$(document).on('click','input.disabled',function(event) {
    event.preventDefault();
    $(this).removeClass('disabled');
});
npth
sumber
Bagian JavaScript tidak berfungsi untuk saya. Selain itu, itu tidak menjawab pertanyaan, karena ini adalah tentang mengaktifkan input yang dinonaktifkan. Namun dalam contoh ini tidak dinonaktifkan di awal, dan dengan demikian akan dikirim saat dikirimkan.
Raimund Krämer
-2

saran di sini terlihat seperti kandidat yang baik untuk pertanyaan ini juga

Melakukan acara klik pada elemen yang dinonaktifkan? Javascript jQuery

jQuery('input#submit').click(function(e) {
    if ( something ) {        
        return false;
    } 
});
katzmopolitan
sumber
Acara klik mungkin tidak akan terjadi pada atribut yang dinonaktifkan.
Hello Universe