You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态追加的子按钮点击不执行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,导致点击事件无法向上传递触发绑定的逻辑。

修改步骤

  1. 将动态按钮的事件绑定改为事件委托模式
  2. 给.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 22:30:31