Warum funktioniert mein JavaScript nicht in JSFiddle?

114

Ich kann nicht herausfinden, wo das Problem liegt JSFiddle liegt .

HTML:

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

JavaScript:

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

Und wenn ich auf die Schaltfläche klicke, ist nichts passiert. Die Konsole sagt "Test nicht definiert"

Ich habe die JSFiddle-Dokumentation gelesen - dort steht, dass JS-Code hinzugefügt <head>und HTML-Code hinzugefügt wird <body>(dieser JS-Code ist also früher als HTML und sollte funktionieren).

Larry Cinnabar
quelle
Das Entfernen der Klammern würde auch unter normalen Umständen funktionieren, obwohl es definitiv ein guter Rat ist, js so weit wie möglich von HTML zu trennen. Ich erlaube mir nur den style = "display: none" CSS inline no-no.
Adrian Bartholomew

Antworten:

60

Die Funktion wird in einem Load-Handler definiert und liegt somit in einem anderen Bereich. Wie @ellisbben in den Kommentaren feststellt, können Sie dies beheben, indem Sie es explizit für das windowObjekt definieren. Besser noch, ändern Sie es, um den Handler unauffällig auf das Objekt anzuwenden: http://jsfiddle.net/pUeue/

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

Beachten Sie, dass das Anwenden des Handlers auf diese Weise anstelle von Inline Ihren HTML-Code sauber hält. Ich verwende jQuery, aber Sie können es mit oder ohne Framework oder mit einem anderen Framework tun, wenn Sie möchten.

Tvanfosson
quelle
@Innuendo - jsFiddle verwendet separate Frames für Code / HTML / Stylesheets. Sie müssten im Funktionsaufruf auf den Frame verweisen, aber es gibt keine einfache Möglichkeit, dies zu tun, da der Frame keinen Namen hat. Es ist wirklich ein Problem aufgrund der Funktionsweise von jsfiddle, aber es ist immer noch eine gute Idee, Ihr Javascript vollständig getrennt zu halten.
Tvanfosson
5
@ tvanfosson- Ihre Lösung funktioniert, aber jsfiddle verwendet keine separaten Frames, um das Ergebnis anzuzeigen. siehe jsfiddle.net/Yazpj/show . Der Grund, warum es anfangs nicht funktioniert hat, ist, dass testes innerhalb einer onLoadFunktion definiert wurde. Mit window.test = function(){/*...*/}macht es perfekt.
Ellisbben
@ellisbben - Wenn ich das DOM mit Firebug inspiziere, befindet sich jedes der 4 separaten Fenster in einem separaten Iframe.
Tvanfosson
1
Ja, aber wenn Sie den einzelnen Iframe untersuchen, der zum Anzeigen des Beispiels verwendet wird, werden Sie feststellen, dass der gesamte Code auf einer einzelnen Seite abgelegt wird, auf der keine Frames verwendet werden. Daher können diese Frames Ihr Beispiel nicht beschädigen. Fügen Sie showeine beliebige jsfiddle-URL hinzu, um zu sehen, wovon ich spreche: jsfiddle.net/Yazpj/show
ellisbben
100

Wenn Sie die Wrap-Einstellung nicht angeben, wird standardmäßig "onLoad" verwendet. Dies führt dazu, dass sämtliches JavaScript in eine Funktion eingeschlossen wird, die ausgeführt wird, nachdem das Ergebnis geladen wurde. Alle Variablen sind lokal für diese Funktion und daher im globalen Bereich nicht verfügbar.

Ändern Sie die Wrapping-Einstellung auf "No Wrap" und es wird funktionieren:

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

Ich habe das Framework auf "Keine Bibliothek" umgestellt, da Sie keine verwenden.

Zalun
quelle
22

Es gibt eine andere Möglichkeit, Ihre Funktion in eine Variable wie diese zu deklarieren:

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

jsFiddle


Einzelheiten

BEARBEITEN (basierend auf den Kommentaren von @nnnnnn)

@nnnnnn:

Warum sollte es behoben test =werden, varwenn man (ohne ) sagt ?

Wenn Sie eine Funktion wie diese definieren:

var test = function(){};

Die Funktion wird lokal definiert, aber wenn Sie Ihre Funktion definieren ohne var:

test = function(){};

testwird für das windowObjekt definiert, das sich im Bereich der obersten Ebene befindet.

Warum funktioniert das?

Wie @zalun sagen:

Wenn Sie die Wrap-Einstellung nicht angeben, wird standardmäßig "onLoad" verwendet. Dies führt dazu, dass sämtliches JavaScript in eine Funktion eingeschlossen wird, die ausgeführt wird, nachdem das Ergebnis geladen wurde. Alle Variablen sind lokal für diese Funktion und daher im globalen Bereich nicht verfügbar.

Aber wenn Sie diese Syntax verwenden:

test = function(){};

Sie haben Zugriff auf die Funktion, testda sie global definiert ist


Verweise :

R3tep
quelle
2
Dies ist wirklich der einfachste Ansatz, wenn Sie nur ein kleines Stück Code in JSFiddle testen.
DOK
Aber warum funktioniert das? Der von Ihnen angegebene Link "Weitere Informationen" erklärt nicht, dass das Problem mit dem Umfang zusammenhängt oder warum das Aussprechen test = (ohne var) das Problem beheben würde.
nnnnnn
@ R3tep Nun, dein erster Link, der lautet: jsfiddle.net/R3tep/Yazpj/1406 alert tut nichts für mich. Ich bin auf Chrom.
Ced
@ R3tep ja es funktioniert mit console.log. Ich werde eine Frage zu SO posten, weil ich glaube, dass die Tatsache, dass ich keine Warnbox habe, mit einem anderen Problem zusammenhängt, das ich mit iframes habe.
Ced
1
@ R3tep Ich denke du hast mich missverstanden, aber ich bin mir nicht sicher. Ihr Code ist / war gut. Es gibt ein Problem mit der Codierung von JSFiddle (fehlender Wert im Sandbox-Attribut des Iframes, mit dem das Ergebnis angezeigt wird). Das macht es so, dass es auf einigen Chromversionen nicht funktioniert. Ich habe einen Problembericht über ihren Github geschickt. Ich war so sehr daran interessiert, weil ich dachte, das Problem, das ich auf meiner Website habe, sei dasselbe, aber nein. Prost.
Ced
3

Ändern Sie die Wrap-Einstellung im Bereich "Frameworks & Extensions" in "No Wrap-In <body>".

Akademie
quelle
-1

Es gibt kein Problem mit Ihrem Code. Wählen Sie einfach die Erweiterung onLoad () auf der rechten Seite.

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

<input type="button" value="test" onclick="test()">
Muslim Munir
quelle
-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");
}
Ivan
quelle