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

点击事件监听器为何返回body元素而非点击的具体元素?

点击chessboard.js白棋子格子时event.target返回body的问题分析与解决

问题描述

在chessboard.js的可拖拽棋子示例页面中,我给document.body绑定了如下点击事件:

document.body.addEventListener(`click`, a1);
function a1(){
   console.dir(event.target);
}

出现了如下异常现象:

  • 点击空棋盘格或黑棋子所在格子时,控制台能正确输出对应的square div元素(如div#e5-b9f9-a5bc-69e1-3e5a-4b82-b2bc-ffe4-966c.square-55d63.black-3c85d.square-e5)
  • 点击白棋子所在格子时,控制台输出的却是<body>元素

通过开发者工具检查元素,白棋子所在的DOM结构为:

<div class="square-55d63 white-1e1d7 square-e2" style="width:49px;height:49px;" id="e2-f699-d489-4d29-2e6f-2a64-c1ec-e26f-fb62" data-square="e2">
    <img src="chessboard/img/chesspieces/wikipedia/wP.png" alt="" class="piece-417db" data-piece="wP" style="width:49px;height:49px;">
</div>

原因分析

这是因为该示例启用了可拖拽棋子功能,chessboard.js的拖拽逻辑会在mousedown触发后,将白棋子的<img>元素临时从所在的square div中移到<body>下进行绝对定位,在mouseup时再将其移回原位置。而click事件是在mouseup之后触发的,此时<img>元素已经被移回,但直接使用全局event对象会因为元素的临时移动被干扰,导致获取的目标元素异常。

另外,你没有在事件处理函数中接收event参数,直接依赖全局event对象,这会大幅增加被其他代码篡改的风险。

解决方案

修改代码,使用函数参数传入的事件对象,并通过closest()方法向上查找目标格子元素:

document.body.addEventListener('click', function(event) {
    // 从点击元素向上遍历,找到最近的棋盘格div
    const targetSquare = event.target.closest('.square-55d63');
    if (targetSquare) {
        console.dir(targetSquare);
    }
});

说明

  • event.target.closest('.square-55d63')会从当前点击的元素(无论是棋子<img>还是格子<div>)开始,向上遍历DOM树,找到第一个带有square-55d63类的元素,确保能正确获取到棋盘格容器
  • 使用函数参数中的event对象,避免全局event被其他代码干扰的问题

内容的提问来源于stack exchange,提问作者Jaroslav Tavgen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:32:31