【问题标题】:In JavaScript/jQuery which is syntactically correct, why does execution never get beyond `$('form').submit(function(event){`?在语法正确的 JavaScript/jQuery 中,为什么执行永远不会超出`$('form').submit(function(event){`?
【发布时间】:2019-06-27 22:34:18
【问题描述】:

我有一些 JavaScript/jQuery 正在尝试在本地运行以进行测试。它以$( 'form' ).submit(function(event) { 开头,但永远不会超出此范围。 (我在那一行之后放了一个console.log。它永远不会执行。我知道js正在被执行,因为在那一行之前的console.log确实执行了。)syntax checker没有错误。

JavaScript:

$( 'form' ).submit(function(event) {
 const SelectElms = $( 'select' );
  var  a          = [];
  var  selectVals = Array.from(SelectElms).reduce((a,n) => {
    if(n.value && n.value !== 'unsure' && n.value !== 'not attend') {
      a.push( {
                 'index': n,
                 'room': n.value
              }
            );
    }  // end if
    return a;
  });  //  end def arrow fn & reduce
  event.preventDefault();
});  //  end def anonymous fn & submit

在下面的 sn-p 中,表单正确显示,但在提交时,控制台会闪烁错误消息一秒钟,然后消失。它显示的时间太短而无法阅读。然后,错误消息“自定义错误模块无法识别此错误”出现在结果窗格中。

另外,如果您愿意,请检查 js 的其余部分是否正确。我想要做的是创建一个对象数组,表单中每个<select> 元素一个对象。每个对象都应该有<select>元素的索引位置和值({'index': n, 'room': n.value})。

在他对prior question 的回答中,MisterJojo 做了类似的事情,我试图在本地运行。虽然它在他的 sn-p 中运行,但当我在本地运行它时,它会产生一个 TypeError,querySelector('#My-Form') 返回 null。我复制并粘贴了他的 js 和 HTML。该表单在<form> 标记中有id="My-Form"。此外,语法检查器会返回几个错误。因此,我无法实施他的解决方案或使其适应这个问题。注意:它确实在this jsfiddle 中运行。

非常感谢您的帮助。

片段:

$( 'form' ).submit(function(event) {
 const SelectElms = $( 'select' );
  var  a          = [];
  var  selectVals = Array.from(SelectElms).reduce((a,n) => {
    if(n.value && n.value !== 'unsure' && n.value !== 'not attend') {
      a.push( {
                 'index': n,
                 'room': n.value
              }
            );
    }  // end if
    return a;
  });  //  end def arrow fn & reduce
  event.preventDefault();
});  //  end def anonymous fn & submit
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post">
  <div>
    <label>First Name
    <input type="text" name="fname" size="25">
  </label>
  </div>
  <div>
    <label>Last Name
    <input type="text" name="lname" size="25">
  </label>
  </div>
  <div>
    <label>email address
    <input type="email" name="email" size="25">
  </label>
  </div>
  <div>
    <label>08:30 Keynote Speaker
    <select class="select" name="select 0830">
      <option value="unsure">unsure</option>
      <option value="attend">attend</option>
      <option value="not attend">not attend</option>
    </select>
  </label>
    <label>09:00 Classes
    <select class="select" name="select 0900">
      <option value="unsure">unsure</option>
      <option value="A">room A</option>
      <option value="B">room B</option>
    </select>
    </label>
    <label>10:30 Classes
    <select class="select" name="select 1030">
      <option value="unsure">unsure</option>
      <option value="A">room A</option>
      <option value="B">room B</option>
    </select>
  </label>
  </div>
  <div>
    <input type="submit" value="submit form">
  </div>
</form>

【问题讨论】:

  • In the snippet below, the form displays correctly, but, on submit, the console flashes an error message for a second, then disappears. 这是表单被提交并替换页面的症状 - 但是,在你的问题中运行 sn-p,看起来事件是 preventDefault()ed 正确,所以表单没有提交,stacksn-ps.net 错误页面没有出现?
  • 至于 null 元素错误,请参阅stackoverflow.com/questions/14028959/…(要修复,我会给你的&lt;script&gt; 标签添加defer 属性)
  • 事件处理程序中的错误将使 JS 停止运行,并且由于您只是在最后阻止默认行为,因此表单仍将提交。这是一个固定版本:jsfiddle.net/khrismuc/feqzL684
  • @ChrisG 哦,酷。我看到你使用mapfilter。感谢您提供的信息。

标签: javascript jquery forms


【解决方案1】:

在你的 reducer 函数中,当你不向它传递初始值时,它将使用第一个元素作为累加器,所以当你认为你正在推入 a 时,情况并非如此,它被替换为您的第一个选择:

$('form').submit(function(event) {
  event.preventDefault(); // <-- MOVE this to be able to see the errors
  const SelectElms = $('select');
  // var a = [];  <-- Not needed
  var selectVals = Array.from(SelectElms).reduce((a, n) => {
    if (n.value && n.value !== 'unsure' && n.value !== 'not attend') {
      a.push({
        'index': n,
        'room': n.value
      });
    } // end if
    return a;
  }, []); //  end def arrow fn & reduce   <-- A is being initialized here, the 
                                           // second argument to reduce
console.log(selectVals);
}); //  end def anonymous fn & submit
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post">
  <div>
    <label>First Name
    <input type="text" name="fname" size="25">
  </label>
  </div>
  <div>
    <label>Last Name
    <input type="text" name="lname" size="25">
  </label>
  </div>
  <div>
    <label>email address
    <input type="email" name="email" size="25">
  </label>
  </div>
  <div>
    <label>08:30 Keynote Speaker
    <select class="select" name="select 0830">
      <option value="unsure">unsure</option>
      <option value="attend">attend</option>
      <option value="not attend">not attend</option>
    </select>
  </label>
    <label>09:00 Classes
    <select class="select" name="select 0900">
      <option value="unsure">unsure</option>
      <option value="A">room A</option>
      <option value="B">room B</option>
    </select>
    </label>
    <label>10:30 Classes
    <select class="select" name="select 1030">
      <option value="unsure">unsure</option>
      <option value="A">room A</option>
      <option value="B">room B</option>
    </select>
  </label>
  </div>
  <div>
    <input type="submit" value="submit form">
  </div>
</form>

但是,reduce 运行的函数将数组中的所有元素减少为一个值,因此您使用了错误的函数。来自MDN

reduce() 方法在 数组的每个元素,产生一个输出值

请改用map

 var a = [];
 var selectVals = Array.from(SelectElms).map((n, i) => {
   if (n.value && n.value !== 'unsure' && n.value !== 'not attend') {
     a.push({
       'index': i,
       'room': n.value
     });
   } // end if
   return a;
 });

【讨论】:

  • 感谢您的精彩解释和解决方案。为什么变量a不需要初始化?另外,我知道这是不公平的,也是一种负担,但是您知道为什么当我在本地尝试时,工作小提琴 (jsfiddle.net/alxfyv/2aj5fhwd) 代码会失败吗?执行似乎没有超出$('form').submit 行。我知道我的 scripts.js 文件正在加载,因为我放在第一个的 console.log 被执行,而 .submit 行之后的那个没有被执行。我粘贴了小提琴代码。没有错误信息。这就像让医生通过电话进行诊断,我知道。
  • @alxfyv 如果使用reduce,则不需要初始化only。您将一个空数组作为第三个参数传递。这将被填充到函数体中并返回。可能是因为没有加载 jQuery。如果我这样做,对我有用。并且记住,把你的preventDefault放在函数体的第一件事,否则如果有异常,它不会被触发。
  • @alxfyv 我一直在说“第三个参数”,但实际上是第二个。抱歉打错了。
  • 我发现了阻止本地执行的错误。我在脚本中添加了$(document).ready(function( ... },一切都是杰克,笨拙的,只是桃子。你解决了困扰我好几天的问题。我非常感激。
  • @alxfyv 但是,在第二次阅读时,我认为答案可能是错误的。您说该对象应包含“ 的索引位置和select 元素的值”。您的意思是select 本身的索引还是选择的option?如果是后者,那就错了,传递的索引是select的索引。
【解决方案2】:

控制台应该闪烁片刻,因为您没有添加任何 url 来提交表单,默认情况下它假定 # 这意味着您正在提交同一页面。

结果应该类似于重新加载页面。

我看到你有空格 name 属性。您可能想要更改它,因为可能某些浏览器将无法处理它们。

【讨论】:

    猜你喜欢
    • 2016-08-04
    • 1970-01-01
    • 2015-05-24
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    相关资源
    最近更新 更多