Utilizzo di un pulsante HTML per chiamare una funzione JavaScript


229

Sto cercando di utilizzare un pulsante HTML per chiamare una funzione JavaScript.

Ecco il codice:

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

Tuttavia, non sembra funzionare correttamente. C'è un modo migliore per farlo?

Ecco il link: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html fai clic sulla scheda della capacità nella sezione in basso a sinistra. Il pulsante dovrebbe generare un avviso se i valori non vengono modificati e dovrebbe produrre un grafico se si immettono valori.


6
si prega di definire "non sembra funzionare correttamente". quali errori vengono visualizzati facendo clic su di esso?
Solo qualcuno il

Il pulsante funziona in IE8, ma non in FF 3.5 a causa di un errore JavaScript (vedi la risposta di Jeff)
Chris Shouts,

1
Sì, risulta document.all è una cosa IE non standard; ho aggiornato la mia risposta con un'alternativa suggerita.
Jeff,

@ paper1337, @Jeff: la funzione non ottiene ancora l'effetto desiderato in IE8, quindi anche lo scambio di document.all con document.getElementById non lo risolverà.
Andy E

Risposte:


356

Esistono alcuni modi per gestire gli eventi con HTML / DOM. Non esiste un vero modo giusto o sbagliato, ma modi diversi sono utili in diverse situazioni.

1: Lo sta definendo in HTML:

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

2: C'è l'aggiunta alla proprietà DOM per l'evento in Javascript:

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

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

3: E c'è una funzione allegata al gestore eventi usando Javascript:

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

Sia il secondo che il terzo metodo consentono funzioni incorporate / anonime ed entrambi devono essere dichiarati dopo che l'elemento è stato analizzato dal documento. Il primo metodo non è XHTML valido perché l'attributo onclick non è nella specifica XHTML.

Il 1o e il 2o metodo si escludono a vicenda, nel senso che l'uso di uno (il 2o) prevale sull'altro (il 1o). Il 3o metodo ti permetterà di associare tutte le funzioni che vuoi allo stesso gestore di eventi, anche se è stato usato anche il 1o o il 2o metodo.

Molto probabilmente, il problema risiede da qualche parte nella tua CapacityChart()funzione. Dopo aver visitato il collegamento ed eseguito lo script, viene eseguita la funzione CapacityChart () e vengono aperti i due popup (uno è chiuso come da script). Dove hai la seguente riga:

CapacityWindow.document.write(s);

Prova invece quanto segue:

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

EDIT
Quando ho visto il tuo codice ho pensato che lo stessi scrivendo appositamente per IE. Come altri hanno già detto, dovrai sostituire i riferimenti document.allcon document.getElementById. Tuttavia, avrai comunque il compito di correggere lo script, quindi ti consiglio di farlo funzionare almeno in IE, poiché qualsiasi errore che commetti cambiando il codice per far funzionare il browser incrociato potrebbe causare ancora più confusione. Una volta che funziona in IE, sarà più facile dire se funziona in altri browser mentre aggiorni il codice.


7
Usando jquery, c'è anche: $("#clickMe").bind('click', function () { alert('hello!'); };)
Romano

32

Direi che sarebbe meglio aggiungere il javascript in modo non invadente ...

se usi jQuery potresti fare qualcosa del tipo:

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

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

4
Concordato. In molti casi, jQuery e altri framework sono semplicemente eccessivi per piccole quantità di javascript e non tutto il codice javascript deve essere cross-browser.
Andy E

2
Abbastanza giusto .. il punto che stavo cercando di chiarire era "un modo migliore per farlo" è discreto ... Senza jQuery, qualcosa del tipo: var btn = document.getElementById ('MyButton'); btn.onclick = function () {CapacityChart ();}
Paul,

1
Queste persone che usano jQuery sembrano essere impostate per usarlo per tutto il web. Che ne dici di usare JavaScript flat per uno? Bontà, adesso jQuery mi sta davvero innervosendo. LOL! Lo chiamerò il modo pigro di creare web, perché immagino che sia tutto ciò che è veramente.
DoctorLouie,

@DrLouie: Non ho nulla contro jQuery, è una buona soluzione a molti problemi, ma quando non è taggato o richiesto dall'OP qualsiasi menzione di jQuery dovrebbe essere assistita anche da un metodo non jQuery, altrimenti corrono il rischio di a) confondere il richiedente - potrebbe non sapere cosa sia jQuery oppure b) infastidire il richiedente chiedendogli di usare jQuery per alcune righe di codice javascript. @Paul - Devo dire che non è stata un'ottima lettura ...
Andy E

1
scuse ... link errato pubblicato - destinato a pubblicare uno stackoverflow uno. stackoverflow.com/questions/1588374/…
Paul

8

Il tuo HTML e il modo in cui chiami la funzione dal pulsante sembrano corretti.

Il problema sembra essere nella CapacityCountfunzione. Ricevo questo errore nella mia console su Firefox 3.5: "document.all non è definito" sulla riga 759 di bendelcorp.js.

Modificare:

Sembra che document.allsia solo una cosa di IE ed è un modo non standard di accedere al DOM. Se lo usi document.getElementById(), probabilmente dovrebbe funzionare. Esempio: document.getElementById("RUnits").valueanzichédocument.all.Capacity.RUnits.value


Questo non è specificamente il problema con la funzione, che non genera alcun errore in IE
Andy E

4

Questo sembra corretto. Immagino che tu abbia definito la tua funzione con un nome diverso o in un contesto che non è visibile al pulsante. Per favore aggiungi un po 'di codice


3

In questo modo, il punto e virgola ( ; ) non dovrebbe essere presente nel pulsante quando si chiama la funzione.

Quindi dovrebbe apparire così: onclick="CapacityChart()"

allora dovrebbe funzionare tutto :)


2

Uno dei maggiori problemi che hai è che stai utilizzando lo sniffing del browser senza una buona ragione:

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
    }

Sono su Chrome, quindi navigator.appNamenon lo sarà Netscape. Chrome supporta document.all? Forse, ma forse di nuovo no. E gli altri browser?

La versione del codice sul Netscaperamo dovrebbe funzionare su qualsiasi browser fino a Netscape Navigator 2 dal 1996, quindi probabilmente dovresti semplicemente attenersi a quello ... tranne che non funzionerà (o non è garantito che funzioni ) perché non hai specificato un nameattributo sugli inputelementi, quindi non verranno aggiunti elementsall'array del modulo come elementi denominati:

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

Dagli un nome e usa l' elementsarray o (meglio) usa

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

che funzionerà su tutti i browser moderni, senza bisogno di ramificazioni. Solo per essere al sicuro, sostituisci lo sniffing con una versione del browser maggiore o uguale a 4 con un controllo per il getElementByIdsupporto:

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

Probabilmente vuoi anche validare il tuo input; qualcosa di simile a

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

aiuterebbe.


Ciao NickFitz, una delle mie sfide qui è che questo script è stato originariamente scritto nel 1993 - da qui i riferimenti a Netscape 4. Ho avuto qualche aiuto per aggiornarlo e ha funzionato fino a quando non l'ho inserito nella sua pagina designata.
forrest

Dubito che sia stato scritto nel 1993, poiché Brendan Eich non ha inventato JS fino al 1995 en.wikipedia.org/wiki/Javascript#History ;-) Consiglio vivamente di usare document.getElementByIde togliere le altre cose.
NickFitz,

Penso che sarebbe prudente farlo funzionare almeno in IE prima di poi lavorare sulla compatibilità del browser, altrimenti non saprà se i suoi problemi di compatibilità del browser verranno risolti perché non funzionerà ancora.
Andy E

Meglio farlo funzionare usando le tecniche DOM standard, quindi non ci saranno problemi di compatibilità del browser di cui parlare :-)
NickFitz,

2

Il tuo codice non riesce su questa riga:

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

ho provato a fare un passo avanti con firebug e non ci riesce. questo dovrebbe aiutarti a capire il problema.

hai fatto riferimento a jquery. potresti anche usarlo in tutte queste funzioni. pulirà il tuo codice in modo significativo.


Non sta fallendo in IE su quella linea, però.
Andy E

perché document.all è una cosa di IE. dovrebbe solo usare $ ('# RUints'). val () notazione jquery b / c che sta già includendo jquery. questo si prende cura delle differenze del browser e ripulisce il codice.
Patricia,

2

Ho un codice pulsante di chiamata di funzione intelligente:

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

1

RISPOSTA SEMPLICE:

   onclick="functionName(ID.value);

Dove ID è l'ID del campo di input.


-2

modo sciocco:

onclick="javascript:CapacityChart();"

Dovresti leggere il javascript discreto e utilizzare un metodo di bind dei framework per associare i callback agli eventi dom.


@erenon: Oh andiamo. Questo non è il suo problema, la notazione va benissimo, e non c'è motivo di entrare in complicati collegamenti e framework solo per il gusto di assegnare un evento onclick.
Pekka,

Grazie per essere venuto in mia difesa Pekka. Voglio solo un semplice pulsante per funzionare correttamente.
forrest

3
Il javascript:protocollo non è necessario onclicknell'evento. L'evento onclick è già javascript. Il javascript:protocollo è per l'esecuzione di javascript nell'attributo href di un collegamento.
Web_Designer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.