【问题标题】:Javascript form validation only works in firefoxJavascript 表单验证仅适用于 firefox
【发布时间】:2010-05-28 17:57:09
【问题描述】:

我对 Javascript 比较陌生,所以我希望这是一个简单的错误。我构建了一个在表单的 onSubmit 上调用的通用表单验证函数。该函数循环遍历表单的所有子元素,查找某些类,并分析相应字段的内容。如果它发现一些缺失或错误,它会显示相应的错误消息 div 并返回 false,从而阻止表单提交到 php 页面。

它在 firefox 3.6.3 中运行良好,但在我测试过的所有其他浏览器(Safari 4.0.4、Chrome 4.1、IE8)中,它似乎忽略了 onSubmit 并直接跳转到 php 处理页面。

HTML 代码:

    <form name='myForm' id='myForm' action='process_form.php' method='post' onSubmit="return validateRequired('myForm')">

   <fieldset class="required radioset">
    <label for='selection1'>
     <input type='radio' name='selection' id='selection1' value='1'/>
     Option 1
    </label>
    <label for='selection2'>
     <input type='radio' name='selection' id='selection2' value='2'/>
     Option 2
    </label>
    <label for='selection3'>
     <input type='radio' name='selection' id='selection3' value='3'/>
     Option 3
    </label>
    <label for='selection4'>
     <input type='radio' name='selection' id='selection4' value='4'/>
     Option 4
    </label>
    <div class='errorBox' style='visibility:hidden'>
     Please make a selection
    </div>
   </fieldset>

   <fieldset class="required checkset">
    <label>
     Choice 1
     <input type='checkbox' name='choices' id='choice1' value='1'/>
    </label>
    <label>
     Choice 2
     <input type='checkbox' name='choices' id='choice2' value='2'/>
    </label>
    <label>
     Choice 3
     <input type='checkbox' name='choices' id='choice3' value='3'/>
    </label>
    <label>
     Choice 4
     <input type='checkbox' name='choices' id='choice4' value='4'/>
    </label>
    <div class='errorBox' style='visibility:hidden'>
     Please choose at least one
    </div>
   </fieldset>


   <fieldset class="required textfield" >
    <label for='textinput1'>
     Required Text:
     <input type='text' name='textinput1' id='textinput1' size='40'/>
    </label>
    <div class='errorBox' style='visibility:hidden'>
     Please enter some text
    </div>
   </fieldset>

   <fieldset class="required email textfield">
    <label for='email'>
     Required Email:
     <input type='text' name='email' id='email' size='40'/>
    </label>
    <div class='errorBox' style='visibility:hidden'>
     The email address you have entered is invalid
    </div>
   </fieldset>


   <div>
    <input type='submit' value='submit'>
    <input type='reset' value='reset'>
   </div>

  </form>

JAVASCRIPT 代码:

    function validateRequired(id){

 var form = document.getElementById(id);
 var errors = 0;
 var returnVal = true;
 for(i = 0; i < form.elements.length; i++){
  var elem = form.elements[i];
  if(hasClass(elem,"required")){

   /*RADIO BUTTON or CHECK BOX SET*/
   if(hasClass(elem,"radioset") || hasClass(elem,"checkset")){
    var inputs = elem.getElementsByTagName("input");
    var check = false;
    for(j = 0; j < inputs.length; j++){
     if(inputs[j].checked){
      check = true;
     }
    }
    if(check == false){
     errors += 1;
     showError(elem);
    } else {
     hideError(elem);
    }
   }

   /*TEXT FIELD*/
   else if(hasClass(elem,"textfield")){
    var input = elem.getElementsByTagName("input");
    if(input[0].value == ""){
     errors += 1;
     showError(elem);
    } else {
     hideError(elem);

     /*EMAIL ADDRESS*/
     if(hasClass(elem,"email")){
      if(isValidEmail(input[0].value) == false){
       errors += 1;
       showError(elem);
      } else {
       hideError(elem);
      }
     }
    }
   }
  }
 }
 if(errors > 0){
  returnVal = false;
 } else {
  returnVal = true;
 }
 return returnVal;}

我知道要查看的代码很多,但如果有任何帮助,我们将不胜感激。由于它在一个浏览器中运行良好,我不知道如何开始调试。 谢谢 安德鲁

【问题讨论】:

    标签: javascript validation forms cross-browser onsubmit


    【解决方案1】:
    for(i = 0; i < form.elements.length; i++){
        var elem = form.elements[i];
        if(hasClass(elem,"required")){
    

    问题是您的required 和其他类都放在&lt;fieldset&gt; 元素上。

    Fieldset 元素包含在 IE、Firefox 和 Opera 上的 form.elements 集合中,但不包括 WebKit 浏览器(Chrome、Safari)。正是这些浏览器让我的表单失败了。

    &lt;fieldset&gt; 被包含在 elements 集合中一直是一个奇怪的怪癖。 DOM Level 2 HTML 规范指出集合中应该只存在“表单控件元素”,而 HTML4's definition 似乎不包括没有控件名称或值的字段集。

    您或许可以更改您的代码以使用 getElementsByTagName 来获取字段集:

    var fieldsets= form.getElementsByTagName('fieldset');
    for (var i= 0; i<fieldsets.length; i++) {
        var elem= fieldsets[i];
    

    【讨论】:

    • 谢谢。不过,我不确定您如何测试我的表单,因为我没有在此处包含所有功能。 hasClass(), isValidEmail(), showError(), hideError()...这些是我创建的函数
    • 哦,很明显他们应该做什么,并模拟一个存根。
    • 这行得通,你一针见血。谢谢!我对其进行了更改,使其仅查找“fieldset”元素,现在它适用于所有 4 个浏览器。我最初的想法是我可以将“必需”类添加到任何表单元素,但我认为要求它是一个字段集是可行的。
    【解决方案2】:

    我不会使用 hasClass。这是另一种可能更适合您的尝试方法:

    var node_list = document.getElementsByTagName('input');
    for (var i = 0; i < node_list.length; i++) {
        var node = node_list[i];
    
        if (node.getAttribute('type') == 'text') {
            // do something here with a <input type="text" .../>
            alert(node.value);
        }
    } 
    

    我知道 IE 在从具有多个关联的类的某些元素中获取类时遇到问题。无论如何,这是一个方便的功能。

    【讨论】:

      【解决方案3】:

      如果您有任何类型的 JavaScript 错误,该函数不会返回 false,因此会触发提交数据的默认行为。

      尝试先通过 [http://www.javascriptlint.com/online_lint.php][1],然后通过调试器运行您的代码。

      【讨论】:

      • 用 === 替换了几个 ==,这些是唯一的错误。还是一样的问题
      【解决方案4】:

      尽量不要使用 if(errors > 0)...只是在每种情况下(对于错误的输入) put return false; 并在最后一个括号之前的末尾返回 true; 并更好地使用:

      onSubmit="return validateRequired(this)"
      

      并且这行不需要(以防您删除错误变量)

       var form = document.getElementById(id);
       var errors = 0;
       var returnVal = true;
      

      【讨论】:

      • 谢谢,我不确定这是否可行,因为我必须在返回之前遍历表单的所有元素,否则它只会显示它得到的第一个错误。这就是为什么我把我的回报放在最后。有意义吗?
      • 您可以保留errors,但returnVal 是多余的,只需使用return errors===0。无论哪种方式,将id 更改为直接使用this 都是一个好主意。更好的是直接从 JavaScript (document.getElementById('myForm').onsubmit= function() { ...validation stuff... }) 编写处理程序,并在其中直接使用 thisreturn,而不是使用讨厌的内联事件处理程序属性。
      • 我已将其更改为 onSubmit="return validateRequired(this)"。没有区别,在 Firefox 中仍然有效,但没有别的
      • 我已将其更改为...
        ... 现在它根本不起作用。所有浏览器只跳转到 process_form.php
      • 你必须自然地将&lt;script&gt;放在它引用的@​​987654332@下面,否则该对象将不存在。 ...validation stuff... 我的意思是 validateRequired 的当前内容,更改为 cthulu 所说的使用 this 而不是尝试通过 id 获取表单元素。不需要额外的包装函数,除了调用 validateRequired 之外什么都不做。
      【解决方案5】:

      我敢肯定,这不是您的问题的原因,但最好不要在未选择其中一个的情况下提供一组单选按钮。

      在您的特定情况下,如果您知道在提供页面时设置了一个,则不需要“必需”检查;用户无法将单选按钮置于未选中的状态。选择一个合理的默认值,使其成为第一个选项,然后将其选中。简化您的生活:)

      来自 W3C:

      http://www.w3.org/TR/html401/interact/forms.html#radio

      如果集合共享中没有单选按钮 最初是相同的控件名称 "on",用于选择的用户代理行为 最初“打开”的控件是 不明确的。笔记。由于现有 实现处理这种情况 不同的是,当前的规范 不同于 RFC 1866 ([RFC1866] 第 8.1.2.4 节),其中指出:

      At all times, exactly one of the radio 
      buttons in a set is checked. If
      none of the <INPUT> elements of a set
      of radio buttons specifies `CHECKED',
      then the user agent must check the
      first radio button of the set
      initially.
      

      由于用户代理行为不同, 作者应确保在每组 最初是单选按钮的数量 “开”。

      【讨论】:

        【解决方案6】:

        回到基础:你说它“似乎忽略了 onsubmit”。这留下了我能想到的三种可能性:

        1. 您的函数永远不会被调用
        2. 它已被调用,但由于错误而正在中途轰炸
        3. 它被调用了,但并没有按照你的想法做,总是返回 true

        从你的问题中不清楚它是什么,所以如果我是你,我会通过在函数开头放置一个警报来开始调试它,以查看 IE 是否在调用它 - 然后将该警报向下移动并运行再次验证,并查看它停止出现的位置(任何错误都必须高于该点)。

        我还想从调用它的地方提醒返回值,看看返回了什么。如果它总是正确的,那么你的代码正在工作,但没有按照你的想法做。

        从那里,您至少可以更清楚地了解正在发生的事情,如果不是要仔细检查的确切代码块。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-23
          • 2022-01-21
          • 2017-09-30
          • 2015-12-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多