动态追加的子按钮点击不执行JS代码问题求助
问题描述
我有一组通过函数动态追加的按钮(.fingerButton 与 .stopButton),嵌套在多层div中。点击这些按钮时,虽能触发CSS的:active样式(背景色变化),但无法执行绑定的click事件中的console.log代码;初始的.startButton点击后可正常执行追加按钮的逻辑。我已尝试修改父元素与按钮的visibility、pointer-events属性,移除.startScreen元素,以及尝试event.stopPropagation()等方法,均未解决问题。
原JS代码
//What will happen when the start button is pressed. Basically, reset everything //and take to first stage of game. Must clear the Start Button and title if pressed. function startButtonPressed(indexStartButton) { hideStartScreenEle(indexStartButton); startGame(); } //Hides display of startScreen ele function hideStartScreenEle(indexStartButton) { $(" .startScreen").eq(0).css("display", "none"); $(" .startButton").eq(indexStartButton).css("display", "none"); } //Sets up game, assumes everything else is already hidden //Creates div with 2 fingers function startGame() { //Appends the flex containers $(" .appendToMe").append("<div class='handHolder'><div class='fingerHolder'></div></div>"); //Appends the thumb $(" .fingerHolder").append("<button class= 'fingerButton thumb'></button>"); //Appends the other fingers for (let i = 0; i < 1; i++) { $(" .fingerHolder").append("<button class='fingerButton'></button>"); } //Appends the stop button $(" .appendToMe").append("<button class='stopButton'>Stop?</button>"); } //Original button that runs the function that appends the rest of the buttons. Works //After being pressed, it and the div it is contained in have their display changed to none $(" .startButton").on("click", function() { startButtonPressed($(this).index(" .startButton")); }); //One stop button. Does not work, but becomes active. $(" .stopButton").on("click", function() { console.log("stop button pressed"); }); //There are five fingers, each is a button. Does not work when clicked, but becomes active. $(" .fingerButton").on("click", function() { console.log("finger clicked"); });
原CSS代码
body { overflow: hidden; margin: 0; padding: 0; background: chartreuse; } .startScreen { text-align: center; width: 100vw; background: blue; } .startButtonDiv { background: yellow; } .startButton { width: 20vw; height: 20vh; background: red; } .appendToMe { width: 100vw; text-align: center; background: cyan; pointer-events: none; } .handHolder { background: steelblue; display: flex; flex-direction: column; flex-wrap: wrap; justify-content: center; width: 760px; margin-left: auto; margin-right: auto; display: block; pointer-events: none; } .thumb { width: 200px; background: goldenrod; } .fingerButton { pointer-events: all; width: 140px; height: 340px; background: burlywood; border-width: 0px; } .fingerButton:active { background: orange; } .stopButton { background: firebrick; font-size: 80px; width: 10vw; height: 10vh; } .stopButton:active { background: blue; } .mission{ margin-left: auto; margin-right: auto; display: block; background: chocolate; width: 70vw; }
原HTML代码
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <div class="appendToMe"></div> <div class="startScreen"> <div class="gameTitle"> <h1>Free Your Fingers</h1> </div> <div class="startButtonDiv"> <button class="startButton">Start</button> </div> </div>
解决方案
问题根源有两个:
- 动态元素事件绑定方式错误:直接用
$(".stopButton").on("click", ...)只能绑定页面加载时已存在的元素,动态生成的元素不会继承该事件,必须用事件委托绑定到页面初始化时就存在的父元素(比如document或.appendToMe)。 - 父元素
pointer-events阻断事件:.appendToMe设置了pointer-events: none,而.stopButton直接嵌套在该容器中,未设置pointer-events: all,导致点击事件无法向上传递触发绑定的逻辑。
修改步骤
- 将动态按钮的事件绑定改为事件委托模式
- 给
.stopButton添加pointer-events: all属性,确保它能接收点击事件
修改后的代码
JS代码
// 点击开始按钮后的逻辑:重置并进入游戏第一阶段,隐藏开始按钮和标题 function startButtonPressed(indexStartButton) { hideStartScreenEle(indexStartButton); startGame(); } // 隐藏开始屏幕元素 function hideStartScreenEle(indexStartButton) { $(".startScreen").eq(0).css("display", "none"); $(".startButton").eq(indexStartButton).css("display", "none"); } // 初始化游戏,创建手指按钮和停止按钮 function startGame() { // 添加容器 $(".appendToMe").append("<div class='handHolder'><div class='fingerHolder'></div></div>"); // 添加拇指按钮 $(".fingerHolder").append("<button class='fingerButton thumb'></button>"); // 添加其他手指按钮(循环1次,共2个手指按钮) for (let i = 0; i < 1; i++) { $(".fingerHolder").append("<button class='fingerButton'></button>"); } // 添加停止按钮 $(".appendToMe").append("<button class='stopButton'>Stop?</button>"); } // 初始开始按钮的点击事件(正常工作) $(".startButton").on("click", function() { startButtonPressed($(this).index(".startButton")); }); // 事件委托绑定停止按钮的点击事件 $(document).on("click", ".stopButton", function() { console.log("stop button pressed"); }); // 事件委托绑定手指按钮的点击事件 $(document).on("click", ".fingerButton", function() { console.log("finger clicked"); });
CSS代码(仅修改.stopButton部分)
/* 其他原有CSS代码保持不变 */ .stopButton { background: firebrick; font-size: 80px; width: 10vw; height: 10vh; pointer-events: all; /* 添加此行,允许按钮接收点击事件 */ } .stopButton:active { background: blue; } /* 其他原有CSS代码保持不变 */
HTML代码(无需修改)
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <div class="appendToMe"></div> <div class="startScreen"> <div class="gameTitle"> <h1>Free Your Fingers</h1> </div> <div class="startButtonDiv"> <button class="startButton">Start</button> </div> </div>
内容的提问来源于stack exchange,提问作者BarelyAwake
相关产品推荐
相关产品推荐

