我正在寻找一种方法来检测单击事件是否发生在组件之外,如本文所述。jQueryclosest()用于查看单击事件的目标是否将dom元素作为其父元素之一。如果存在匹配项,则单击事件属于其中一个子项,因此不被视为在组件之外。
因此,在我的组件中,我想将一个单击处理程序附加到窗口。当处理程序启动时,我需要将目标与组件的dom子级进行比较。
click事件包含类似“path”的财产,它似乎保存了事件经过的dom路径。我不知道该比较什么,或者如何最好地遍历它,我想肯定有人已经把它放在了一个聪明的效用函数中。。。不
我有一个需要有条件地将孩子插入模态的例子。像这样,贝娄。
const [view, setView] = useState(VIEWS.SomeView)
return (
<Modal onClose={onClose}>
{VIEWS.Result === view ? (
<Result onDeny={() => setView(VIEWS.Details)} />
) : VIEWS.Details === view ? (
<Details onDeny={() => setView(VIEWS.Result) /> />
) : null}
</Modal>
)
所以parent.contains(event.target)在这里不起作用,因为一旦分离了子级,parent(modal)就不再包含event.targe。
我的解决方案(到目前为止有效,没有任何问题)是这样写:
const listener = (event: MouseEvent) => {
if (parentNodeRef && !event.path.includes(parentNodeRef)) callback()
}
若父级包含已经分离的树中的元素,那个么它不会触发回调。
编辑:event.path是新的,尚未在所有浏览器中退出。请改用composedPath。
https://stackoverflow.com/a/42234988/9536897解决方案在手机上不起作用。
您可以尝试:
// returns true if the element or one of its parents has the class classname
hasSomeParentTheClass(element, classname) {
if(element.target)
element=element.target;
if (element.className&& element.className.split(" ").indexOf(classname) >= 0) return true;
return (
element.parentNode &&
this.hasSomeParentTheClass(element.parentNode, classname)
);
}
componentDidMount() {
const fthis = this;
$(window).click(function (element) {
if (!fthis.hasSomeParentTheClass(element, "myClass"))
fthis.setState({ pharmacyFocus: null });
});
}
在视图中,将className赋给特定元素。