Використання кнопки HTML для виклику функції JavaScript


229

Я намагаюся використовувати кнопку HTML для виклику функції JavaScript.

Ось код:

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

Це, здається, не працює правильно. Чи є кращий спосіб зробити це?

Ось посилання: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html натисніть на вкладку місткості в нижньому лівому розділі. Кнопка повинна генерувати попередження, якщо значення не змінені, і повинна створювати діаграму, якщо ви вводите значення.


6
будь ласка, визначте, "здається, не працює правильно". яку помилку ви отримуєте при натисканні на неї?
просто хтось

Кнопка працює в IE8, але не FF 3.5 через помилку JavaScript (див. Відповідь Джеффа)
Chris Shouts

1
Так, виявляється document.all - нестандартна річ IE; оновив свою відповідь запропонованою альтернативою.
Джефф

@ paper1337, @Jeff: Функція все ще не досягає бажаного ефекту в IE8, тому навіть заміна document.all для document.getElementById не виправить це.
Енді Е

Відповіді:


356

Існує кілька способів обробляти події за допомогою HTML / DOM. Немає справжнього правильного чи неправильного способу, але різні способи корисні у різних ситуаціях.

1: Є визначення цього в HTML:

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

2: Додано його до властивості DOM для події в Javascript:

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

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

3: І є додавання функції до обробника подій за допомогою Javascript:

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

І другий, і третій методи дозволяють виконувати вбудовані / анонімні функції, і обидва повинні бути оголошені після розбору елемента з документа. Перший метод недійсний XHTML, оскільки атрибут onclick відсутній у специфікації XHTML.

1-й і 2-й методи взаємно виключають, тобто використання одного (2-го) перекриє інший (1-го). Третій метод дозволить вам приєднати стільки функцій, скільки вам подобається, до одного і того ж обробника подій, навіть якщо 1-й або 2-й метод також використовувався.

Швидше за все, проблема лежить десь у вашій CapacityChart()функції. Після відвідування вашого посилання та запуску сценарію функція CapacityChart () запускається, і відкриваються дві спливаючі вікна (одна закрита відповідно до сценарію). Де у вас такий рядок:

CapacityWindow.document.write(s);

Спробуйте замість цього:

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

EDIT
Коли я побачив ваш код, я подумав, що ви пишете його спеціально для IE. Як уже згадувалося вам потрібно буде замінити посилання на document.allз document.getElementById. Однак після цього у вас залишиться завдання виправити скрипт, тому я б рекомендував спочатку його попрацювати принаймні в IE, оскільки будь-які помилки, які ви робите, змінюючи код на перехресний браузер, можуть викликати ще більше плутанини. Як тільки він працює в IE, вам буде простіше зрозуміти, чи працює він в інших браузерах, коли ви оновлюєте код.


6
Використовуючи jquery, є також: $("#clickMe").bind('click', function () { alert('hello!'); };)
Роман

32

Я б сказав, що було б краще додати javascript ненав'язливим чином ...

якщо за допомогою jQuery ви можете зробити щось на кшталт:

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

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

4
Домовились. У багатьох випадках jQuery та інші рамки є надмірним надмірним вмістом для невеликої кількості javascript, і не всі коди JavaScript повинні бути перехресними браузерами.
Енді Е

2
Досить справедливо ... пункт, який я намагався зробити, - "кращий спосіб зробити це" - ненав'язливо ... Без jQuery, щось на зразок: var btn = document.getElementById ("MyButton"); btn.onclick = function () {CapacityChart ();}
Павло

1
Ці люди, що використовують jQuery, схоже, налаштовані використовувати його для всього Інтернету. Як щодо використання плоского JavaScript для одного? Боже, jQuery справді мені на нерви. ЛОЛ! Я називаю це ледачим чоловічим способом створення Інтернету, бо я гадаю, що це все справді є.
DoctorLouie

@DrLouie: У мене взагалі нічого немає проти jQuery, це хороше рішення багатьох проблем, але коли він не позначений і не запитується ОП, будь-яка згадка про jQuery також повинна допомагати методом, не jQuery, інакше вони ризикують a) плутати запитувача - він може не знати, що таке jQuery, або b) дратувати запитувача, кажучи йому використовувати jQuery для кількох рядків коду javascript. @Paul - Треба сказати, що це не було чудовим читанням ...
Енді Е


8

Ваш HTML і спосіб виклику функції за допомогою кнопки виглядають правильно.

Здається, проблема в CapacityCount функції. Я отримую цю помилку в консолі на Firefox 3.5: "document.all не визначено" у рядку 759 від bendelcorp.js.

Редагувати:

Схоже, document.allце лише IE і є нестандартним способом доступу до DOM. Якщо ви використовуєте document.getElementById(), це, мабуть, має спрацювати. Приклад: document.getElementById("RUnits").valueзамістьdocument.all.Capacity.RUnits.value


Це не конкретно проблема з функцією, яка не кидає жодних помилок в IE
Енді Е

4

Це виглядає правильно. Я думаю, що ви визначили свою функцію або з іншим іменем, або в контексті, який не видно кнопці. Будь ласка, додайте код


3

Просто ви знаєте, крапка з комою ( ; ) не повинна міститись у кнопці під час виклику функції.

Отже, воно повинно виглядати приблизно так: onclick="CapacityChart()"

тоді все повинно працювати :)


2

Одна з основних ваших проблем полягає в тому, що ви використовуєте нюх браузера без поважних причин:

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
    }

Я на Chrome, так navigator.appNameне буде Netscape. Чи підтримує Chromedocument.all ? Можливо, але тоді знову, можливо, ні. А як щодо інших браузерів?

Версія коду у Netscapeгілці повинна працювати в будь-якому браузері прямо на шляху до Netscape Navigator 2 з 1996 року, тому, ймовірно, ви повинні просто дотримуватися цього ... за винятком того, що він не працюватиме (або не гарантовано працює) ), оскільки ви не вказали nameатрибут для inputелементів, тому вони не будуть додані до elementsмасиву форми як названі елементи:

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

Або дайте їм ім’я та скористайтеся elementsмасивом, або (краще)

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

який буде працювати у всіх сучасних браузерах - розгалуження не потрібно. Для того, щоб бути захищеним, замініть це нюхання на версію браузера, що перевищує 4, чеком на getElementByIdпідтримку:

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

Ви, ймовірно, хочете перевірити також свої дані; щось на зразок

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

допомогло б.


Привіт NickFitz, одна з моїх проблем тут полягає в тому, що цей сценарій був спочатку написаний у 1993 році - отже, посилання на Netscape 4. У мене була допомога щодо оновлення, і він працював, поки я не вставив його на свою призначену сторінку.
forrest

Я сумніваюся, що це було написано в 1993 році, оскільки Брендан Ейх не винайшов JS до 1995 року en.wikipedia.org/wiki/Javascript#History ;-) Я б настійно рекомендував використовувати document.getElementByIdінші матеріали.
NickFitz

Я думаю, було б доцільно принаймні примусити його працювати в IE до того, як працювати над сумісністю браузера, інакше він не знатиме, чи будуть виправлені проблеми з сумісністю його браузера, оскільки він все ще не працюватиме.
Енді Е

Краще
налагодити

2

У цьому рядку код не вдається:

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

Я намагався крокувати, хоча це з firebug, і він не вдається. це повинно допомогти вам з’ясувати проблему.

у вас є посилання на jquery. ви можете також використовувати його у всіх цих функціях. це значно очистить ваш код.


Хоча це не в системі IE на цій лінії.
Енді Е

тому що document.all - річ IE. він повинен просто використовувати $ ('# RUints'). Позначення jquery val () b / c, він вже включає jquery. це усуває будь-які відмінності веб-переглядачів та очищує код.
Патрісія

2

У мене є інтелектуальний код кнопки функцій зворотного дзвінка:

<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

ПРОСТИЙ ВІДПОВІДЬ:

   onclick="functionName(ID.value);

Де ID - ідентифікатор поля введення.


-2

дурний спосіб:

onclick="javascript:CapacityChart();"

Вам слід прочитати про дискретний javascript і використовувати метод прив'язки фреймворків для прив’язки зворотних викликів до подій dom.


@erenon: Ой давай. Це не його проблема, нотація ідеально чудова, і немає ніяких причин вникати в складні зв'язки та рамки лише заради призначення однієї події onclick.
Пекка

Дякуємо, що прийшли на мій захист Пекка. Я просто хочу, щоб проста кнопка працювала правильно.
forrest

3
javascript:Протокол не потрібно в onclickразі. Подія onclick вже javascript. javascript:Протокол для виконання JavaScript в атрибуті HREF ланки.
Web_Designer
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.