Usar un botón HTML para llamar a una función de JavaScript

229

Estoy tratando de usar un botón HTML para llamar a una función de JavaScript.

Aquí está el código:

<input type="button" value="Capacity Chart" onclick="CapacityChart();">

Sin embargo, no parece funcionar correctamente. ¿Hay una mejor manera de hacer esto?

Aquí está el enlace: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html haga clic en la pestaña de capacidad en la sección inferior izquierda. El botón debe generar una alerta si los valores no cambian y debe generar un gráfico si ingresa valores.

para descanso
fuente
66
defina "no parece funcionar correctamente". ¿Qué error (s) obtiene al hacer clic en él?
Alguien
El botón funciona en IE8, pero no en FF 3.5 debido a un error de JavaScript (consulte la respuesta de Jeff)
Chris Shouts
1
Sí, resulta document.all es una cosa de IE no estándar; Actualicé mi respuesta con una alternativa sugerida.
Jeff
@ paper1337, @Jeff: la función aún no logra el efecto deseado en IE8, por lo que incluso intercambiar document.all por document.getElementById no lo solucionará.
Andy E

Respuestas:

356

Hay algunas formas de manejar eventos con HTML / DOM. No hay una forma correcta o incorrecta real, pero diferentes formas son útiles en diferentes situaciones.

1: Lo está definiendo en el HTML:

<input id="clickMe" type="button" value="clickme" onclick="doFunction();" />

2: Hay que agregarlo a la propiedad DOM para el evento en Javascript:

//- Using a function pointer:
document.getElementById("clickMe").onclick = doFunction;

//- Using an anonymous function:
document.getElementById("clickMe").onclick = function () { alert('hello!'); };

3: Y se adjunta una función al controlador de eventos usando Javascript:

var el = document.getElementById("clickMe");
if (el.addEventListener)
    el.addEventListener("click", doFunction, false);
else if (el.attachEvent)
    el.attachEvent('onclick', doFunction);

Tanto el segundo como el tercer método permiten funciones en línea / anónimas y ambos deben declararse después de que el elemento se haya analizado del documento. El primer método no es válido XHTML porque el atributo onclick no está en la especificación XHTML.

Los métodos primero y segundo son mutuamente excluyentes, lo que significa que usar uno (el segundo) anulará al otro (el primero). El tercer método le permitirá adjuntar tantas funciones como desee al mismo controlador de eventos, incluso si el primer o segundo método también se ha utilizado.

Lo más probable es que el problema se encuentre en algún lugar de su CapacityChart()función. Después de visitar su enlace y ejecutar su script, se ejecuta la función CapacityChart () y se abren las dos ventanas emergentes (una se cierra según el script). Donde tienes la siguiente línea:

CapacityWindow.document.write(s);

Pruebe lo siguiente en su lugar:

CapacityWindow.document.open("text/html");
CapacityWindow.document.write(s);
CapacityWindow.document.close();

EDITAR
Cuando vi su código pensé que lo estaba escribiendo específicamente para IE. Como otros han mencionado, deberá reemplazar las referencias document.allcon document.getElementById. Sin embargo, aún tendrá la tarea de corregir el script después de esto, por lo que recomendaría que funcione al menos en IE primero, ya que cualquier error que cometa al cambiar el código para que funcione en varios navegadores podría causar aún más confusión. Una vez que esté funcionando en IE, será más fácil saber si está funcionando en otros navegadores mientras actualiza el código.

Andy E
fuente
77
Usando jquery, también hay: $("#clickMe").bind('click', function () { alert('hello!'); };)
Romano
32

Yo diría que sería mejor agregar el JavaScript de una manera discreta ...

si usa jQuery podría hacer algo como:

<script>
  $(document).ready(function(){
    $('#MyButton').click(function(){
       CapacityChart();
    });
  });
</script>

<input type="button" value="Capacity Chart" id="MyButton" >
Pablo
fuente
44
Convenido. En muchos casos, jQuery y otros marcos son una exageración excesiva para pequeñas cantidades de JavaScript y no todo el código de JavaScript debe ser cruzado.
Andy E
2
Es justo ... lo que estaba tratando de hacer era "una mejor manera de hacer esto" es discretamente ... Sin jQuery, algo como: var btn = document.getElementById ('MyButton'); btn.onclick = function () {CapacityChart ();}
Paul
1
Estas personas que usan jQuery parecen estar configuradas para usarlo para todo lo relacionado con la web. ¿Qué tal usar JavaScript plano para uno? Dios mío, jQuery realmente me está poniendo de los nervios ahora. Jajaja Lo llamaré la forma de crear web de un hombre perezoso, porque supongo que eso es todo lo que realmente es.
DoctorLouie
@DrLouie: No tengo nada en contra de jQuery, es una buena solución para muchos problemas, pero cuando el OP no lo etiqueta o pregunta, cualquier mención de jQuery debería ser asistida por un método que no sea jQuery también, de lo contrario corren el riesgo de a) confundir al autor de la pregunta: es posible que no sepa qué es jQuery ob) molestar al autor de la pregunta diciéndole que use jQuery para algunas líneas de código javascript. @Paul - Debo decir que no fue una gran lectura ...
Andy E
1
disculpas ... enlace incorrecto publicado - destinado a publicar un stackoverflow uno. stackoverflow.com/questions/1588374/…
Paul
8

Su HTML y la forma en que llama a la función desde el botón se ven correctos.

El problema parece estar en la CapacityCountfunción. Recibo este error en mi consola en Firefox 3.5: "document.all is undefined" en la línea 759 de bendelcorp.js.

Editar:

Parece que document.alles una cosa solo de IE y es una forma no estándar de acceder al DOM. Si lo usa document.getElementById(), probablemente debería funcionar. Ejemplo: en document.getElementById("RUnits").valuelugar dedocument.all.Capacity.RUnits.value

Jeff
fuente
Ese no es específicamente el problema con la función, que no arroja ningún error en IE
Andy E
4

Esto se ve correcto. Supongo que definiste tu función con un nombre diferente o en un contexto que no es visible para el botón. Por favor agregue un código

estar nervioso
fuente
3

Para que lo sepas, no se supone que el punto y coma ( ; ) esté allí en el botón cuando llamas a la función.

Entonces debería verse así: onclick="CapacityChart()"

entonces todo debería funcionar :)

jacki
fuente
2

Un problema importante que tiene es que está utilizando el rastreo del navegador sin una buena razón:

if(navigator.appName == 'Netscape')
    {
      vesdiameter  = document.forms['Volume'].elements['VesDiameter'].value;
      // more stuff snipped
    }
    else
    {
      vesdiameter  = eval(document.all.Volume.VesDiameter.value);
      // more stuff snipped
    }

Estoy en Chrome, así navigator.appNameque no lo estaré Netscape. ¿Chrome es compatible?document.all ? Tal vez, pero de nuevo tal vez no. ¿Y qué hay de otros navegadores?

La versión del código en la Netscaperama debería funcionar en cualquier navegador desde Netscape Navigator 2 desde 1996, por lo que probablemente debería seguir con eso ... excepto que no funcionará (o no está garantizado que funcione) ) porque no ha especificado un nameatributo en los inputelementos, por lo que no se agregarán a la elementsmatriz del formulario como elementos con nombre:

<input type="text" id="VesDiameter" value="0" size="10" onKeyUp="CalcVolume();">

Déles un nombre y use la elementsmatriz, o (mejor) use

var vesdiameter = document.getElementById("VesDiameter").value;

que funcionará en todos los navegadores modernos, sin necesidad de ramificaciones. Solo para estar seguro, reemplace esa búsqueda de una versión de navegador mayor o igual a 4 con una verificación de getElementByIdsoporte:

if (document.getElementById) { // NB: no brackets; we're testing for existence of the method, not executing it
    // do stuff...
}

Probablemente también desee validar su entrada; algo como

var vesdiameter = parseFloat(document.getElementById("VesDiameter").value);
if (isNaN(vesdiameter)) {
    alert("Diameter should be numeric");
    return;
}

ayudaría.

NickFitz
fuente
Hola NickFitz, uno de mis desafíos aquí es que este script fue escrito originalmente en 1993, de ahí las referencias a Netscape 4. Tuve algo de ayuda para actualizarlo y funcionó hasta que lo inserté en la página designada.
forrest
Dudo que haya sido escrito en 1993, ya que Brendan Eich no inventó JS hasta 1995 en.wikipedia.org/wiki/Javascript#History ;-) Recomiendo encarecidamente usar document.getElementByIdy eliminar las otras cosas.
NickFitz
Creo que sería prudente al menos hacerlo funcionar en IE antes de trabajar en la compatibilidad del navegador, de lo contrario no sabrá si se solucionarán sus problemas de compatibilidad del navegador porque aún no funciona.
Andy E
Es mejor hacer que funcione utilizando técnicas DOM estándar, entonces no habrá problemas de compatibilidad del navegador para hablar :-)
NickFitz
2

Su código falla en esta línea:

var RUnits = Math.abs(document.all.Capacity.RUnits.value);

Traté de pisarlo con Firebug y falla allí. eso debería ayudarte a resolver el problema.

tienes jquery referenciado. También podría usarlo en todas estas funciones. limpiará tu código significativamente.

Patricia
fuente
Sin embargo, no está fallando en IE en esa línea.
Andy E
porque document.all es una cosa de IE. debería usar $ ('# RUints'). val () notación jquery b / c ya está incluyendo jquery. esto se ocupa de cualquier diferencia de navegador y limpia el código.
Patricia
2

Tengo un código de botón inteligente de función de devolución de llamada:

<br>
<p id="demo"></p><h2>Intelligent Button:</h2><i>Note: Try pressing a key after clicking.</i><br>
<button id="button" shiftKey="getElementById('button').innerHTML=('You're pressing shift, aren't you?')" onscroll="getElementById('button').innerHTML=('Don't Leave me!')" onkeydown="getElementById('button').innerHTML=('Why are you pressing keys?')" onmouseout="getElementById('button').innerHTML=('Whatever, it is gone.. maybe')" onmouseover="getElementById('button').innerHTML=('Something Is Hovering Over Me.. again')" onclick="getElementById('button').innerHTML=('I was clicked, I think')">Ahhhh</button>
textmonster404
fuente
1

RESPUESTA SIMPLE:

   onclick="functionName(ID.value);

Donde ID es la ID del campo de entrada.

Agrush
fuente
-2

forma tonta:

onclick="javascript:CapacityChart();"

Debe leer sobre JavaScript discreto y utilizar un método de enlace de frameworks para vincular devoluciones de llamada a eventos dom.

Erenon
fuente
@ Erenon: Oh, vamos. Este no es su problema, la notación está perfectamente bien, y no hay razón para entrar en enlaces y marcos complicados solo por el hecho de asignar un evento onclick.
Pekka
Gracias por defender a Pekka. Solo quiero que un botón simple funcione correctamente.
forrest
3
El javascript:protocolo no es necesario en el onclickevento. El evento onclick ya es javascript. El javascript:protocolo es para ejecutar javascript en el atributo href de un enlace.
Web_Designer