Perché il mio JavaScript non funziona in JSFiddle?


114

Non riesco a scoprire qual è il problema con questo JSFiddle .

HTML:

<input type="button" value="test" onclick="test()">

JavaScript:

function test(){alert("test");}

E quando clicco sul pulsante, non è successo niente. La console dice "test non definito"

Ho letto la documentazione di JSFiddle - lì dice che viene aggiunto il codice JS <head>e il codice HTML <body>(quindi questo codice JS è precedente a html e dovrebbe funzionare).


La rimozione delle parentesi funzionerebbe anche in normali circostanze non violente sebbene sia sicuramente un buon consiglio separare il più possibile js dall'HTML. Mi concedo solo lo stile = "display: none" CSS inline no-no.
Adrian Bartholomew

Risposte:


60

La funzione viene definita all'interno di un dispositivo di presa del carico e quindi è in un ambito diverso. Come nota @ellisbben nei commenti, puoi risolvere il problema definendolo esplicitamente windowsull'oggetto. Meglio, ancora, modificalo per applicare il gestore all'oggetto in modo discreto: http://jsfiddle.net/pUeue/

$('input[type=button]').click( function() {
   alert("test");   
});

Nota che l'applicazione del gestore in questo modo, invece che in linea, mantiene pulito il tuo HTML. Sto usando jQuery, ma potresti farlo con o senza un framework o usando un framework diverso, se lo desideri.


@Innuendo - jsFiddle usa frame separati per code / html / fogli di stile. avresti bisogno di fare riferimento al frame nella chiamata di funzione, ma non c'è davvero un modo semplice per farlo poiché il frame non ha un nome. È davvero un problema a causa del modo in cui funziona jsfiddle, ma è comunque una buona idea mantenere il tuo javascript completamente separato.
tvanfosson

5
@ tvanfosson- la tua soluzione funziona, ma jsfiddle non usa frame separati per mostrare il risultato; vedere jsfiddle.net/Yazpj/show . Il motivo per cui inizialmente non ha funzionato è che è teststato definito all'interno di una onLoadfunzione; l'utilizzo lo window.test = function(){/*...*/}fa funzionare perfettamente.
ellisbben

@ellisbben - se utilizzo Firebug per ispezionare il DOM, ciascuno dei 4 riquadri separati esiste in un iframe separato.
tvanfosson

1
Sì, ma se esamini il singolo iframe utilizzato per mostrare l'esempio, vedrai che mette tutto il codice in una singola pagina che non utilizza i frame, quindi quei frame non possono rompere il tuo esempio. Aggiungi showa qualsiasi URL jsfiddle per vedere di cosa sto parlando: jsfiddle.net/Yazpj/show
ellisbben

100

Se non si specifica l'impostazione di avvolgimento, il valore predefinito è "onLoad". Ciò si traduce con tutto il JavaScript inserito in una funzione eseguita dopo il caricamento del risultato. Tutte le variabili sono locali per questa funzione, quindi non disponibili nell'ambito globale.

Cambia l'impostazione di avvolgimento su "nessun ritorno a capo" e funzionerà:

http://jsfiddle.net/zalun/Yazpj/1/

Ho cambiato il framework in "Nessuna libreria" perché non ne usi nessuna.


22

C'è un altro modo, dichiara la tua funzione in una variabile come questa:

test = function() {
  alert("test");
}

jsFiddle


Dettagli

EDIT (basato sui commenti di @nnnnnn)

@nnnnnn:

perché dire test =(senza var) lo aggiusterebbe?

Quando definisci una funzione come questa:

var test = function(){};

La funzione è definita localmente, ma quando definisci la tua funzione senza var:

test = function(){};

testè definito windowsull'oggetto che si trova nell'ambito di livello superiore.

perché funziona?

Come @zalun dice:

Se non si specifica l'impostazione di avvolgimento, il valore predefinito è "onLoad". Ciò si traduce con tutto il JavaScript inserito in una funzione eseguita dopo il caricamento del risultato. Tutte le variabili sono locali per questa funzione, quindi non disponibili nell'ambito globale.

Ma se usi questa sintassi:

test = function(){};

Hai accesso alla funzione testperché è definita globalmente


Riferimenti :


2
Questo è davvero l'approccio più semplice è che stai solo testando un po 'di codice in JSFiddle.
DOK

Ma perché funziona? Il collegamento "Ulteriori informazioni" fornito non spiega che il problema è correlato all'ambito o perché dire test = (senza var) lo risolverebbe.
nnnnnn

@ R3tep bene il tuo primo collegamento che è: jsfiddle.net/R3tep/Yazpj/1406 alert non fa nulla per me. Sono su Chrome.
Ced,

@ R3tep sì, funziona con console.log. Pubblicherò una domanda su SO perché credo che il fatto che non ho una casella di avviso sia collegato a un altro problema che ho con gli iframe.
Ced,

1
@ R3tep Penso che tu mi abbia frainteso ma non ne sono sicuro. Il tuo codice è / era buono. Si è verificato un problema con la modalità di codifica di JSFiddle (valore mancante nell'attributo sandbox dell'iframe che stanno utilizzando per visualizzare il risultato). Ciò lo rende tale che non funzionerà su alcune versioni di Chrome. Ho inviato un rapporto sul problema sul loro GitHub. Mi interessava molto perché pensavo che il problema che avevo sul mio sito web fosse lo stesso, ma no. Saluti.
Ced

3

Modifica l'impostazione di avvolgimento nel riquadro Frameworks ed estensioni su "Nessun wrap-in <body>"


-1

Non ci sono problemi con il codice, basta scegliere l'estensione onLoad () dal lato destro.


-1
<script> 
function test(){
 alert("test");   
}
</script>

<input type="button" value="test" onclick="test()">

-3
Select OnDomready

HTML:

<input id="dButton" type="button" value="test"/>

JavaScript:

addEventListener('load', init, false);

function init()
{
  oInput = document.getElementById('dButton');
  oInput.onclick = test;
}

function test(){
  alert("test");
}
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.