Javascript 为什么这会导致最大调用堆栈错误?

Javascript 为什么这会导致最大调用堆栈错误?,javascript,jquery,callstack,Javascript,Jquery,Callstack,此代码块触发了最大调用堆栈错误: $(".resume_box").click(function () { $("#resume_upload").trigger("click"); }); 这是它引用的HTML: <div class="resume_box"> <div class="file_instructions"> Please use .pdf format</div> <div class="button_plate"

此代码块触发了最大调用堆栈错误:

$(".resume_box").click(function () {
   $("#resume_upload").trigger("click");
});
这是它引用的HTML:

<div class="resume_box">
   <div class="file_instructions"> Please use .pdf format</div>
   <div class="button_plate">Choose a file</div>
   <input id = "resume_upload" type = "file" name = "resume" style = "display: none" />
</div>

重复最后8行,直到超过堆栈大小。

由于事件传播,事件会在DOM树上冒泡

resume\u上载在.resume\u框中。单击元素会向父元素发送一个冒泡事件

在您的例子中,单击父对象会触发对子对象的单击,该子对象会传播到父对象的处理程序,然后再次触发子对象的单击,从而调用父对象处理程序,依此类推

可以通过在单击内部元素时手动防止传播来解决此问题:

$("#resume_upload").click(function (e) {
   e.stopPropagation();
});

由于事件传播,事件会在DOM树上冒泡

resume\u上载在.resume\u框中。单击元素会向父元素发送一个冒泡事件

在您的例子中,单击父对象会触发对子对象的单击,该子对象会传播到父对象的处理程序,然后再次触发子对象的单击,从而调用父对象处理程序,依此类推

可以通过在单击内部元素时手动防止传播来解决此问题:

$("#resume_upload").click(function (e) {
   e.stopPropagation();
});

问题是因为您正在父元素的单击处理程序中触发对子元素的单击。然后,此事件将DOM向上传播回父对象,这将触发对传播到父对象的子对象的单击,从而触发传播到父对象的子对象。。。因此存在无限递归和堆栈错误

要解决此问题,最好同时将单击处理程序附加到两个元素,而不是以编程方式创建事件:

$(".resume_box, #resume_upload").click(function(e) {
    e.stopPropagation(); // important, as it will prevent the event bubbling .: recursion
    // your logic here...
});

问题是因为您正在父元素的单击处理程序中触发对子元素的单击。然后,此事件将DOM向上传播回父对象,这将触发对传播到父对象的子对象的单击,从而触发传播到父对象的子对象。。。因此存在无限递归和堆栈错误

要解决此问题,最好同时将单击处理程序附加到两个元素,而不是以编程方式创建事件:

$(".resume_box, #resume_upload").click(function(e) {
    e.stopPropagation(); // important, as it will prevent the event bubbling .: recursion
    // your logic here...
});

您正在触发.resume\u框的事件处理程序中的.resume\u框上的单击事件,因为单击事件会使DOM冒泡。相反,只有在尚未单击输入的情况下,才触发手动单击输入:

$(".resume_box").click(function ( e ) {
   if ( e.target.id !== 'resume_upload' )
       $("#resume_upload").trigger("click");
});

您正在触发.resume\u框的事件处理程序中的.resume\u框上的单击事件,因为单击事件会使DOM冒泡。相反,只有在尚未单击输入的情况下,才触发手动单击输入:

$(".resume_box").click(function ( e ) {
   if ( e.target.id !== 'resume_upload' )
       $("#resume_upload").trigger("click");
});

其他答案都是正确的,这里有另一个解决方案:只需从resume\u box元素中删除resume\u upload按钮。因此,触发对按钮的点击不会冒泡到框中,从而结束此调用堆栈

<div class="resume_box">
  <div class="file_instructions"> Please use .pdf format</div>
  <div class="button_plate">Choose a file</div>
</div>
<input id="resume_upload" type="file" name="resume" style="display: none" />

这是一个可行的解决方案。

每一个其他答案都是正确的,这只是另一个解决方案:只需从resume\u box元素中删除resume\u upload按钮。因此,触发对按钮的点击不会冒泡到框中,从而结束此调用堆栈

<div class="resume_box">
  <div class="file_instructions"> Please use .pdf format</div>
  <div class="button_plate">Choose a file</div>
</div>
<input id="resume_upload" type="file" name="resume" style="display: none" />

这是一个可行的解决方案。

因为事件会在dom树中出现。因此,如果在子元素上触发了相同的单击,那么将执行绑定到父元素上的if-click事件

因此,它会创建一个循环并导致错误

解决方案是,您可以使用event.stopPropagation;关于子元素

或将选择器更改为:

$(".resume_box > .button_plate").click(function () {

因为事件会在dom树中出现。因此,如果在子元素上触发了相同的单击,那么将执行绑定到父元素上的if-click事件

因此,它会创建一个循环并导致错误

解决方案是,您可以使用event.stopPropagation;关于子元素

或将选择器更改为:

$(".resume_box > .button_plate").click(function () {