¿Por qué mi JavaScript no funciona en JSFiddle?

114

No puedo averiguar cuál es el problema con este JSFiddle .

HTML:

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

JavaScript:

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

Y cuando hago clic en el botón, no pasó nada. La consola dice "prueba no definida"

He leído la documentación de JSFiddle: allí dice que se agrega código JS <head>y código HTML <body>(por lo que este código JS es anterior a html y debería funcionar).

Larry Cinnabar
fuente
Eliminar los paréntesis también funcionaría en circunstancias normales que no sean de violín, aunque definitivamente es un buen consejo separar js de HTML tanto como sea posible. Solo me permito el estilo = "display: none" CSS en línea no-no.
Adrian Bartholomew

Respuestas:

60

La función se define dentro de un controlador de carga y, por lo tanto, está en un ámbito diferente. Como señala @ellisbben en los comentarios, puede solucionar esto definiéndolo explícitamente en el windowobjeto. Mejor aún, cámbielo para aplicar el controlador al objeto de forma discreta: http://jsfiddle.net/pUeue/

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

Tenga en cuenta que aplicar el controlador de esta manera, en lugar de en línea, mantiene limpio su HTML. Estoy usando jQuery, pero podría hacerlo con o sin un marco o usando un marco diferente, si lo desea.

tvanfosson
fuente
@Innuendo - jsFiddle usa marcos separados para código / html / hojas de estilo. necesitaría hacer referencia al marco en la llamada a la función, pero no hay realmente una manera fácil de hacerlo ya que el marco no tiene nombre. Es realmente un problema debido a la forma en que funciona jsfiddle, pero sigue siendo una buena idea mantener su javascript completamente separado.
tvanfosson
5
@ tvanfosson- su solución funciona, pero jsfiddle no usa marcos separados para mostrar el resultado; consulte jsfiddle.net/Yazpj/show . La razón por la que no funcionó inicialmente es que testse definió dentro de una onLoadfunción; usarlo window.test = function(){/*...*/}hace que funcione perfectamente bien.
ellisbben
@ellisbben: si uso Firebug para inspeccionar el DOM, cada uno de los 4 paneles separados existe en un iframe separado.
tvanfosson
1
Sí, pero si examina el iframe único utilizado para mostrar el ejemplo, verá que coloca todo el código en una sola página que no usa marcos, por lo que esos marcos no pueden romper su ejemplo. Anexar showa cualquier URL jsFiddle para ver lo que estoy hablando: jsfiddle.net/Yazpj/show
ellisbben
100

Si no especifica la configuración de ajuste, el valor predeterminado es "onLoad". Esto da como resultado que todo JavaScript se incluya en una función que se ejecuta después de que se haya cargado el resultado. Todas las variables son locales para esta función, por lo que no están disponibles en el ámbito global.

Cambie la configuración de envoltura a "sin envoltura" y funcionará:

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

Cambié el marco a "Sin biblioteca" porque no usas ninguna.

zalun
fuente
22

Hay otra forma de declarar su función en una variable como esta:

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

jsFiddle


Detalles

EDITAR (basado en los comentarios de @nnnnnn)

@nnnnnn:

¿Por qué decir test =(sin var) lo arreglaría?

Cuando define una función como esta:

var test = function(){};

La función se define localmente, pero cuando define su función sin var:

test = function(){};

testse define en el windowobjeto que se encuentra en el ámbito de nivel superior.

¿Por qué funciona esto?

Como @zalun dice:

Si no especifica la configuración de ajuste, el valor predeterminado es "onLoad". Esto da como resultado que todo JavaScript se incluya en una función que se ejecuta después de que se haya cargado el resultado. Todas las variables son locales para esta función, por lo que no están disponibles en el ámbito global.

Pero si usa esta sintaxis:

test = function(){};

Tienes acceso a la función testporque está definida globalmente


Referencias:

R3tep
fuente
2
Este es realmente el enfoque más simple: solo está probando un poco de código en JSFiddle.
DOK
Pero, ¿por qué funciona esto? El enlace "Más información" que proporcionó no explica que el problema esté relacionado con el alcance, o por qué decir test = (sin var) lo solucionaría.
nnnnnn
@ R3tep bueno, su primer enlace que es: jsfiddle.net/R3tep/Yazpj/1406 alert no hace nada por mí. Estoy en Chrome.
Ced
@ R3tep sí, funciona con console.log. Publicaré una pregunta en SO porque creo que el hecho de que no tengo un cuadro de alerta está vinculado a otro problema que tengo con iframes.
Ced
1
@ R3tep Creo que me entendiste mal, pero no estoy seguro. Tu código es / era bueno. Existe un problema con la forma en que se codifica JSFiddle (falta el valor en el atributo sandbox del iframe que están usando para mostrar el resultado). Eso hace que no funcione en alguna versión de Chrome. Envié un informe de problemas en su github. Estaba tan interesado en él porque pensé que el problema que tengo en mi sitio web era el mismo, pero no. Salud.
Ced
3

Cambie la configuración de ajuste en el panel Estructuras y extensiones a "Sin ajuste <body>".

Academia
fuente
-1

No hay problema con su código, simplemente elija la extensión onLoad () del lado derecho.

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

<input type="button" value="test" onclick="test()">
Munir musulmán
fuente
-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");
}
Iván
fuente