【问题标题】:How to send value of input created from a jquery for loop to php using ajax [duplicate]如何使用ajax将从jquery for循环创建的输入值发送到php [重复]
【发布时间】:2020-04-12 23:22:34
【问题描述】:

我有一个向我的表单添加新字段的按钮,以及另一个将输入字段的值提交到服务器端 (php) 的按钮。 我正在尝试获得将值从动态创建的表单输入发送到 php 的最佳方式。

这是我尝试过的

$('#submit').on("click", function(e) {
   e.preventDefault();
   for(var i = 1; i <= 9; i++) {

     if ($('label[name="men'+i+'"]').length) { //for each [i] check if man field exist 
       var manName  = $('select[id="manName'+i+'"]').val();
       var manAge  = $('select[id="manAge'+i+'"]').val();
       if (manName.length < 1) {
         //show input error on the form
       } else {
         //set value for each manName field created 
         window["manName" + i] = manName;
       }

       if (manAge.length < 1) {
         //show input error on the form
       } else {
         //set value for each manAge field created 
         window["manAge" + i] = manAge;
       }
     }
   } else {
     //if man field [i] was not created
     window["manName" + i] = "";
     window["manAge" + i] = "";
     //set man field [i] to empty/null
   }

 //and more of the above to check for women and children fields

}

然后在我的ajax中我有

$.ajax
   ({
   type:"POST",
   url: "send.php",
   data: {"manName1": manName1, "manAge1": manAge1, "manName2": manName2, "manAge2": manAge2, "manName3": manName3, "manAge3": manAge3, "womanName1": womanName1, "womanAge1": womanAge1, "womanName2": womanName2, "womanAge2": womanAge2 }, //and so on for the rest of the women and children
    //cache: false,
    success: function(data) { 
    console.log(data)
    }
    });

这有效,但在响应之前会冻结一段时间。

那么有没有合适的方法呢

【问题讨论】:

  • 它以什么方式“冻结”?服务器是否需要很长时间才能响应?还是客户端代码锁定了浏览器片刻?
  • 是的客户端,在浏览器控制台中出现此错误“未捕获 RangeError:超出最大调用堆栈大小”
  • 这意味着您在代码中的某个地方进行了一些无限递归调用。您可以在导致此错误的调​​用函数中设置断点以找出问题所在。

标签: javascript jquery ajax


【解决方案1】:

我认为主要冻结是由Uncaught RangeError: Maximum call stack size exceeded 引起的,这意味着您在代码的某处进行了一些无限递归调用。 但也许你应该优化你的代码,以尽量减少使用 jQuery 扫描 DOM 元素。

  1. 为每个输入的组包装添加一些类名(假设 .js-inputs-man)以获取下一个 HTML
<div class="js-inputs-man">
    <select id="manName1"></select> 
    <select id="manAge1"></select> 
</div>
  1. 应用下一个代码来聚合数据。不要使用窗口作为收集数据的地方。
$('#submit').on('click', function(e) {
    e.preventDefault();

    var inputs = $('.js-input-man');

    if (input.length === 0) {
        //show input error on the form
    }

    var data = {}

    inputs.each(function (i, input) {
        var elem = $(input);

        data['manAge' + i] = elem.find('[id="manAge' + i +'"]').val();
        data['manName' + i] = elem.find('[id="mannName' + i +'"]').val();
    });

    // similar code for women and children which you can optimize too to not repeat it

    $.ajax({
        type:"POST",
        url: "send.php",
        data: data,
        success: function(data) { 
            console.log(data)
        }
    });
}

【讨论】:

  • 非常感谢,显然用窗口收集数据是个问题,所以我重建并使用了数据,它工作得很好。
【解决方案2】:

您的 for 循环中可能存在某种错误(可能在代码中的其他地方i 的值正在发生变化,或者您的循环正在调用另一个循环等)

如果您想找出哪里出错了,我建议您删除(或注释)一些代码,直到它停止冻结。然后重构坏的部分,直到找到错误。

这是一个示例,说明如何在不遍历元素 ID 的情况下实现您的需要。它在技术上没有任何问题,但 ID 的目的是标记独特的元素。如果你需要不止一个,你应该使用类。这将避免索引变量和列表项被删除时的很多麻烦。

$('button.add').on('click', function (e) {
  e.preventDefault();
  var div = $('<div>');
  div.append('<h3 class="sex">'+this.id+'</h3>')
  div.append('<label class="name">name<input type="text" required></label>');
  div.append('<label class="age">age<input type="number" required></label>');
  var delBt = $('<button>X</button>');
  delBt.on('click', function () {
    $(this).parent().remove();
  });
  div.append(delBt);
  $('#inputContainer').append(div);
});

$('#submit').on('click', function (e) {
  e.preventDefault();
  var data = [];
  $('#inputContainer div').each(function () {
    var sex = $('.sex', this).text();
    var name = $('.name input', this).val();
    var age = $('.age input', this).val();
    data.push({sex, name, age});
  });
  console.clear();
  console.log(data);
/*
  $.ajax({
    type:"POST",
    url: "send.php",
    data: data,
    success: function(data) {console.log(data)}
  });
*/
});
#inputContainer {
  padding: 1em;
}
input {
  width: 5em;
  margin: 0.5em;
}
input:invalid {
  border: 2px dashed red;
}
h3 {
  margin: 0;
}
<form>
  <button id="man" class="add">Add Man</button>
  <button id="woman" class="add">Add Woman</button>
  <button id="child" class="add">Add Child</button>
  <div id="inputContainer"></div>
  <input id="submit" type="submit" value="Submit">
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

如果您的输入列表足够大(例如超过数千个项目),您的用户可能会遇到一些快速冻结,因为 JS 主线程确实阻塞了 UI。 在这种情况下,您应该使用超时或动画帧来避免 UI 阻塞。

【讨论】:

    猜你喜欢
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多