为什么这会导致最大调用堆栈错误?
Why is this causing a maximum call stack error?
此代码块触发了最大调用堆栈错误:
$(".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>
我已经检查过了,JS 文件或 HTML 文件中没有其他同名、class 或 id 的内容。堆栈如下所示:
trigger @ jquery.min.js:4
(anonymous) @ jquery.min.js:4
each @ jquery.min.js:2
each @ jquery.min.js:2
trigger @ jquery.min.js:4
(anonymous) @ script.js:70
dispatch @ jquery.min.js:3
r.handle @ jquery.min.js:3
trigger @ jquery.min.js:4
(anonymous) @ jquery.min.js:4
each @ jquery.min.js:2
each @ jquery.min.js:2
trigger @ jquery.min.js:4
(anonymous) @ script.js:70
重复最后 8 行,直到超出堆栈大小。
由于事件传播,事件在 DOM 树中冒泡。
#resume_upload
在 .resume_box
之内。单击一个元素会向父级发送一个冒泡的事件。
在您的情况下,单击父级会触发对子级的单击,该子级会传播到父级的处理程序,然后再次触发子级单击,从而调用父级处理程序,依此类推。
您可以通过在单击内部元素时手动阻止传播来解决此问题:
$("#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...
});
您正在 .resume_box
的事件处理程序中触发 .resume_box
上的点击事件(因为点击事件向上冒泡 DOM)。相反,只有在尚未点击输入时才触发手动点击输入:
$(".resume_box").click(function ( e ) {
if ( e.target.id !== 'resume_upload' )
$("#resume_upload").trigger("click");
});
所有其他答案都是正确的 (event bubbling),这只是另一个解决方案:只需 从 resume_box
中删除 resume_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" />
这是一个有效的 codepen。
因为事件在 dom 树中冒泡。因此,如果在子元素上触发了相同的 click
,则绑定在父元素上的 click
事件将被执行。
因此它创建了一个循环并导致你得到的错误。
解决方案是您可以在子元素上使用 event.stopPropagation();
。
或将您的选择器更改为:
$(".resume_box > .button_plate").click(function () {
此代码块触发了最大调用堆栈错误:
$(".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>
我已经检查过了,JS 文件或 HTML 文件中没有其他同名、class 或 id 的内容。堆栈如下所示:
trigger @ jquery.min.js:4
(anonymous) @ jquery.min.js:4
each @ jquery.min.js:2
each @ jquery.min.js:2
trigger @ jquery.min.js:4
(anonymous) @ script.js:70
dispatch @ jquery.min.js:3
r.handle @ jquery.min.js:3
trigger @ jquery.min.js:4
(anonymous) @ jquery.min.js:4
each @ jquery.min.js:2
each @ jquery.min.js:2
trigger @ jquery.min.js:4
(anonymous) @ script.js:70
重复最后 8 行,直到超出堆栈大小。
由于事件传播,事件在 DOM 树中冒泡。
#resume_upload
在 .resume_box
之内。单击一个元素会向父级发送一个冒泡的事件。
在您的情况下,单击父级会触发对子级的单击,该子级会传播到父级的处理程序,然后再次触发子级单击,从而调用父级处理程序,依此类推。
您可以通过在单击内部元素时手动阻止传播来解决此问题:
$("#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...
});
您正在 .resume_box
的事件处理程序中触发 .resume_box
上的点击事件(因为点击事件向上冒泡 DOM)。相反,只有在尚未点击输入时才触发手动点击输入:
$(".resume_box").click(function ( e ) {
if ( e.target.id !== 'resume_upload' )
$("#resume_upload").trigger("click");
});
所有其他答案都是正确的 (event bubbling),这只是另一个解决方案:只需 从 resume_box
中删除 resume_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" />
这是一个有效的 codepen。
因为事件在 dom 树中冒泡。因此,如果在子元素上触发了相同的 click
,则绑定在父元素上的 click
事件将被执行。
因此它创建了一个循环并导致你得到的错误。
解决方案是您可以在子元素上使用 event.stopPropagation();
。
或将您的选择器更改为:
$(".resume_box > .button_plate").click(function () {