Evento su un input disabilitato


234

Apparentemente un disabile <input>non è gestito da nessun evento

C'è un modo per aggirare questo problema?

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

Qui, devo fare clic sull'input per abilitarlo. Ma se non lo attivo, l'input non dovrebbe essere pubblicato.



Puoi usare CSS-pretend-disable e scorrere gli input nel gestore onSubmit, disabilitando quelli non attivati ​​per davvero.
ptrk,

Risposte:


267

Gli elementi disabilitati non generano eventi del mouse. La maggior parte dei browser propagherà un evento originato dall'elemento disabilitato nella struttura DOM, quindi i gestori di eventi potrebbero essere posizionati su elementi contenitore. Tuttavia, Firefox non presenta questo comportamento, non fa assolutamente nulla quando si fa clic su un elemento disabilitato.

Non riesco a pensare a una soluzione migliore ma, per una completa compatibilità tra browser, potresti posizionare un elemento davanti all'input disabilitato e catturare il clic su quell'elemento. Ecco un esempio di cosa intendo:

<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();
});​

Esempio: http://jsfiddle.net/RXqAm/170/ (aggiornato per utilizzare jQuery 1.7 con propinvece di attr).


2
Piccola cosa: se si utilizza l' disabledattributo senza valore, ciò implica HTML anziché XHTML, nel qual caso la barra di chiusura non è necessaria.
Tim Down,

11
@Tim: in effetti non è necessario, ma è ancora HTML valido. È solo una forza dell'abitudine davvero e sento che sembra migliore.
Andy E,

1
Grazie Andy, questo è abbastanza intelligente. Non c'è più semplice? Sai perché gli input disabilitati non sono gestibili?
Pierre de LESPINAY,

2
Questo non ha senso: qualsiasi altro elemento html gestisce gli eventi del mouse, perché non un elemento disabilitato (es. mouseenterEcc.)
Augustin Riedinger

7
Puoi impedire all'elemento disabilitato di "buttare via" i tuoi clic inserendo il input[disabled] {pointer-events:none}tuo CSS. Quindi il clic si comporta come se si fa clic sull'elemento principale. IMHO questa è la soluzione più semplice e pulita, ma purtroppo funziona solo per i browser che supportano la pointer-eventsproprietà CSS: caniuse.com/#search=pointer-events
Doin

70

Forse potresti rendere il campo di sola lettura e, al momento dell'invio, disabilitare tutti i campi di sola lettura

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

e l'input (+ script) dovrebbe essere

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

$('input[readonly]').click(function () {
    $(this).removeAttr('readonly');
})

5
+1, questo è un suggerimento alternativo decente. L'unico aspetto negativo è che la casella di input non assumerà lo stile disabilitato, che varia tra i browser, quindi sarebbe difficile renderlo coerente con le aspettative dell'utente di un input disabilitato.
Andy E,

vero. Forse questo potrebbe essere risolto con i CSS? Ma sì, non avrebbe lo stesso aspetto dei normali campi di input
diabetici

Ottima soluzione alternativa. Mi piace di più questo perché puoi fare qualsiasi styling necessario con CSS (cioè farlo sembrare disabilitato) ma hai ancora eventi disponibili.
Giosuè,

62

Gli elementi disabilitati "mangiano" i clic in alcuni browser: non rispondono a questi, né consentono loro di essere catturati dai gestori di eventi in qualsiasi punto dell'elemento o dei suoi contenitori.

IMHO il modo più semplice e pulito per "risolvere" questo (se in realtà è necessario acquisire clic su elementi disabilitati come fa l'OP) è solo quello di aggiungere il seguente CSS alla tua pagina:

input[disabled] {pointer-events:none}

In questo modo tutti i clic su un input disabilitato passeranno all'elemento padre, dove è possibile acquisirli normalmente. (Se hai diversi input disabilitati, potresti voler metterli ciascuno in un singolo contenitore a sé stante, se non sono già disposti in quel modo - un extra <span>o un <div>, diciamo - solo per rendere facile distinguere quale input disabilitato è stato cliccato).


Il rovescio della medaglia è che questo trucco purtroppo non funziona per i browser più vecchi che non supportano la pointer-eventsproprietà CSS. (Dovrebbe funzionare da IE 11, FF v3.6, Chrome v4): caniuse.com/#search=pointer-events

Se devi supportare browser meno recenti, dovrai utilizzare una delle altre risposte!


Non ero sicuro input[disabled]che corrispondesse anche agli elementi disabilitati da JavaScript ( element.disabled = true;) ma sembra che lo faccia. Comunque, trovo input:disabledpiù pulito.
Martin,

Sembra una buona soluzione, non funziona per me in IE11! Dici anche FF 38+ e Chrome 31+ ma il tuo link caniuse dice FF 3.6+ e Chrome 4+?
user764754,

@utente764754 ... errore mio, non mi ero reso conto di dover fare clic su "Mostra tutto" nella pagina caniuse per ottenere le versioni precedenti del browser! L'ho risolto. Per quanto riguarda IE11, l'ho appena testato e funziona benissimo (vedi jsfiddle.net/7kkszq1c/1 per il codice, anche se per qualche ragione il sito jsFiddle non ha funzionato per me in IE11, ho dovuto incollarlo in un. file htm invece)
Doin

Grazie per l'aggiornamento! Nel frattempo ho anche osservato che funziona su un sito Web in IE11 ma non con jsfiddle. Forse a causa dell'iframe jsfiddle ...
user764754,

2
@Protectorone: disabled è una pseudo-classe dal CSS 3: w3.org/TR/css3-selectors/#UIstates
Martin

15

Vorrei suggerire un'alternativa: utilizzare CSS:

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

invece dell'attributo disabilitato. Quindi, puoi aggiungere i tuoi attributi CSS per simulare un input disabilitato, ma con un maggiore controllo.


4
funziona solo con ie10, troppi utenti hanno ie9 / 8. quindi non un'alternativa affidabile.
codifica il

Ciò causa comunque la registrazione del campo quando viene inviato il modulo, il che è indesiderabile in molti casi.
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>


5
Ma questo non funziona su FireFox - e questo era il punto!
GarethOwen,

6

Invece di disabled, potresti prendere in considerazione l'utilizzo readonly. Con alcuni CSS extra puoi modellare l'input in modo che appaia come un disabledcampo.

In realtà c'è un altro problema. L'evento changesi innesca solo quando l'elemento perde lo stato attivo, il che non è logico considerando un disabledcampo. Probabilmente stai spingendo i dati in questo campo da un'altra chiamata. Per farlo funzionare puoi usare l'evento 'bind'.

$('form').bind('change', 'input', function () {
    console.log('Do your thing.');
});

Un input di sola lettura verrà comunque inviato con il modulo se non sbaglio
Pierre de LESPINAY,

È corretto. Dovrebbe quindi essere combinato con @npth anwsner.
Nykac,

Grazie, è stato molto pulito e ottimale per il mio caso.
Sultanos,

4

O fallo con jQuery e CSS!

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

In questo modo l'aspetto dell'elemento viene disabilitato e nessun evento puntatore si attiva, tuttavia consente la propagazione e, se inviato, è possibile utilizzare l'attributo 'ignora' per ignorarlo.


@Precastic, è vero, ma a questo punto funziona per quasi tutti gli altri browser e puoi usare un polyfill per <11 . sidonaldson, perché non usare CSS diretto per applicare gli stili?
KyleMit,

@KyleMit potresti aggiungere una classe piuttosto che impostare gli stili, ma non è questo il tema! Stavo solo suggerendo eventi puntatore che è ancora una risposta buona e corretta a seconda della matrice del browser che stai costruendo. E grazie per tutti coloro che hanno contrassegnato questa risposta che un po 'fa schifo perché nulla qui è errato: /
sidonaldson

1
@sidonaldson, è una buona risposta, quindi vorrei anche che fosse classificata più in alto. Non sono sicuro di cosa faccia l'attributo ignore . Ma il mio punto sul CSS era che non penso che abbiamo bisogno di jQuery per essere il veicolo per l'applicazione dei CSS. Puoi semplicemente impostare una regola CSS che abbia come target lo stesso selettore e disabiliti anche gli eventi puntatore. In questo violino , jQuery e CSS dovrebbero fare la stessa cosa, ma il CSS sarà molto più performante.
KyleMit,

@KyleMit ah, supponendo che il modulo sia stato inviato, dovrai in qualche modo dire al back-end di ignorare quel campo se contenesse un valore (dato che lo spoofing è disabilitato).
Sidonaldson,

Sono d'accordo che CSS potrebbe essere più potente in quanto è possibile utilizzare un selettore basato su un attributo! Dai
un'occhiata a

0

Oggi abbiamo avuto un problema come questo, ma non volevamo cambiare l'HTML. Per questo abbiamo usato l' evento mouseenter

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');

-1

Trovo un'altra soluzione:

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

La classe "disabilitato" immette l'elemento disabilitato per opacità:

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

E quindi annullare l'evento se l'elemento è disabilitato e rimuovere la classe:

$(document).on('click','input.disabled',function(event) {
    event.preventDefault();
    $(this).removeClass('disabled');
});

La parte JavaScript non funziona per me. A parte questo, non risponde alla domanda, in quanto si tratta di abilitare un input disabilitato. In questo esempio, tuttavia, non è disabilitato all'inizio e quindi viene inviato al momento dell'invio.
Raimund Krämer,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.