Использование кнопки 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 (см. Ответ Джеффа)
Крис Кричит

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();

РЕДАКТИРОВАТЬ
Когда я увидел ваш код, я подумал, что вы пишете его специально для IE. Как уже упоминалось, вам нужно заменить ссылки наdocument.all с document.getElementById. Однако после этого у вас все еще будет задача исправить скрипт, поэтому я бы рекомендовал сначала заставить его работать, по крайней мере, в IE, поскольку любые ошибки, которые вы совершаете, изменяя код для работы в разных браузерах, могут вызвать еще большую путаницу. Как только он будет работать в IE, будет легче определить, работает ли он в других браузерах, пока вы обновляете код.


7
Используя 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 действительно действует мне на нервы. РЖУНИМАГУ! Я буду называть это ленивым способом создания сети, потому что, думаю, это все, что есть на самом деле.
Доктор Луи

@DrLouie: я ничего не имею против jQuery, это хорошее решение для многих проблем, но когда он не помечен или не задан ОП, любое упоминание о jQuery также должно поддерживаться не-jQuery, иначе они рискуют а) путаницы спрашивающего - он может не знать, что такое jQuery, или б) раздражать спрашивающего, сказав ему использовать jQuery для нескольких строк кода javascript. @ Пол - я должен сказать, что это не было хорошим чтением ...
Энди Э

1
извинения ... неправильная ссылка опубликована - предназначена для публикации стека overoverflow. stackoverflow.com/questions/1588374/…
Пол

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

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. Мне помогли обновить его, и он работал, пока я не вставил его на назначенную страницу.
Форрест

Я сомневаюсь, что это было написано в 1993 году, так как Брендан Айх не изобретал JS до 1995 года. En.wikipedia.org/wiki/Javascript#History ;-) Я бы настоятельно рекомендовал использовать document.getElementByIdи удалять другие материалы.
NickFitz

Я думаю, что было бы разумно, по крайней мере, заставить его работать в IE, а затем работать над совместимостью с браузерами, иначе он не будет знать, будут ли исправлены его проблемы с совместимостью с браузерами, потому что он все еще не будет работать.
Энди Э

Лучше заставить его работать, используя стандартные методы DOM, тогда не будет проблем с совместимостью с браузерами, о которых можно говорить :-)
NickFitz

2

Ваш код не работает в этой строке:

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

я попытался сделать это с помощью firebug, и там ничего не вышло. это должно помочь вам разобраться в проблеме.

Вы ссылаетесь на JQuery. Вы могли бы также использовать это во всех этих функциях. это значительно очистит ваш код.


Тем не менее, в IE не происходит сбоев.
Энди Э

потому что document.all - вещь IE. он должен просто использовать $ ('# RUints'). val () jquery нотацию, потому что он уже включает 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 и использовать метод связывания frameworks для привязки обратных вызовов к событиям dom.


@erenon: О, давай. Это не его проблема, с нотацией все в порядке, и нет никаких причин заходить в сложные привязки и структуры только ради назначения одного события onclick.
Пекка

Спасибо, что пришли на мою защиту Пекка. Я просто хочу, чтобы простая кнопка работала правильно.
Форрест

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