2011-07-05 13 views
8

Ho la seguente jQuery che opera in tutti i principali browser tranne Opera:Opera ignorando .Live() Gestore di eventi

jQuery(document).ready(function() { 

     jQuery("#GetResults").live("click", function(e){ 
      e.preventDefault(); //Opera doesn't execute anything here 
     }); 

}; 

che dovrebbe fuoco quando cliccando sul seguente link:

<a id="GetResults" href="Folder/File/javascript:void(0);">Get Results</a> 

Solo Opera ignora questo. Qualche idea?

Edit:

Ho appena scoperto che se ho sostituito .Live() per .bind() tutto funziona come previsto. Tuttavia, non riesco a trovare alcuna documentazione relativa ai bug di .live() in Opera, ed è funzionante con in jsFiddle che indicherebbe qualcosa di ambientale. Cosa potrebbe causare questo comportamento?

+0

e.preventDefault() interrompe l'azione predefinita (seguendo il collegamento). ho provato questo in jsfiddle, non segue il link, quale versione di opera stai usando? Cosa stai cercando di fare? – Patricia

+0

Quello è corretto - tuttavia Opera segue il collegamento. In realtà c'è un sacco di codice in più ma l'ho rimosso per il post e nessuno di essi funziona. Opera 11.5. –

+1

Può essere una ripresa molto lunga, ma la prima cosa che faccio ovunque solo Opera si comporta diversamente, è controllare se la cache è cancellata. – CodeVirtuoso

risposta

2

leggere questo articolo: http://jupiterjs.com/news/why-you-should-never-use-jquery-live Prova Usa delegato anziché

+0

Mi sono già imbattuto in questo, per essere onesti, il problema è che ho degli elementi che entrano in campo più tardi quindi il gestore di eventi ha davvero bisogno di sedersi in cima al DOM. –

+0

Forse potresti provare a usare 'delegato' per il documento' body'? –

4

Il seguente codice funziona come previsto in Opera 11.50.

<!doctype html> 
<title></title> 
<a id="GetResults" href="http://google.com">Get Results</a> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
<script> 
jQuery(document).ready(function() { 
    jQuery("#GetResults").live("click", function(e){ 
    alert('doing something'); 
    e.preventDefault(); //Opera doesn't execute anything here 
    }); 
}); 
</script> 

O è un errore corretto o qualcosa di più sottile.

È possibile verificare se quanto sopra funziona sulla versione di Opera/jQuery?

+0

Posso confermare che questo funziona, con una versione 1.4.2 di jQuery. Questo sicuramente deve essere un problema ambientale ora, qualche idea su cosa potrebbe impedire a tutti .live() di sparare? I breakpoint non si rompono mai in essi. –

+0

Nel tuo post, manca un paren di chiusura nell'ultima riga javascript. Puoi confermare che questo non è il problema qui? –

+0

Ah si hai ragione. Il mancante) è apparso solo durante la composizione della domanda, è lì nella fonte –

6

Cosa succede quando si collega il gestore utilizzando:

$ (something).bind ("click", function (e) { 
    // do something 
}) 

Si può anche provare ad attaccare il gestore utilizzando il metodo .Click().

+0

Fare questo funziona, ma non fa luce sul perché .live() non lo farà? –

+1

Vedere la mia risposta. Devi solo sapere perché '.live' è magico – naugtur

7

Questo ha bisogno di chiarimenti. Le risposte sopra sono corrette, ma nessuno ha chiaramente spiegato da dove viene il tuo problema.

In effetti penso che probabilmente potresti riprodurre il problema anche in altri browser. funziona a causa del modo in cui .live funziona:

Si lega all'evento su document e attende che un evento particolare bolla fino a lì. Quindi controlla se lo event.target è ciò che si desidera gestire. *

Se si fa clic su un elemento di collegamento è molto probabile che il browser va alla nuova pagina prima dell'evento bolle abbastanza alto per attivare il codice. In un'app con un sacco di HTML e gestori di eventi tutti i browser dovrebbero avere problemi. Opera inizia appena a visualizzare la nuova pagina e distrugge il precedente più veloce in questo caso. Dipende molto da una situazione particolare più che dal browser. Ad esempio: probabilmente non lo vedrai se avessi una latenza di rete elevata durante la connessione al sito.

per prevenire l'azione predefinita su un elemento a è necessario utilizzare .bind come ai vecchi tempi;) quando un eveloper doveva essere consapevole di quello che carica con AJAX e si legano a nuovi eventi che in un callback.

* C'è dell'altro e .live è più complicato. Ho appena descritto ciò che è necessario qui.

+0

>" Se fai clic su un elemento di collegamento, è possibile che il browser passi alla nuova pagina prima che l'evento bolle abbastanza in alto da attivare il tuo codice. " ... falso, il bubbling avviene prima dell'azione predefinita. Tuttavia, se qualcosa in alto sulla catena DOM utilizza stopPropagation() senza preventDefault(), allora potrebbe non insinuarsi nel documento per attivare il gestore .live(). Se così fosse, però, fallirebbe in tutti i browser. – jimbojw

+0

@jimbojw Probabilmente sei più interessato a finire la tua funzione di gestione prima, o meglio, invece di un'azione predefinita. Il fatto che una bolla arrivi all'inizio per avviare la funzione non è sufficiente. Inoltre, nonostante quello che hai affermato, non puoi essere sicuro di impedire l'azione predefinita con il gestore del live, nella maggior parte dei casi è troppo tardi. Questo deriva dalla mia esperienza con più browser. – naugtur

1

Non so se lo vuoi fare, o se funzionerà per te. Ho avuto problemi simili con Opera 9.5 e e.preventDefault() non funziona, l'unica soluzione che ho trovato è stato quello appena return false ...

jQuery(document).ready(function() { 

     jQuery("#GetResults").live("click", function(e){ 
      e.preventDefault(); 
      return false; 
     }); 

}; 
1

Ci sono due aspetti di un evento di bubbling da prendere in considerazione in questo caso: la propagazione e l'azione predefinita .

La propagazione si riferisce all'evento che bolle. Prima il tag anchor ottiene l'evento click, quindi il suo elemento genitore, quindi il genitore del genitore, e così via, fino all'elemento del documento. È possibile interrompere la propagazione di un evento in qualsiasi momento chiamando lo e.stopPropagation().

L'azione predefinita è ciò che il browser farà se non viene fatto nulla per impedirlo. Il caso più noto è quando si fa clic su un ancoraggio con un href, il browser proverà a navigare lì. Esistono anche altri esempi, ad esempio quando si fa clic e si trascina un'immagine, molti browser creeranno un'immagine fantasma che è possibile rilasciare su un'altra applicazione. In entrambi i casi, è possibile interrompere il browser di fare l'azione di default in qualsiasi momento chiamando e.preventDefault()

Come detto in altre risposte a questa domanda, funzionalità di jQuery .live() imposta un gestore ad un elemento di alto livello (come document) e prende azione dopo gli eventi si sono propagati. Se un gestore tra l'ancora e il documento chiama e.stopPropagaiton()senza chiamando e.preventDefault(), il gestore del live non risponde, consentendo comunque al browser di navigare (l'azione predefinita).

Dubito che questo è ciò che sta accadendo, dal momento che interesserebbe tutti i browser, ma è una possibile spiegazione.

1

Assicurarsi che l'evento document.ready si verifichi prima di fare clic sul collegamento.

Prova a mettere tutte le vite nella parte superiore del wrapper document.ready. Potrebbe essere d'aiuto, se hai un sacco di codice javascript.

Problemi correlati