event.stopPropagation 无法停止向父级冒泡
event.stopPropagation fails to stop bubbling up to parent
我将 onContextMenu 事件附加到父组件和子组件。两者都是 React 合成事件,但 event.stopPropagation 未能阻止此事件。
两者都是反应事件
Edit: I had an epiphany,is it because im hydrating inside a content-editable div? and react doesnt know that both components are child and parent as react ignores content inside editable divs. is there a way to make react understand this?
父组件
const CMSCheckBox = (props, ref) => {
openMenu=()=>{
alert("Parent");
}
//hydrating components based on props
useEffect(() => {
if (props.objValue && props.objValue.SubElements) {
props.objValue.SubElements.map(SubElement => {
let strDivId = SubElement.DivId ? SubElement.DivId : "element_" + SubElement.iElementId;
if (!document.getElementById(strDivId)) {
let objSavedSel = ApplicationState.GetProperty("objActiveSelection");
if (objSavedSel && objSavedSel != null) {
let divElement;
divElement = document.createElement("span");
ApplicationState.SetProperty("objActiveDiv",
{
strDivId: strDivId
});
divElement.id = strDivId;
divElement.setAttribute('type', SubElement.iElementType.toLowerCase() + 'div');
let range = document.createRange();
range.setStart(document.getElementById(objSavedSel.divId),
0);
range.collapse(true);
var nodeStack = [document.getElementById(objSavedSel.divId)
], node, foundStart = false, stop = false, charIndex = 0;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && objSavedSel.intStart >= charIndex && objSavedSel.intStart <= nextCharIndex) {
range.setStart(node, objSavedSel.intStart - charIndex);
foundStart = true;
}
if (foundStart && objSavedSel.intEnd >= charIndex && objSavedSel.intEnd <= nextCharIndex) {
range.setEnd(node, objSavedSel.intEnd - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i
]);
}
}
}
range.deleteContents();
range.insertNode(divElement); //insert div to hydrate
}
}
let Element = UndoRedo(ElementController.getComponent(SubElement.iElementType.toLowerCase()));
ReactDom.hydrate(<Provider store={store
} ><Element ElementJson={SubElement
} PageId={props.PageId
} Mode={props.Mode
} /></Provider>, document.getElementById(strDivId));
// setTimeout(() => {
// onContentChange();
// }, 100);
})
}
return () => {
divRef.current.removeEventListener("blur", onContentChange_Callbck);
divRef.current.removeEventListener("mousedown", onMouseDown_Callbck);
}
},
[state, props
])
retrun (<div onContextMenu={} contenteditable="true"></div>)
}
子组件根据点击位置水合到父组件中的内容可编辑div
const Child =(props,ref) =>{
const openmenu=(e)=>{
e.stopPropagation(); //doesnt work
alert("child");
}
return (<div onContextMenu={openmenu}>Test</div>);
}
两个上下文菜单事件都被调用
e.nativeEvent.stopImmediatePropagation();
此参考指南记录了 SyntheticEvent
所以问题如我的编辑所述,因为我的 div 是内容可编辑的,react 不知道这两者都是父元素和子 dom 元素,因此在调用 stopPropagation 时什么都不做.
我发现的解决方案虽然是一个混乱的解决方案是将子组件添加为 ref 然后使用 addEventListener 附加反应事件处理程序javascript 的方法。由于该事件不再是合成的,也不再由 React 管理,因此该事件不再冒泡到父级。
我将 onContextMenu 事件附加到父组件和子组件。两者都是 React 合成事件,但 event.stopPropagation 未能阻止此事件。
两者都是反应事件
Edit: I had an epiphany,is it because im hydrating inside a content-editable div? and react doesnt know that both components are child and parent as react ignores content inside editable divs. is there a way to make react understand this?
父组件
const CMSCheckBox = (props, ref) => {
openMenu=()=>{
alert("Parent");
}
//hydrating components based on props
useEffect(() => {
if (props.objValue && props.objValue.SubElements) {
props.objValue.SubElements.map(SubElement => {
let strDivId = SubElement.DivId ? SubElement.DivId : "element_" + SubElement.iElementId;
if (!document.getElementById(strDivId)) {
let objSavedSel = ApplicationState.GetProperty("objActiveSelection");
if (objSavedSel && objSavedSel != null) {
let divElement;
divElement = document.createElement("span");
ApplicationState.SetProperty("objActiveDiv",
{
strDivId: strDivId
});
divElement.id = strDivId;
divElement.setAttribute('type', SubElement.iElementType.toLowerCase() + 'div');
let range = document.createRange();
range.setStart(document.getElementById(objSavedSel.divId),
0);
range.collapse(true);
var nodeStack = [document.getElementById(objSavedSel.divId)
], node, foundStart = false, stop = false, charIndex = 0;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && objSavedSel.intStart >= charIndex && objSavedSel.intStart <= nextCharIndex) {
range.setStart(node, objSavedSel.intStart - charIndex);
foundStart = true;
}
if (foundStart && objSavedSel.intEnd >= charIndex && objSavedSel.intEnd <= nextCharIndex) {
range.setEnd(node, objSavedSel.intEnd - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i
]);
}
}
}
range.deleteContents();
range.insertNode(divElement); //insert div to hydrate
}
}
let Element = UndoRedo(ElementController.getComponent(SubElement.iElementType.toLowerCase()));
ReactDom.hydrate(<Provider store={store
} ><Element ElementJson={SubElement
} PageId={props.PageId
} Mode={props.Mode
} /></Provider>, document.getElementById(strDivId));
// setTimeout(() => {
// onContentChange();
// }, 100);
})
}
return () => {
divRef.current.removeEventListener("blur", onContentChange_Callbck);
divRef.current.removeEventListener("mousedown", onMouseDown_Callbck);
}
},
[state, props
])
retrun (<div onContextMenu={} contenteditable="true"></div>)
}
子组件根据点击位置水合到父组件中的内容可编辑div
const Child =(props,ref) =>{
const openmenu=(e)=>{
e.stopPropagation(); //doesnt work
alert("child");
}
return (<div onContextMenu={openmenu}>Test</div>);
}
两个上下文菜单事件都被调用
e.nativeEvent.stopImmediatePropagation();
此参考指南记录了 SyntheticEvent
所以问题如我的编辑所述,因为我的 div 是内容可编辑的,react 不知道这两者都是父元素和子 dom 元素,因此在调用 stopPropagation 时什么都不做.
我发现的解决方案虽然是一个混乱的解决方案是将子组件添加为 ref 然后使用 addEventListener 附加反应事件处理程序javascript 的方法。由于该事件不再是合成的,也不再由 React 管理,因此该事件不再冒泡到父级。