Javascript 检测单击是否在react组件内部或不在typescript中
我大致有以下几点:Javascript 检测单击是否在react组件内部或不在typescript中,javascript,typescript,Javascript,Typescript,我大致有以下几点: componentDidMount() { document.querySelector('body'
componentDidMount() {
document.querySelector('body')!.addEventListener('click', this.click);
}
click = (e: Event) => {
if (this.state.toggled) {
if (!ReactDom.findDOMNode(this.someRef).contains(e.target)) {
this.setState({ toggled: false });
}
}
};
render() {
return (<CustomElement
ref={(e) => { this.someRef = e; }}
/>)
}
查看node\u modules/typescript/lib/lib.d.ts
这很有意义,因为e.target
是一个EventTarget
,它似乎只定义了添加和删除事件处理程序的函数。然而,e.target表示“对发送事件的对象的引用”,这听起来更接近我想要的
那么,我如何保留当前工作的功能,同时也使tsc满意(而不仅仅是消除错误)?如何定义您的单击处理程序,如下所示:
private click = (e: Event) =>
{
if (e.target instanceof HTMLElement && !ReactDOM.findDOMNode(this.someRef).contains(e.target))
{
if (this.state.toggled)
{
this.setState({ toggled: false });
}
}
}
示例。我在中发现了类似的讨论,在本例中,类型断言是: 基本上EventTarget是最通用的类型,其中元素是一个子类型,HtmleElement是该类型的一个子类型。如果您从DOM中得到一个东西,我们通常不知道它是什么,您应该添加一个类型断言来“添加”关于特定DOM布局结构的特定外部知识 例如,事件的.target可能不是元素(例如,可以将事件侦听器添加到XMLHttpRequest,而XMLHttpRequest没有getBoundingClientRect方法) 因此,因为目标可能是也可能不是我想要的
节点
,TS无法推断真相,我需要断言
包含(例如,目标作为节点)
似乎是正确的解决方案。这对我来说是可行的,重点是你还应该为你的ref提供一个类型:
const wrapperRef=useRef(null);
const handleClickOutside=(事件:React.MouseEvent)=>{
如果(
wrapperRef?current?contains(event.target作为节点)&&
isFocusLockDisabled
) {
返回foo(false);
}
};
我对这里的好处有点不清楚,在我看来,这样做可以消除错误,因此TSC现在会假设内码从不运行,因为它会认为检查的次数总是失败。试试它。我已经测试了建议的代码,它实际上总是成功的,因为HtmleElement是其他元素的基础。它不会真正消除错误(不像对任何错误进行强制转换),相反,它会进行有效的检查,如果它是真的,则会继续。我附上了一个示例供您检查。
private click = (e: Event) =>
{
if (e.target instanceof HTMLElement && !ReactDOM.findDOMNode(this.someRef).contains(e.target))
{
if (this.state.toggled)
{
this.setState({ toggled: false });
}
}
}