foreach渲染按钮点击触发Ajax仅取首个值的修复方法
问题根因
出现这个问题是两个低级错误导致的:
- 类选择器没有限定查找范围:循环渲染后页面存在多个带
.price、.name类的输入框,直接写jQuery('.name').val()时,jQuery会匹配全页面所有符合规则的元素,默认返回第一个匹配项的值,和你当前点击的按钮完全没关系。 - 代码本身有笔误:你ajax里传
price参数时,取的居然是.name类的值,就算范围对了参数也传错。
另外还有几个不规范的点:@csrf直接写在循环里会重复渲染N个隐藏token、ajaxSetup每次点击都重复初始化、购买类接口用GET请求不符合规范、行内写onclick="event.preventDefault()"冗余。
修复方法
核心原则:点击事件里通过this拿到当前触发事件的按钮,基于这个按钮就近找需要的参数,绝对不要全局搜通用类名。
方案1:保留原有表单结构,修正选择器范围
修正后的Blade模板代码
{{-- 确保页面head区域已经引入csrf meta标签:<meta name="_token" content="{{ csrf_token() }}">,不需要在循环里重复写@csrf --}} @foreach($examples as $example) <div class="new__content"> <form style="background-color: #2A2929;"> <input type="hidden" value="{{$example->price}}" class="price"> <input type="hidden" value="{{$example->name}}" class="name"> {{-- 补上你ajax里要传的gameid字段,之前代码里根本没渲染这个输入框 --}} <input type="hidden" value="{{$example->id}}" class="gameid"> {{-- 把type设为button就不会触发表单默认提交,删掉冗余的行内onclick --}} <button class="buy-btn ajaxSubmit" type="button">BUY</button> </form> </div> @endforeach
修正后的JS代码
jQuery(document).ready(function(){ // csrf头只需要全局初始化一次,不用每次点击都设置 $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') } }); jQuery('.ajaxSubmit').click(function(e){ e.preventDefault(); // 拿到当前点击的按钮,向上查找它所属的父级form const currentForm = jQuery(this).closest('form'); // 只在当前form的范围内查找输入框取值,完全不会串到其他商品的参数 const submitData = { price: currentForm.find('.price').val(), name: currentForm.find('.name').val(), gameid: currentForm.find('.gameid').val() }; jQuery.ajax({ url: "{{ url('/buy') }}", method: 'POST', // 涉及购买、数据写入的接口统一用POST,不要用GET data: submitData, success: function(result){ console.log(result); } }); }); });
方案2:更简洁的data属性写法(推荐)
不需要套form、不需要写隐藏输入框,直接把参数挂在按钮的自定义data属性上,从根源上避免选择器找错范围的问题。
Blade模板代码
@foreach($examples as $example) <div class="new__content"> <button class="buy-btn ajaxSubmit" type="button" data-price="{{$example->price}}" data-name="{{$example->name}}" data-gameid="{{$example->id}}" style="background-color: #2A2929;" > BUY </button> </div> @endforeach
JS取值代码
jQuery(document).ready(function(){ $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') } }); jQuery('.ajaxSubmit').click(function(e){ e.preventDefault(); // 直接从当前点击的按钮上取data属性,不可能拿错值 const currentBtn = jQuery(this); const submitData = { price: currentBtn.data('price'), name: currentBtn.data('name'), gameid: currentBtn.data('gameid') }; jQuery.ajax({ url: "{{ url('/buy') }}", method: 'POST', data: submitData, success: function(result){ console.log(result); } }); }); });
内容的提问来源于stack exchange,提问作者Levarados
相关产品推荐
相关产品推荐

