Verwenden einer HTML-Schaltfläche zum Aufrufen einer JavaScript-Funktion

229

Ich versuche, eine HTML-Schaltfläche zum Aufrufen einer JavaScript-Funktion zu verwenden.

Hier ist der Code:

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

Es scheint jedoch nicht richtig zu funktionieren. Gibt es einen besseren Weg, dies zu tun?

Hier ist der Link: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html Klicken Sie auf die Registerkarte Kapazität im unteren linken Bereich. Die Schaltfläche sollte eine Warnung generieren, wenn die Werte nicht geändert werden, und ein Diagramm erstellen, wenn Sie Werte eingeben.

Wald
quelle
6
Bitte definieren Sie "scheint nicht richtig zu funktionieren". Welche Fehler erhalten Sie, wenn Sie darauf klicken?
Nur jemand
Die Schaltfläche funktioniert in IE8, aber nicht in FF 3.5 aufgrund eines JavaScript-Fehlers (siehe Jeffs Antwort)
Chris Shouts
1
Ja, es stellt sich heraus, dass document.all eine nicht standardmäßige IE-Sache ist. hat meine Antwort mit einer vorgeschlagenen Alternative aktualisiert.
Jeff
@ paper1337, @Jeff: Die Funktion erzielt in IE8 immer noch nicht den gewünschten Effekt, sodass selbst das Austauschen von document.all gegen document.getElementById den Fehler nicht beheben kann.
Andy E

Antworten:

356

Es gibt verschiedene Möglichkeiten, Ereignisse mit HTML / DOM zu behandeln. Es gibt keinen richtigen oder falschen Weg, aber verschiedene Wege sind in verschiedenen Situationen nützlich.

1: Es wird im HTML definiert:

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

2: Es wird der DOM-Eigenschaft für das Ereignis in Javascript hinzugefügt:

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

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

3: Und es gibt eine Funktion, die mit Javascript eine Funktion an den Ereignishandler anfügt:

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

Sowohl die zweite als auch die dritte Methode ermöglichen Inline- / anonyme Funktionen und beide müssen deklariert werden, nachdem das Element aus dem Dokument analysiert wurde. Die erste Methode ist kein gültiges XHTML, da das onclick-Attribut nicht in der XHTML-Spezifikation enthalten ist.

Die 1. und 2. Methode schließen sich gegenseitig aus, dh die Verwendung der einen (2.) Methode überschreibt die andere (1.). Mit der 3. Methode können Sie beliebig viele Funktionen an denselben Ereignishandler anhängen, auch wenn auch die 1. oder 2. Methode verwendet wurde.

Das Problem liegt höchstwahrscheinlich irgendwo in Ihrer CapacityChart()Funktion. Nachdem Sie Ihren Link besucht und Ihr Skript ausgeführt haben, wird die Funktion CapacityChart () ausgeführt und die beiden Popups werden geöffnet (eines wird gemäß dem Skript geschlossen). Wo Sie die folgende Zeile haben:

CapacityWindow.document.write(s);

Versuchen Sie stattdessen Folgendes:

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

BEARBEITEN
Als ich Ihren Code sah, dachte ich, Sie schreiben ihn speziell für den IE. Wie andere bereits erwähnt haben, müssen Sie Verweise auf document.alldurch ersetzen document.getElementById. Sie haben jedoch weiterhin die Aufgabe, das Skript danach zu reparieren. Ich würde daher empfehlen, es zuerst mindestens im IE zum Laufen zu bringen, da Fehler, die Sie beim Ändern des Codes machen, um browserübergreifend zu funktionieren, noch mehr Verwirrung stiften können. Sobald es im IE funktioniert, ist es einfacher zu erkennen, ob es in anderen Browsern funktioniert, während Sie den Code aktualisieren.

Andy E.
quelle
6
Mit jquery gibt es auch: $("#clickMe").bind('click', function () { alert('hello!'); };)
Roman
32

Ich würde sagen, es wäre besser, das Javascript unauffällig hinzuzufügen ...

Wenn Sie jQuery verwenden, können Sie Folgendes tun:

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

<input type="button" value="Capacity Chart" id="MyButton" >
Paul
quelle
4
Einverstanden. In vielen Fällen sind jQuery und andere Frameworks für kleine Mengen von Javascript ein reiner Overkill, und nicht jeder Javascript-Code muss browserübergreifend sein.
Andy E
2
Fair genug ... der Punkt, den ich ansprechen wollte, war "ein besserer Weg, dies zu tun", ist unauffällig ... Ohne jQuery etwas wie: var btn = document.getElementById ('MyButton'); btn.onclick = function () {CapacityChart ();}
Paul
1
Diese Leute, die jQuery verwenden, scheinen darauf eingestellt zu sein, es für alles Web zu verwenden. Wie wäre es mit flachem JavaScript für einen? Meine Güte, jQuery geht mir jetzt wirklich auf die Nerven. LOL! Ich nenne es die Art des faulen Mannes, ein Web zu erstellen, denn ich denke, das ist alles, was es wirklich ist.
DoctorLouie
@DrLouie: Ich habe überhaupt nichts gegen jQuery, es ist eine gute Lösung für viele Probleme, aber wenn es nicht vom OP markiert oder gefragt wird, sollte jede Erwähnung von jQuery auch durch eine Nicht-jQuery-Methode unterstützt werden, da sonst das Risiko besteht von a) Verwirrung des Fragestellers - er weiß möglicherweise nicht, was jQuery ist, oder b) Ärger des Fragestellers, indem er ihn auffordert, jQuery für einige Zeilen Javascript-Code zu verwenden. @ Paul - Ich muss sagen, das war keine gute Lektüre ...
Andy E
1
Entschuldigung ... falscher Link gepostet - soll einen Stackoverflow posten. stackoverflow.com/questions/1588374/…
Paul
8

Ihr HTML-Code und die Art und Weise, wie Sie die Funktion über die Schaltfläche aufrufen, sehen korrekt aus.

Das Problem scheint in der CapacityCountFunktion zu liegen. Ich erhalte diesen Fehler in meiner Konsole unter Firefox 3.5: "document.all is undefined" in Zeile 759 von bendelcorp.js.

Bearbeiten:

Sieht so aus, als wäre document.alles nur ein IE und eine nicht standardmäßige Möglichkeit, auf das DOM zuzugreifen. Wenn Sie verwenden document.getElementById(), sollte es wahrscheinlich funktionieren. Beispiel: document.getElementById("RUnits").valuestattdocument.all.Capacity.RUnits.value

Jeff
quelle
Das ist nicht speziell das Problem mit der Funktion, die keine Fehler im IE wirft
Andy E
4

Das sieht richtig aus. Ich denke, Sie haben Ihre Funktion entweder mit einem anderen Namen oder in einem Kontext definiert, der für die Schaltfläche nicht sichtbar ist. Bitte fügen Sie einen Code hinzu

Jitter
quelle
3

Damit Sie wissen, sollte das Semikolon ( ; ) nicht in der Schaltfläche vorhanden sein, wenn Sie die Funktion aufrufen.

Also sollte es einfach so aussehen: onclick="CapacityChart()"

dann sollte alles klappen :)

Jacki
quelle
2

Ein großes Problem ist, dass Sie Browser-Sniffing ohne guten Grund verwenden:

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
    }

Ich bin auf Chrome, navigator.appNamewerde es also nicht sein Netscape. Unterstützt Chrome document.all? Vielleicht, aber vielleicht auch nicht. Und was ist mit anderen Browsern?

Die Version des Codes in der NetscapeVerzweigung sollte in jedem Browser bis zu Netscape Navigator 2 von 1996 funktionieren, also sollten Sie sich wahrscheinlich einfach daran halten ... außer dass es nicht funktioniert (oder nicht garantiert funktioniert) ), weil Sie namefür die inputElemente kein Attribut angegeben haben , sodass sie nicht elementsals benannte Elemente zum Array des Formulars hinzugefügt werden:

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

Geben Sie ihnen entweder einen Namen und verwenden Sie das elementsArray oder (besser) verwenden

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

Dies funktioniert auf allen modernen Browsern - keine Verzweigung erforderlich. Um auf der sicheren Seite zu sein, ersetzen Sie dieses Schnüffeln für eine Browserversion größer oder gleich 4 durch eine Überprüfung auf getElementByIdUnterstützung:

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

Sie möchten wahrscheinlich auch Ihre Eingabe validieren. etwas wie

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

würde helfen.

NickFitz
quelle
Hallo NickFitz, eine meiner Herausforderungen besteht darin, dass dieses Skript ursprünglich 1993 geschrieben wurde - daher die Verweise auf Netscape 4. Ich hatte einige Hilfe bei der Aktualisierung und es hat funktioniert, bis ich es in die entsprechende Seite eingefügt habe.
Wald
Ich bezweifle, dass es 1993 geschrieben wurde, da Brendan Eich JS erst 1995 erfunden hat. En.wikipedia.org/wiki/Javascript#History ;-) Ich würde dringend empfehlen document.getElementById, die anderen Sachen zu verwenden und zu entfernen.
NickFitz
Ich denke, es wäre ratsam, es zumindest im IE zum Laufen zu bringen, bevor man an der Browserkompatibilität arbeitet, sonst weiß er nicht, ob seine Browserkompatibilitätsprobleme behoben werden, weil es immer noch nicht funktioniert.
Andy E
Besser, es mit Standard-DOM-Techniken zum
Laufen
2

Ihr Code schlägt in dieser Zeile fehl:

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

Ich habe versucht, es mit Firebug zu durchlaufen, und es schlägt dort fehl. Das sollte Ihnen helfen, das Problem herauszufinden.

Sie haben jquery referenziert. Sie können es auch in all diesen Funktionen verwenden. Dadurch wird Ihr Code erheblich bereinigt.

Patricia
quelle
Es schlägt jedoch nicht im IE in dieser Zeile fehl.
Andy E
weil document.all eine IE-Sache ist. er sollte nur $ ('# RUints') verwenden. val () jquery notation b / c er schließt jquery bereits ein. Dadurch werden eventuelle Browserunterschiede behoben und der Code bereinigt.
Patricia
2

Ich habe einen intelligenten Funktionsrückruf-Tastencode:

<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
quelle
1

EINFACHE ANTWORT:

   onclick="functionName(ID.value);

Wobei ID die ID des Eingabefeldes ist.

AGrush
quelle
-2

alberner Weg:

onclick="javascript:CapacityChart();"

Sie sollten sich mit diskretem Javascript befassen und eine Frameworks-Bindungsmethode verwenden, um Rückrufe an dom-Ereignisse zu binden.

erenon
quelle
@erenon: Ach komm schon. Dies ist nicht sein Problem, die Notation ist vollkommen in Ordnung, und es gibt keinen Grund, sich auf komplizierte Bindungen und Frameworks einzulassen, nur um ein Ereignis mit einem Klick zuzuweisen.
Pekka
Danke, dass du zu meiner Verteidigung gekommen bist, Pekka. Ich möchte nur, dass eine einfache Taste richtig funktioniert.
Wald
3
Das javascript:Protokoll wird in diesem onclickFall nicht benötigt . Das Ereignis onclick ist bereits Javascript. Das javascript:Protokoll dient zur Ausführung von Javascript im href-Attribut eines Links.
Web_Designer