2009-08-05 3 views
1

У меня есть форма, которая отправляет данные на ту же страницу. Основываясь на выборе переключателя пользователя, я вставляю checked = "checked" в элемент формы переключателя, чтобы повторно отобразить правильный выбор. Это прекрасно работает, однако, когда форма отображается повторно (в случае плохой записи и т. Д.), Мне нужно открыть div (содержащий соответствующие поля из формы).Автоматическое создание div в зависимости от статуса переключателя с JavaScript

У меня есть событие onclick, которое показывает div в первую очередь (до того, как пользователь разместил форму), и это отлично работает, но когда я перерисовываю форму, я не хочу, чтобы пользователю приходилось вручную раскрывать форму снова щелкнув.

Поэтому я кой-что вдоль следующие линии (сильно вырублены для целей этого поста) пытаюсь ...

<link href="styles/style1.css" rel="stylesheet" type="text/css" /> 
<script language="JavaScript"> 
    if (document.getElementById('complete_yes').checked) { 
    document.getElementById('repair_complete').style.display = 'block'; 
    } else { 
    document.getElementById('repair_complete').style.display = 'none'; 
    } 
</script> 
<form action="javascript_test.php" method="POST"> 
    <input id="complete_yes" type="radio" name="complete" checked="checked" value="true"/>Yes 
    <input id="complete_no" type="radio" name="complete" value="false"/>No 
    <input type="submit" value="Save"> 
    <div id="repair_complete"> 
    I'm a div! 
    </div> 

... но он возвращает Требуются объект яваскрипт ошибки (как это делает в 'реальной' страницы):

Сообщение: требуется объект
Line: 3
Char: 1
код: 0
URI: http://localhost/repair_system/javascript_test.php

Почему это? Не правильно ли я ссылаюсь на элемент формы? Извиняюсь, если я являюсь «div» (преднамеренный плохой каламбур!), Мне еще предстоит узнать о забавах и играх javascript!

ответ

1

Потому что ваш браузер не завернуты внутри функции, то браузер выполняет его, как только он «добирается до него». В этом случае JS выполняется до того, как браузер достигнет html, объявляющего вашу форму.

Простейшим решением является перемещение Javascript после формы. Более надежное решение заключалось бы в том, чтобы обернуть код в функцию и вызвать это как-то - из того, что вы пытаетесь сделать, в этом случае это будет событие onLoad тега тела:

<head> 
<script language="JavaScript"> 
    function showHelpDiv() { 
    if (document.getElementById('complete_yes').checked) { 
    document.getElementById('repair_complete').style.display = 'block'; 
    } else { 
    document.getElementById('repair_complete').style.display = 'none'; 
    } 
    } 
</script> 
</head> 
<body onload="showHelpDiv()"> 
<form action="javascript_test.php" method="POST"> 
    <input id="complete_yes" type="radio" name="complete" checked="checked" value="true"/>Yes 
    <input id="complete_no" type="radio" name="complete" value="false"/>No 
    <input type="submit" value="Save"> 
    <div id="repair_complete"> 
    I'm a div! 
    </div> 
+1

Использование onload - довольно стандартный подход, но если у вас большие ресурсы на странице, это может вызвать задержку между рендерингом разметки и запуском вашего скрипта. См. Http: // stackoverflow.com/questions/473628/what-external-resources-are -load-when-window-onload-event-is -ired-and-what-для получения дополнительной информации о порядке событий загрузки. – Joel

+0

Спасибо за ответ - запуск этого кода дает ту же ошибку, хотя ... – cw84

0

Это потому, что Javascript выполняется непосредственно перед тем, как остальные объекты будут созданы.
Поместите свой javascript-код в тело функции и добавьте эту функцию в событие onclick для всего, что вам нужно.

<link href="styles/style1.css" rel="stylesheet" type="text/css" /> 
<script language="JavaScript"> 
function test() { 
    if (document.getElementById('complete_yes').checked) { 
    document.getElementById('repair_complete').style.display = 'block'; 
    } else { 
    document.getElementById('repair_complete').style.display = 'none'; 
    } 
} 
</script> 
<form action="javascript_test.php" method="POST"> 
<input id="complete_yes" type="radio" name="complete" checked="checked" value="true" onClick="javascript: test();"/>Yes 
<input id="complete_no" type="radio" name="complete" value="false" onClick="javascript: test();"/>No 
<input type="submit" value="Save"> 
<div id="repair_complete"> 
    I'm a div! 
</div> 
</form> 
1

Ваш код выполняется в процессе загрузки документа, а DOM дерево еще не готов. Поэтому он пытается получить доступ к элементу, который еще не существует.

Возможно, вы захотите вместо этого обработать обработчик событий, который переключает div, когда установлен флажок.

Я предпочитаю jQuery, который абстрагирует вещи, такие как обработка кросс-браузера, предоставляет множество приятных помощников и обычно делает код более чистым (при правильном написании).Нечто подобное должно работать:

$(document).ready(function() { 
    $('#repair_complete').toggle($('#complete_yes').is(':checked')); 
} 

выше можно грубо перевести как:

  • При загрузке документа, выполните следующие действия:
  • Добавь обработчик событий для «change» события любые элементы типа «input» с именем «complete»
  • Когда срабатывает обработчик событий, переключите видимость элемента с идентификатором «repair_complete», где он должен быть виден, если t он элемент с идентификатором «complete_yes» проверяется

Обновление: JS выше в настоящее время на самом деле то, что вы хотите, первоначально я это написал, как OnClick

0

Мне кажется, что ваш сценарий стреляет до того, как форма будет нарисована, вам может понадобиться переместить блок сценария после элемента формы. В принципе, я думаю, что document.getElementById ('complete_yes'). Checked проверяет null.checked, что вызовет ошибку, требуемую объектом.

0

Вы должны сделать действие переключателя для изменения видимости div (то есть «надавить» на него статус), а не «вытащить» состояние div через статус переключателя при рендеринге время (которое, по словам Андрея, не будет отменено).

0

Похоже, проблема в коде инициализации. Javascript вызывается до того, как страница закончит рендеринг. Это один из раздражающих аспектов события «onload», который, на мой взгляд, просто не работает так, как должен в каждом браузере.

Существует технология перекрестного браузера для вызова кода инициализации один раз и только один раз после полной загрузки DOM.

Попробуйте этот код в голову вашего HTML:

function showHelpDiv() { 
    if (document.getElementById('complete_yes').checked) { 
    document.getElementById('repair_complete').style.display = 'block'; 
    } else { 
    document.getElementById('repair_complete').style.display = 'none'; 
    } 
} 

function InitOnce() 
{ 
    if (arguments.callee.done) return; 
    arguments.callee.done = true; 

    showHelpDiv(); 
} 

/* for Mozilla */ 
if (document.addEventListener) 
{ 
    document.addEventListener("DOMContentLoaded", InitOnce, null); 
} 

/* for Internet Explorer */ 
/*@cc_on @*/ 
/*@if (@_win32) 
     document.write("<script defer src=ie_onload.js><"+"/script>"); 
/*@end @*/ 

/* for other browsers */ 
window.onload = InitOnce; 

И тогда вам нужно создать ie_onload.js файл, содержащий эту строку для совместимости IE:

InitOnce(); 

I «Я пробовал другие методы, но никто не работает так прекрасно, как это. Я считаю, что изначально я нашел это решение здесь: http://dean.edwards.name/weblog/2005/09/busted/

Я использую его в онлайн-приложении, которое получает 500 уникальных посещений в день или около того, и это было надежным для нас.