Usando um botão HTML para chamar uma função JavaScript

229

Estou tentando usar um botão HTML para chamar uma função JavaScript.

Aqui está o código:

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

Parece não funcionar corretamente. Existe uma maneira melhor de fazer isso?

Aqui está o link: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html, clique na guia de capacidade na seção inferior esquerda. O botão deve gerar um alerta se os valores não forem alterados e produzir um gráfico se você inserir valores.

forrest
fonte
6
defina "não parece funcionar corretamente". que erro (s) você está recebendo quando clica nele?
apenas alguém
As obras de botão em IE8, mas não FF 3.5 devido a um erro JavaScript (veja a resposta de Jeff)
Chris Shouts
1
Sim, acontece document.all é uma coisa fora do padrão do IE; atualizei minha resposta com uma alternativa sugerida.
22409 Jeff
@ paper1337, @ Jeff: A função ainda não alcança o efeito desejado no IE8, portanto, mesmo trocando document.all por document.getElementById não o corrigirá.
Andy E

Respostas:

356

Existem algumas maneiras de lidar com eventos com HTML / DOM. Não existe um caminho certo ou errado, mas modos diferentes são úteis em situações diferentes.

1: Existe uma definição no HTML:

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

2: Adicionamos à propriedade DOM do evento em Javascript:

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

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

3: E há anexar uma função ao manipulador 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);

O segundo e o terceiro métodos permitem funções em linha / anônimas e ambos devem ser declarados após o elemento ter sido analisado no documento. O primeiro método não é XHTML válido porque o atributo onclick não está na especificação XHTML.

Os primeiro e segundo métodos são mutuamente exclusivos, ou seja, o uso de um (o segundo) substituirá o outro (o primeiro). O terceiro método permitirá que você anexe quantas funções desejar ao mesmo manipulador de eventos, mesmo que o primeiro ou o segundo método também tenham sido usados.

Muito provavelmente, o problema está em algum lugar da sua CapacityChart()função. Depois de visitar seu link e executar seu script, a função CapacityChart () é executada e os dois pop-ups são abertos (um é fechado conforme o script). Onde você tem a seguinte linha:

CapacityWindow.document.write(s);

Tente o seguinte:

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

EDITAR
Quando vi seu código, pensei que você estivesse escrevendo especificamente para o IE. Como outros já mencionaram, você precisará substituir as referências document.allpor document.getElementById. No entanto, você ainda terá a tarefa de corrigir o script depois disso, portanto, recomendo que ele funcione pelo menos no IE primeiro, pois qualquer erro cometido ao alterar o código para funcionar em vários navegadores pode causar ainda mais confusão. Quando estiver funcionando no IE, será mais fácil saber se ele está funcionando em outros navegadores enquanto você atualiza o código.

Andy E
fonte
7
Usando jquery, há também: $("#clickMe").bind('click', function () { alert('hello!'); };)
Roman
32

Eu diria que seria melhor adicionar o javascript de uma maneira não invasiva ...

se você estiver usando o jQuery, poderá fazer algo como:

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

<input type="button" value="Capacity Chart" id="MyButton" >
Paulo
fonte
4
Acordado. Em muitos casos, o jQuery e outras estruturas são um exagero para pequenas quantidades de javascript e nem todo código javascript precisa ser entre navegadores.
Andy E
2
Justo o suficiente ... o argumento que eu estava tentando destacar era "a melhor maneira de fazer isso" é discreto ... Sem jQuery, algo como: var btn = document.getElementById ('MyButton'); btn.onclick = function () {CapacityChart ();}
Paul
1
Essas pessoas que usam o jQuery parecem estar dispostas a usá-lo para tudo na web. Que tal usar JavaScript simples para um? Meu Deus, o jQuery está realmente me dando nos nervos agora. RI MUITO! Vou chamá-lo de maneira preguiçosa de criar web, pois acho que é tudo o que realmente é.
DoctorLouie
@DrLouie: Não tenho nada contra o jQuery, é uma boa solução para muitos problemas, mas quando não é marcado ou solicitado pelo OP, qualquer menção ao jQuery deve ser auxiliada por um método não-jQuery, caso contrário, eles correm o risco de a) confundir o solicitante - ele pode não saber o que é o jQuery ou b) irritar o solicitante, dizendo-lhe para usar o jQuery para algumas linhas de código javascript. @Paul - Devo dizer que não foi uma ótima leitura ...
Andy E
1
desculpas ... link errado postado - destinado a postar um stackoverflow. stackoverflow.com/questions/1588374/…
Paul
8

Seu HTML e a maneira como você chama a função no botão parecem corretos.

O problema parece estar na CapacityCountfunção. Estou recebendo esse erro no meu console no Firefox 3.5: "document.all is undefined" na linha 759 do bendelcorp.js.

Editar:

Parece que document.allé apenas uma coisa do IE e é uma maneira não padrão de acessar o DOM. Se você usar document.getElementById(), provavelmente deve funcionar. Exemplo: em document.getElementById("RUnits").valuevez dedocument.all.Capacity.RUnits.value

Jeff
fonte
Isso não é especificamente o problema com a função, o que não gera qualquer erro no IE
Andy E
4

Parece correto. Eu acho que você definiu sua função com um nome diferente ou em um contexto que não é visível para o botão. Adicione algum código

nervosismo
fonte
3

Só para você saber, o ponto-e-vírgula ( ; ) não deveria estar lá no botão quando você chama a função.

Portanto, deve ficar assim: onclick="CapacityChart()"

então tudo deve funcionar :)

jacki
fonte
2

Um grande problema que você tem é que você está usando o sniffing do navegador sem um bom motivo:

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
    }

Estou no Chrome, então navigator.appNamenão Netscape. O Chrome suportadocument.all ? Talvez, mas talvez não. E quanto a outros navegadores?

A versão do código na Netscaperamificação deve funcionar em qualquer navegador desde o Netscape Navigator 2 de 1996, então você provavelmente deve continuar com isso ... exceto que não funcionará (ou não está garantido que funcione) ) porque você não especificou um nameatributo nos inputelementos, portanto eles não serão adicionados à elementsmatriz do formulário como elementos nomeados:

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

Dê a eles um nome e use a elementsmatriz ou (melhor) use

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

que funcionará em todos os navegadores modernos - sem necessidade de ramificação. Para garantir a segurança, substitua esse farejador por uma versão do navegador maior ou igual a 4 por uma verificação de getElementByIdsuporte:

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

Você provavelmente deseja validar sua entrada também; algo como

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

ajudaria.

NickFitz
fonte
Olá NickFitz, um dos meus desafios aqui é que esse script foi originalmente escrito em 1993 - daí as referências ao Netscape 4. Tive alguma ajuda para atualizá-lo e funcionou até inseri-lo em sua página designada.
Forrest
Duvido que tenha sido escrito em 1993, pois Brendan Eich não inventou o JS até 1995 en.wikipedia.org/wiki/Javascript#History ;-) Eu recomendaria fortemente o uso document.getElementByIde remoção de outras coisas.
22412 NickFitz
Eu acho que seria prudente pelo menos fazê-lo funcionar no IE antes de trabalhar na compatibilidade do navegador, caso contrário ele não saberá se os problemas de compatibilidade do navegador serão corrigidos porque ainda não funcionará.
Andy E
É melhor fazê-lo funcionar usando técnicas DOM padrão, então não haverá quaisquer problemas de compatibilidade do navegador para falar :-)
NickFitz
2

Seu código está falhando nesta linha:

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

Eu tentei pisar embora com firebug e falha lá. isso deve ajudá-lo a descobrir o problema.

você referenciou jquery. você também pode usá-lo em todas essas funções. isso limpará seu código significativamente.

Patricia
fonte
Não está falhando no IE nessa linha, no entanto.
Andy E
porque document.all é uma coisa do IE. ele deve usar apenas a notação jquery $ ('# RUints'). val () porque já está incluindo jquery. isso cuida de quaisquer diferenças no navegador e limpa o código.
Patricia
2

Eu tenho um código de botão inteligente para chamada de função:

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

RESPOSTA SIMPLES:

   onclick="functionName(ID.value);

Onde ID é o ID do campo de entrada.

AGrush
fonte
-2

maneira boba:

onclick="javascript:CapacityChart();"

Você deve ler sobre javascript discreto e usar um método de ligação de estruturas para vincular retornos de chamada a eventos dom.

erenon
fonte
@erenon: Oh, vamos lá. Esse não é o problema dele, a notação está perfeitamente correta e não há razão para entrar em ligações e estruturas complicadas apenas para atribuir um evento onclick.
Pekka
Obrigado por vir em minha defesa Pekka. Eu só quero um botão simples para funcionar corretamente.
Forrest
3
O javascript:protocolo não é necessário no onclickevento. O evento onclick já é javascript. O javascript:protocolo é para executar o javascript no atributo href de um link.
Web_Designer 13/02/12