为何仅首个容器按钮能发送自身输入值,其余容器无法实现?
解决前的提问内容
我编写了一个脚本,可将值发送至x.php页面。该脚本的设计逻辑为:每个红色dataContainer容器拥有独立的输入框和按钮,点击任意容器内的按钮时,应将该容器内的输入值发送至x.php页面并输出。
当前问题:点击任意按钮均可发起请求,但无论点击哪个容器的按钮,始终仅发送首个dataContainer容器的输入值,而非对应容器自身的值。如何修改才能实现点击按钮时发送对应容器的输入值?
预期效果:点击对应容器的按钮,发送该容器内的输入框值到后端并展示结果。
原代码
index.php
<style> .dataContainer{ background-color: red; width: 185px; position: relative; margin-bottom: 25px; } .dataContainerDesign .a,.b,.send{ display: block; margin: auto; } </style> <script> document.addEventListener('DOMContentLoaded', function(){ var containerButtons = document.querySelectorAll('.dataContainer .send'); for (var i = 0; i < containerButtons.length; i++) { containerButtons[i].addEventListener('click', perContainer); } var xhr= new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ document.querySelector('.dataContainer').innerHTML= xhr.responseText; } }; function perContainer(){ var data = new FormData(); //Var structrue var a= document.querySelector('.a').value; var b= document.querySelector('.b').value; // //Data data.append('a', a); data.append('b', b); // xhr.open('POST','x'); xhr.send(data); } }); </script> <div class='dataContainer dataContainerDesign'> <input class='a' type='text'> <input class='b' type='text'> <button class='send'>Send</button> </div><!--</dataContainer>--> <div class='dataContainer dataContainerDesign'> <input class='a' type='text'> <input class='b' type='text'> <button class='send'>Send</button> </div><!--</dataContainer>--> <div class='dataContainer dataContainerDesign'> <input class='a' type='text'> <input class='b' type='text'> <button class='send'>Send</button> </div><!--</dataContainer>--> <div class='dataContainer dataContainerDesign'> <input class='a' type='text'> <input class='b' type='text'> <button class='send'>Send</button> </div><!--</dataContainer>-->
x.php
<p style='display: inline-block;'> <?php $a= $_POST['a']; $b= $_POST['b']; echo 'Sent Values: '; echo $a.','.$b; ?> </p>
解决方案
问题的核心在于你用了document.querySelector('.a')和document.querySelector('.b')——这个方法只会返回页面中第一个匹配选择器的元素,所以不管点哪个按钮,拿到的都是第一个容器的输入值。另外全局复用同一个XHR对象可能导致请求冲突,更新内容时也只修改了第一个容器,这些都是要调整的点。
下面是修改后的index.php代码,关键修改我都标出来了:
<style> .dataContainer{ background-color: red; width: 185px; position: relative; margin-bottom: 25px; padding: 10px; /* 加内边距让内容不贴边 */ } .dataContainerDesign .a,.b,.send{ display: block; margin: 10px auto; /* 增加间距更美观 */ } </style> <script> document.addEventListener('DOMContentLoaded', function(){ var containerButtons = document.querySelectorAll('.dataContainer .send'); for (var i = 0; i < containerButtons.length; i++) { containerButtons[i].addEventListener('click', perContainer); } function perContainer(){ // 关键修改1:通过当前点击的按钮,找到它所在的父容器 const currentContainer = this.closest('.dataContainer'); // 关键修改2:在当前容器内查找输入框,而非全局查找 const a = currentContainer.querySelector('.a').value; const b = currentContainer.querySelector('.b').value; var data = new FormData(); data.append('a', a); data.append('b', b); // 关键修改3:每次请求创建新的XHR对象,避免复用冲突 var xhr= new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState === 4 && xhr.status === 200){ // 关键修改4:更新当前点击按钮所在的容器内容 currentContainer.innerHTML= xhr.responseText; // 重新添加按钮并绑定事件,支持再次输入发送 currentContainer.innerHTML += '<button class="send">Send</button>'; currentContainer.querySelector('.send').addEventListener('click', perContainer); } }; xhr.open('POST','x.php'); xhr.send(data); } }); </script> <div class='dataContainer dataContainerDesign'> <input class='a' type='text' placeholder="输入a"> <input class='b' type='text' placeholder="输入b"> <button class='send'>Send</button> </div> <div class='dataContainer dataContainerDesign'> <input class='a' type='text' placeholder="输入a"> <input class='b' type='text' placeholder="输入b"> <button class='send'>Send</button> </div> <div class='dataContainer dataContainerDesign'> <input class='a' type='text' placeholder="输入a"> <input class='b' type='text' placeholder="输入b"> <button class='send'>Send</button> </div> <div class='dataContainer dataContainerDesign'> <input class='a' type='text' placeholder="输入a"> <input class='b' type='text' placeholder="输入b"> <button class='send'>Send</button> </div>
修改说明:
- 锁定当前容器:用
this.closest('.dataContainer')定位到点击按钮所属的容器,把查找范围限制在当前容器内。 - 局部获取输入值:在当前容器内调用
querySelector,确保拿到的是对应容器的输入内容。 - 独立请求对象:每次点击都创建新的XHR,避免多个请求互相干扰。
- 更新对应容器:请求成功后只修改当前容器的内容,并且重新添加按钮绑定事件,让用户可以再次发送新的内容。
x.php的代码不需要修改,保持原样即可。现在点击每个容器的按钮,都会发送该容器内的输入值,并且在对应容器里展示返回结果。
内容的提问来源于stack exchange,提问作者user9767744
相关产品推荐
相关产品推荐

