Javascript 如何打开和关闭btn点击下拉列表,但同时与外部点击关闭?
我有一个下拉列表,在点击btn时打开Javascript 如何打开和关闭btn点击下拉列表,但同时与外部点击关闭?,javascript,html,reactjs,Javascript,Html,Reactjs,我有一个下拉列表,在点击btn时打开 toggleAllCategories() { this.setState({ isOpenAllCategories: !this.state.isOpenAllCategories }); } 此外,在“外部单击”下拉列表关闭 handleClickOutside(event) { if (this.wrapperRef && !this.wrapperRef.contains(event.target))
toggleAllCategories() {
this.setState({ isOpenAllCategories: !this.state.isOpenAllCategories });
}
此外,在“外部单击”下拉列表关闭
handleClickOutside(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
this.toggleAllCategories();
}
}
但问题是我不能通过点击按钮来打开和关闭下拉列表
当我点击两次按钮时,下拉列表仍然打开,cus的外部点击实现
如何使ToggleDroondown在按钮上和关闭外部点击在同一时间
STACKBLITZ现场示例:
这是下拉列表和整个相关逻辑的组件和整个实现:
class AllCategories extends Component {
constructor(props) {
super(props);
this.state = {
allCategories: getAllCategoriesList(),
isOpenAllCategories: false
};
}
componentDidMount() {
document.addEventListener('mousedown', this.handleClickOutside.bind(this));
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClickOutside.bind(this));
}
setWrapperRef(node) {
this.wrapperRef = node;
}
handleClickOutside(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
this.toggleAllCategories();
}
}
toggleAllCategories() {
this.setState({ isOpenAllCategories: !this.state.isOpenAllCategories });
}
render() {
return (
<Fragment>
<AllCategoriesButton toggleAllCategories={this.toggleAllCategories} />
{this.state.isOpenAllCategories ? (
<div className="all-categories-wrapper" ref={(node) => this.setWrapperRef(node)}>
<div className="all-categories">
<ul className="all-categories-list">
<li className="all-categories-list-item">All Categories</li>
{this.state.allCategories.map((category) => (
<li
className={`all-categories-list-item ${
category.selected ? 'all-categories-list-item-active' : ''
}`}
>
{category.name}
</li>
))}
</ul>
</div>
</div>
) : (
''
)}
</Fragment>
);
}
}
class AllCategories扩展组件{
建造师(道具){
超级(道具);
此.state={
allCategories:getAllCategoriesList(),
isOpenAllCategories:错误
};
}
componentDidMount(){
document.addEventListener('mousedown',this.handleClickOutside.bind(this));
}
组件将卸载(){
document.removeEventListener('mousedown',this.handleClickOutside.bind(this));
}
setWrapperRef(节点){
this.wrapperRef=节点;
}
handleClickOutside(事件){
if(this.wrapperRef&&!this.wrapperRef.contains(event.target)){
this.toggleAllCategories();
}
}
toggleAllCategories(){
this.setState({isOpenAllCategories:!this.state.isOpenAllCategories});
}
render(){
返回(
{this.state.isOpenAllCategories(
this.setWrapperRef(节点)}>
- 所有类别
{this.state.allCategories.map((category)=>(
-
{category.name}
))}
) : (
''
)}
);
}
}
您可以使用事件.target.tagName
检查触发单击的元素
因此,为了防止两次切换,您可以执行以下操作:
handleClickOutside(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target) &&event.target.tagName.toLowerCase() !== 'button') {
this.toggleAllCategories();
}
}
编辑: 另一种方法
- 为按钮创建一个ref,并将其命名为
buttonRef
handleClickOutside
更新为:
handleClickOutside(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target) &&event.target !== buttonRef.current) {
this.toggleAllCategories();
}
}
这将是更合适的方式
希望这有帮助 在按钮单击的情况下,会触发两次
toggleAllCategories
。一个来自按钮点击,另一个来自handleClickOutside
。您需要从一个位置调用它是的,因为我需要能够在外部点击和按钮点击时关闭下拉列表。这意味着如果点击按钮区域,不会触发外部关闭?我可以检查点击标记的事件类别吗,而不是通过按钮类而不是按钮标签来处理它?对,如果你再次点击同一个按钮,你不想触发外部点击。我正在用另一种方法更新我的answeer。希望有帮助!