Użycie przycisku HTML do wywołania funkcji JavaScript

229

Próbuję użyć przycisku HTML, aby wywołać funkcję JavaScript.

Oto kod:

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

Wydaje się jednak, że nie działa poprawnie. Czy jest na to lepszy sposób?

Oto link: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html kliknij kartę pojemności w lewej dolnej części. Przycisk powinien wygenerować alert, jeśli wartości nie zostaną zmienione, i powinien wygenerować wykres, jeśli wprowadzisz wartości.

forrest
źródło
6
proszę zdefiniować „nie działa poprawnie”. jakie błędy pojawiają się po kliknięciu?
tylko ktoś
Przycisk działa w IE8, ale nie w FF 3.5 z powodu błędu JavaScript (patrz odpowiedź Jeffa)
Chris Shouts
1
Tak, okazuje się, że document.all jest niestandardową rzeczą w IE; zaktualizowałem moją odpowiedź sugerowaną alternatywą.
Jeff
@ paper1337, @Jeff: Funkcja nadal nie osiąga pożądanego efektu w IE8, więc nawet zamiana document.all na document.getElementById nie naprawi tego.
Andy E

Odpowiedzi:

356

Istnieje kilka sposobów obsługi zdarzeń za pomocą HTML / DOM. Nie ma żadnego dobrego lub złego sposobu, ale różne sposoby są przydatne w różnych sytuacjach.

1: Jest to zdefiniowane w HTML:

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

2: Dodanie go do właściwości DOM dla zdarzenia w JavaScript:

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

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

3: I jest dołączenie funkcji do procedury obsługi zdarzeń za pomocą Javascript:

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

Zarówno druga, jak i trzecia metoda pozwalają na funkcje wbudowane / anonimowe i obie muszą zostać zadeklarowane po przeanalizowaniu elementu z dokumentu. Pierwsza metoda nie jest poprawnym XHTML, ponieważ atrybutu onclick nie ma w specyfikacji XHTML.

Pierwsza i druga metoda wzajemnie się wykluczają, co oznacza, że ​​użycie jednej (drugiej) zastąpi drugą (pierwszą). Trzecia metoda umożliwia dołączenie dowolnej liczby funkcji do tej samej procedury obsługi zdarzeń, nawet jeśli pierwsza lub druga metoda również została użyta.

Najprawdopodobniej problem leży gdzieś w twojej CapacityChart()funkcji. Po odwiedzeniu linku i uruchomieniu skryptu uruchamia się funkcja CapacityChart () i otwierają się dwa wyskakujące okienka (jedno jest zamknięte zgodnie ze skryptem). Gdzie masz następujący wiersz:

CapacityWindow.document.write(s);

Zamiast tego spróbuj wykonać następujące czynności:

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

EDYCJA
Kiedy zobaczyłem twój kod, myślałem, że piszesz go specjalnie dla IE. Jak wspominają inni trzeba będzie zastąpić odniesienia do document.allz document.getElementById. Jednak po tym nadal będziesz musiał naprawić skrypt, więc zaleciłbym uruchomienie go przynajmniej w IE, ponieważ wszelkie błędy, które popełnisz, zmieniając kod do działania w różnych przeglądarkach, mogą spowodować jeszcze więcej zamieszania. Gdy będzie działał w IE, łatwiej będzie stwierdzić, czy działa on w innych przeglądarkach podczas aktualizacji kodu.

Andy E.
źródło
6
Przy użyciu jquery są również: $("#clickMe").bind('click', function () { alert('hello!'); };)
Roman
32

Powiedziałbym, że lepiej byłoby dodać javascript w sposób nie narzucający się ...

używając jQuery możesz zrobić coś takiego:

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

<input type="button" value="Capacity Chart" id="MyButton" >
Paweł
źródło
4
Zgoda. W wielu przypadkach jQuery i inne frameworki są przesadnie nadmiarowe w przypadku niewielkich ilości javascript i nie wszystkie kody javascript muszą być dostępne w różnych przeglądarkach.
Andy E
2
W porządku… chciałem powiedzieć, że „lepszy sposób na zrobienie tego” jest dyskretnie ... Bez jQuery coś takiego: var btn = document.getElementById ('MyButton'); btn.onclick = function () {CapacityChart ();}
Paul
1
Wydaje się, że ci ludzie używający jQuery używają go do wszystkiego w sieci. Co powiesz na użycie płaskiego JavaScript dla jednego? Boże, jQuery naprawdę działa mi teraz na nerwy. LOL! Nazywam to leniwym sposobem tworzenia sieci, bo chyba tak naprawdę jest.
DoctorLouie,
@DrLouie: W ogóle nie mam nic przeciwko jQuery, jest to dobre rozwiązanie wielu problemów, ale kiedy nie jest oznaczony lub zapytany przez OP, wszelkie wzmianki o jQuery powinny być wspomagane również przez metodę inną niż jQuery, w przeciwnym razie ryzykują a) mylącego pytającego - może nie wiedzieć, co to jest jQuery lub b) denerwującego pytającego, mówiąc mu, aby używał jQuery dla kilku linii kodu javascript. @Paul - Muszę powiedzieć, że to nie była świetna lektura ...
Andy E
1
przeprosiny ... wysłano niewłaściwy link - przeznaczony do opublikowania jednego z przepływów stosu. stackoverflow.com/questions/1588374/...
Paul
8

Twój kod HTML i sposób wywołania funkcji za pomocą przycisku wyglądają poprawnie.

Problem wydaje się być związany z CapacityCountfunkcją. Ten błąd pojawia się w mojej konsoli w przeglądarce Firefox 3.5: „document.all is undefined” w linii 759 pliku bendelcorp.js.

Edytować:

Wygląda na document.allto, że jest to tylko IE i jest niestandardowym sposobem uzyskiwania dostępu do DOM. Jeśli używasz document.getElementById(), prawdopodobnie powinno działać. Przykład: document.getElementById("RUnits").valuezamiastdocument.all.Capacity.RUnits.value

Jeff
źródło
To nie jest konkretny problem z funkcją, która nie generuje żadnych błędów w IE
Andy E
4

To wygląda poprawnie. Myślę, że zdefiniowałeś swoją funkcję albo inną nazwą, albo w kontekście niewidocznym dla przycisku. Dodaj kod

drganie
źródło
3

Po prostu wiesz, że średnik ( ; ) nie powinien znajdować się w przycisku podczas wywoływania funkcji.

Powinien więc wyglądać tak: onclick="CapacityChart()"

to wszystko powinno działać :)

jacki
źródło
2

Jednym z głównych problemów jest to, że używasz wąchania przeglądarki bez ważnego powodu:

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
    }

Używam Chrome, więc navigator.appNamenie będzie Netscape. Czy Chrome obsługujedocument.all ? Może, ale z drugiej strony może nie. A co z innymi przeglądarkami?

Wersja kodu w Netscapegałęzi powinna działać w dowolnej przeglądarce w drodze do Netscape Navigator 2 z 1996 roku, więc prawdopodobnie powinieneś po prostu trzymać się tego ... poza tym, że nie zadziała (lub nie ma gwarancji, że będzie działać) ), ponieważ nie określono nameatrybutu dla inputelementów, więc nie zostaną one dodane do elementstablicy formularza jako nazwane elementy:

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

Albo nadaj im nazwę i użyj elementstablicy, albo (lepiej) użyj

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

który będzie działał na wszystkich nowoczesnych przeglądarkach - nie jest konieczne rozgałęzianie. Aby być bezpiecznym, zastąp to wąchanie wersji przeglądarki większej lub równej 4, zaznaczając opcję getElementByIdwsparcia:

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

Prawdopodobnie chcesz również zweryfikować swoje dane wejściowe; coś jak

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

mogłoby pomóc.

NickFitz
źródło
Cześć NickFitz, jednym z moich wyzwań jest to, że ten skrypt został pierwotnie napisany w 1993 roku - stąd odniesienia do Netscape 4. Miałem pomoc w aktualizacji i działał, dopóki nie wstawiłem go na wyznaczoną stronę.
forrest
Wątpię, aby został napisany w 1993 r., Ponieważ Brendan Eich nie wynalazł JS aż do 1995 r. En.wikipedia.org/wiki/Javascript#History ;-) Zdecydowanie polecam używanie document.getElementByIdi usuwanie innych rzeczy.
NickFitz,
Myślę, że rozsądnie byłoby przynajmniej uruchomić go w IE, a następnie pracować nad zgodnością przeglądarki, w przeciwnym razie nie będzie wiedział, czy jego problemy ze zgodnością przeglądarki zostaną naprawione, ponieważ nadal nie będzie działać.
Andy E
Lepiej, aby działał przy użyciu standardowych technik DOM, wtedy nie będzie żadnych problemów z kompatybilnością przeglądarki, o których można mówić :-)
NickFitz
2

Twój kod nie działa w tym wierszu:

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

próbowałem nadepnąć z firebugiem i tam się nie udaje. które powinny pomóc ci rozwiązać problem.

odwołujesz się do jquery. równie dobrze możesz użyć go we wszystkich tych funkcjach. znacznie wyczyści twój kod.

Patrycja
źródło
Jednak w tej linii nie zawiedzie w IE.
Andy E
ponieważ document.all jest rzeczą IE. powinien po prostu użyć $ ('# RUints'). val () notacja jquery b / c już dołącza jquery. Zapobiega to wszelkim różnicom w przeglądaniu i czyści kod.
Patricia,
2

Mam kod przycisku inteligentnego wywołania zwrotnego funkcji:

<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
źródło
1

PROSTA ODPOWIEDŹ:

   onclick="functionName(ID.value);

Gdzie ID jest identyfikatorem pola wejściowego.

AGrush
źródło
-2

głupi sposób:

onclick="javascript:CapacityChart();"

Powinieneś przeczytać o dyskretnym javascript i użyć metody bind frameworku, aby powiązać wywołania zwrotne ze zdarzeniami dom.

erenon
źródło
@erenon: Oh daj spokój. To nie jest jego problem, notacja jest w porządku, i nie ma powodu, aby wdawać się w skomplikowane wiązania i frameworki tylko ze względu na przypisanie jednego zdarzenia onclick.
Pekka
Dzięki za przybycie do mojej obrony Pekka. Chcę tylko, aby prosty przycisk działał poprawnie.
forrest
3
javascript:Protokół nie jest potrzebna w onclickprzypadku. Zdarzenie onclick jest już javascript. javascript:Protokół jest do wykonywania javascript w atrybucie href linku.
Web_Designer,