防止事件在 dom 树中冒泡
Prevent event from bubbling up the dom tree
我有一个卡片组件如下
<div
onClick={e => {
console.log("DEMAND CARD CLICKED");
if (isSelectionActive) {
setSelected();
}
}}
>
<DemandCardFooter
demandId={id}
totalBooked={totalBooked}
totalDemand={totalDemand}
/>
</div>
这就是 <DemandCardFooter/>
的样子:
<div className="vt-card-footer d-flex justify-content-between align-items-baseline px-3">
<DemandSelector demandId={demandId} />
<p className="lead font-weight-bold mb-0">
<span className="text-success">{totalBooked}</span> / {totalDemand}{" "}
<small className="text-muted font-weight-normal">Units.</small>
</p>
</div>
最后是 <DemandSelector/>
的样子:
const DemandSelector = ({ demandId }) => {
const [isChecked, setChecked] = useRowSelector({
path: "demands",
payload: { id: demandId }
});
return (
<Checkbox
checked={isChecked ? true : false}
onClick={e => {
console.log("CHECKBOX CLICKED");
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
setChecked();
}}
/>
);
};
我的问题是,当我点击复选框时,复选框的 onClick
和卡片的 onClick
都会被触发,有什么办法可以将回调限制在最低级别吗?
这不是事件冒泡的问题,问题是事件捕获阶段。
该事件不会随着您在代码中使用的 e.stopPropagation();
冒泡。但是在父事件中并没有阻止事件捕获。
您可以通过在父事件中添加 e.stopPropagation();
来阻止它。
<div
onClick={e => {
e.stopPropagation();
console.log("DEMAND CARD CLICKED");
if (isSelectionActive) {
setSelected();
}
}}
>
<DemandCardFooter
demandId={id}
totalBooked={totalBooked}
totalDemand={totalDemand}
/>
</div>
一段时间后想通了。解决方案是将 stopPropogation()
放入包含 <DemandSelector/>
的 DOM 元素中
所以这段代码有效
<div
className="vt-card-footer d-flex justify-content-between align-items-baseline px-3"
onClick={e => {
e.stopPropagation();
}}
>
<DemandSelector demandId={demandId} />
<p className="lead font-weight-bold mb-0">
<span className="text-success">{totalBooked}</span> / {totalDemand}{" "}
<small className="text-muted font-weight-normal">Units.</small>
</p>
</div>
还有别忘了把它一直放下去
const DemandSelector = ({ demandId }) => {
const [isChecked, setChecked] = useRowSelector({
path: "demands",
payload: { id: demandId }
});
return (
<Checkbox
checked={isChecked ? true : false}
onClick={e => {
e.stopPropagation();
setChecked();
}}
/>
);
};
我有一个卡片组件如下
<div
onClick={e => {
console.log("DEMAND CARD CLICKED");
if (isSelectionActive) {
setSelected();
}
}}
>
<DemandCardFooter
demandId={id}
totalBooked={totalBooked}
totalDemand={totalDemand}
/>
</div>
这就是 <DemandCardFooter/>
的样子:
<div className="vt-card-footer d-flex justify-content-between align-items-baseline px-3">
<DemandSelector demandId={demandId} />
<p className="lead font-weight-bold mb-0">
<span className="text-success">{totalBooked}</span> / {totalDemand}{" "}
<small className="text-muted font-weight-normal">Units.</small>
</p>
</div>
最后是 <DemandSelector/>
的样子:
const DemandSelector = ({ demandId }) => {
const [isChecked, setChecked] = useRowSelector({
path: "demands",
payload: { id: demandId }
});
return (
<Checkbox
checked={isChecked ? true : false}
onClick={e => {
console.log("CHECKBOX CLICKED");
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
setChecked();
}}
/>
);
};
我的问题是,当我点击复选框时,复选框的 onClick
和卡片的 onClick
都会被触发,有什么办法可以将回调限制在最低级别吗?
这不是事件冒泡的问题,问题是事件捕获阶段。
该事件不会随着您在代码中使用的 e.stopPropagation();
冒泡。但是在父事件中并没有阻止事件捕获。
您可以通过在父事件中添加 e.stopPropagation();
来阻止它。
<div
onClick={e => {
e.stopPropagation();
console.log("DEMAND CARD CLICKED");
if (isSelectionActive) {
setSelected();
}
}}
>
<DemandCardFooter
demandId={id}
totalBooked={totalBooked}
totalDemand={totalDemand}
/>
</div>
一段时间后想通了。解决方案是将 stopPropogation()
放入包含 <DemandSelector/>
所以这段代码有效
<div
className="vt-card-footer d-flex justify-content-between align-items-baseline px-3"
onClick={e => {
e.stopPropagation();
}}
>
<DemandSelector demandId={demandId} />
<p className="lead font-weight-bold mb-0">
<span className="text-success">{totalBooked}</span> / {totalDemand}{" "}
<small className="text-muted font-weight-normal">Units.</small>
</p>
</div>
还有别忘了把它一直放下去
const DemandSelector = ({ demandId }) => {
const [isChecked, setChecked] = useRowSelector({
path: "demands",
payload: { id: demandId }
});
return (
<Checkbox
checked={isChecked ? true : false}
onClick={e => {
e.stopPropagation();
setChecked();
}}
/>
);
};