React事件处理器问题:如何仅获取绑定元素而非子元素的ID?
解决React组件中事件目标不准确的问题
这个问题其实是事件冒泡导致的——当你点击<td>里的<p>元素时,事件会沿着DOM树向上冒泡,最终触发<td>上绑定的handleSelect函数,但此时e.target指向的是实际被点击的<p>,而不是绑定事件的<td>,自然拿不到正确的ID。
下面给你几个简单有效的解决方案:
方法一:使用e.currentTarget代替e.target
currentTarget是绑定事件处理函数的元素,不管事件是从哪个子元素冒泡上来的,它始终指向你绑定onClick的<td>。这是最直接的解决办法:
修改你的handleSelect函数:
handleSelect(e){ // 用currentTarget代替target,确保获取的是绑定事件的td元素 let week = e.currentTarget.parentNode.id; let day = e.currentTarget.id; this.props.onSelect(week, day); }
这样不管你点击<td>里的<p>还是其他子元素,currentTarget都会稳定指向<td>,父节点就是<tr>,ID获取就准确了。
方法二:阻止子元素的事件冒泡
如果不想用currentTarget,也可以在子元素上阻止事件继续冒泡,比如给<p>添加onClick事件:
dayArr.map(item => <p onClick={(e) => e.stopPropagation()}>{item.rName}</p>)
不过这种方法比较繁琐,如果<td>里有多个子元素,你需要给每个子元素都添加阻止冒泡的逻辑,不如第一种方法高效。
方法三:将点击事件绑定到更高层级(可选)
你也可以把onClick绑定到<tr>甚至<table>上,通过事件委托来判断点击的元素是否是<td>,不过对于你的场景来说,第一种方法已经足够简单直接了。
修改后的完整组件代码示例:
class Schedule extends React.Component { constructor(props){ super(props); this.handleSelect = this.handleSelect.bind(this); } handleSelect(e){ let week = e.currentTarget.parentNode.id; let day = e.currentTarget.id; this.props.onSelect(week, day); } render(){ let schedObj = this.props.meal; let sched = schedObj.map(weekArr => weekArr.map((dayArr, ind1) => <td id={ind1} className={"div"+ind1} onClick={this.handleSelect}> {dayArr.map(item => <p>{item.rName}</p>)} </td> ) ); return( <div> <table> <tbody> <tr id="0"> {sched[0]} </tr> <tr id="1"> {sched[1]} </tr> </tbody> </table> </div> ); } }
内容的提问来源于stack exchange,提问作者albert
相关产品推荐
相关产品推荐

