web-dev-qa-db-fra.com

Utiliser un bouton HTML pour appeler une fonction JavaScript

J'essaie d'utiliser un bouton HTML pour appeler une fonction JavaScript.

Voici le code:

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

Cela ne semble pas fonctionner correctement cependant. Y a-t-il une meilleure manière de faire cela?

Voici le lien: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html cliquez sur l'onglet Capacité dans la section en bas à gauche. Le bouton devrait générer une alerte si les valeurs ne sont pas modifiées et produire un graphique si vous entrez des valeurs.

204
fmz

Il existe plusieurs façons de gérer les événements avec HTML/DOM. Il n'y a pas vraiment de bonne ou de mauvaise manière, mais différentes manières sont utiles dans différentes situations.

1: On le définit dans le HTML:

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

2: On l'ajoute à la propriété DOM pour l'événement en Javascript:

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

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

3: Et il y a l'attachement d'une fonction au gestionnaire d'événements en utilisant Javascript:

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

Les deuxième et troisième méthodes autorisent toutes deux des fonctions inline/anonymous et doivent être déclarées une fois que l'élément a été analysé dans le document. La première méthode n'est pas valide XHTML car l'attribut onclick n'est pas dans la spécification XHTML.

Les méthodes 1 et 2 sont mutuellement exclusives, ce qui signifie que l'utilisation de l'une (la deuxième) aura priorité sur l'autre (la première). La 3ème méthode vous permettra d’attacher autant de fonctions que vous le souhaitez au même gestionnaire d’événements, même si la 1ère ou la 2ème méthode a également été utilisée.

Très probablement, le problème se situe quelque part dans votre fonction CapacityChart(). Après avoir visité votre lien et exécuté votre script, la fonction CapacityChart () s'exécute et les deux fenêtres contextuelles s'ouvrent (l'une est fermée conformément au script). Où vous avez la ligne suivante:

CapacityWindow.document.write(s);

Essayez plutôt ce qui suit:

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

EDIT
Quand j'ai vu votre code, je pensais que vous l'écriviez spécifiquement pour IE. Comme d'autres l'ont mentionné, vous devrez remplacer les références à document.all par document.getElementById. Cependant, vous aurez toujours la tâche de corriger le script après cela. Je vous conseillerais donc de le faire fonctionner au moins au début de IE, car toute erreur que vous commettez en modifiant le code afin de fonctionner entre navigateurs pourrait causer encore plus de confusion. Une fois que cela fonctionne dans IE, il sera plus facile de savoir si cela fonctionne dans d'autres navigateurs pendant la mise à jour du code.

325
Andy E

Je dirais qu'il serait préférable d'ajouter le javascript de manière peu intrusive ...

si vous utilisez jQuery, vous pouvez faire quelque chose comme:

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

<input type="button" value="Capacity Chart" id="MyButton" >
26
Paul

Votre code HTML et la façon dont vous appelez la fonction à partir du bouton semblent corrects.

Le problème semble être dans la fonction CapacityCount. Je reçois cette erreur dans ma console sous Firefox 3.5: "document.all is undefined" à la ligne 759 de bendelcorp.js.

Modifier:

On dirait que document.all est une chose réservée à IE et un moyen non standard d'accéder au DOM. Si vous utilisez document.getElementById(), cela devrait probablement fonctionner. Exemple: document.getElementById("RUnits").value au lieu de document.all.Capacity.RUnits.value

7
Jeff

Cela semble correct. Je suppose que vous avez défini votre fonction avec un nom différent ou dans un contexte non visible pour le bouton. S'il vous plaît ajouter du code

3
jitter

Juste pour que vous sachiez, le point-virgule (;) n'est pas supposé être là dans le bouton lorsque vous appelez la fonction.

Il devrait donc ressembler à ceci: onclick="CapacityChart()"

alors tout devrait marcher :)

2
jacki

Un problème majeur que vous rencontrez est que vous utilisez le sniffing de navigateur sans raison valable:

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
    }

Je suis sur Chrome, donc navigator.appName ne sera pas Netscape. Est-ce que Chrome prend en charge document.all? Peut-être, mais encore une fois peut-être pas. Et qu'en est-il des autres navigateurs?

La version du code sur la branche Netscape devrait fonctionner sur tous les navigateurs, de retour à Netscape Navigator 2 à partir de 1996. Vous devriez donc vous en tenir à cela ... sauf que cela ne fonctionnera pas (ou isn pas garanti de fonctionner) car vous n'avez pas spécifié d'attribut name sur les éléments input, ils ne seront donc pas ajoutés au tableau elements du formulaire en tant qu'éléments nommés:

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

Donnez-leur un nom et utilisez le tableau elements ou (mieux) utilisez

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

qui fonctionnera sur tous les navigateurs modernes - aucun branchement nécessaire. Pour votre sécurité, remplacez cette détection pour une version de navigateur supérieure ou égale à 4 par une vérification du support getElementById:

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

Vous voudrez probablement également valider votre entrée; quelque chose comme

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

aiderait.

1
NickFitz

Votre code échoue sur cette ligne:

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

j'ai essayé de marcher avec Firebug et ça échoue là. cela devrait vous aider à comprendre le problème.

vous avez jquery référencé. vous pourriez aussi bien l'utiliser dans toutes ces fonctions. ça va nettoyer votre code de manière significative.

1
Patricia

J'ai un code de bouton de rappel de fonction intelligent:

<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>
0
textmonster404