添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
慷慨大方的薯片  ·  react ...·  1 周前    · 
寂寞的眼镜  ·  Android Studio生成 Flutt ...·  1 年前    · 
大力的荒野  ·  sonarqube - Jenkins ...·  1 年前    · 
爱搭讪的烤土司  ·  c语言curl库-掘金·  1 年前    · 

我们经常封装一些自己的下拉列表组件 或者 弹窗组件。一般 点击按钮显示 列表或 弹窗。再次点击 隐藏或关闭,但 ui库里的下拉列表,点击除了自己本身也能实现隐藏对应的列表。下面我就给大家一个实现思路。

弹窗组件可以用 React Portals 实现: react 官网 createPortal

实现步骤:

这是一个 简单的点击按钮,显示列表。再次点击隐藏。但我的需求是,点击其他地方也隐藏。

import React, { ReactNode, useEffect, useState, useRef } from "react";
const MyList = () => {
  const [visable, setVisabled] = useState(false);
  return (
      <button onClick={() => setVisabled(!visable)}>点击显示 列表</button>
      <div style={{ display: visable ? "block" : "none" }}>
        <div>11111</div>
        <div>22222</div>
      </div>
    </div>
export default MyList;

可以利用contains 结合 ref(建议用ref,当然也可以用 document方法,给元素加个 id) 。
contains 是 DOM 元素的方法,用于确定一个元素是否包含另一个元素。不包含则执行 关闭/隐藏事件。
还需要 注意的是,需要 给 隐藏、显示的点击事件加个 阻止事件冒泡的方法event.stopPropagation();
阻止事件冒泡方法必须加上!!!

代码如下:

import React, { ReactNode, useEffect, useState, useRef } from "react";
const MyList = () => {
  const [visable, setVisabled] = useState(false);
  // 下拉列表 ref
  const dropdownRef = useRef(null);
  useEffect(() => {
    //实现点击 本元素外的元素时,隐藏下拉列表(点击其他地方隐藏下拉列表)
    function handleOutsideClick(event) {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        setVisabled(false);
    document.addEventListener("click", handleOutsideClick);
    return () => {
      document.removeEventListener("click", handleOutsideClick);
  }, []);
  const hanldClick = (event) => {
    event.stopPropagation(); // 阻止事件冒泡
    setVisabled(!visable);
  return (
      <button onClick={hanldClick}>点击显示 列表</button>
      <div ref={dropdownRef} style={{ display: visable ? "block" : "none" }}>
        <div>11111</div>
        <div>22222</div>
      </div>
    </div>
export default MyList;

核心代码就是这块:
需要注意的是 绑定的事件需要 在 组件卸载时移除。

useEffect(() => {
    //实现点击 本元素外的元素时,隐藏下拉列表(点击其他地方隐藏下拉列表)
    function handleOutsideClick(event) {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        setVisabled(false);
    document.addEventListener("click", handleOutsideClick);
    return () => {
      document.removeEventListener("click", handleOutsideClick);
  }, []);

类组件就是这样:
只是把useEffetc里的内容 转换成Class语法。componentDidMount 绑定事件,componentWillUnmount移除事件。

import React, { Component } from "react";
class MyList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      visible: false
    this.dropdownRef = React.createRef(); // 下拉列表 ref
  componentDidMount() {
    // 实现点击本元素外的元素时,隐藏下拉列表(点击其他地方隐藏下拉列表)
    document.addEventListener("click", this.handleOutsideClick);
  componentWillUnmount() {
    document.removeEventListener("click", this.handleOutsideClick);
  handleOutsideClick = (event) => {
    if (
      this.dropdownRef.current &&
      !this.dropdownRef.current.contains(event.target)
      this.setState({ visible: false });
  handleClick = (event) => {
    event.stopPropagation(); // 阻止事件冒泡
    this.setState((prevState) => ({
      visible: !prevState.visible
    }));
  render() {
    const { visible } = this.state;
    return (
        <button onClick={this.handleClick}>点击显示列表</button>
          ref={this.dropdownRef}
          style={{ display: visible ? "block" : "none" }}
          <div>11111</div>
          <div>22222</div>
        </div>
      </div>
export default MyList;

理论上来说 这个思路在 vue里也适用,只需要转化vue语法。不过vue 有指令库 v-clickoutside。

题外话:现在ai真的很强大,我类组件的写法就是让ai转换的,竟然完全正确,运行无误!!! 如果简单的组件 可以试试 ai 。比如 chatGPT\文心一言\通义千问。

比如:文心给的 就可以用,编程方面 chatGPT会比文心强,目前 我认为 gpt是独一档的强!
文心一言 提问分享

3、通过父元素点击事件判断是否点击的在子id区域,不是则隐藏 (4、由于我是结合选项Cascader级联选择判断Checkbox多选框是否显隐,隐藏为了避免点完选项直接消失可以再加一个判断,默认为false,选完之后为ture,然后如果点击区域则把判断显隐的标识为ture的同时在让这个额的判断为false) 以下只列出了关键代码,其余部分功能代码省略,只是实现思路,不可直接使用!!! //sta.
遇到问题先百度,但是最近发现百度的内容好多都老旧了,跟不上时代,本文基于https://www.cnblogs.com/ives/p/11291769.html的内容上进行完善和补充 为什么说它旧了呢,因为在新版的react中这个已经 ref="refTest"已经废弃可以参考之前的这篇文章 react 中如何清空input的值 import React, {Component} from 'react'; import {findDOMNode} from 'react-dom' export de
React事件系统有两类:合成事件和原生事件。在写React组件是我们很容易绑定一个合成事件,但是在一个组件里面是没有办法去绑定另一个组件的合成事件的,此时原生事件就派上了用场。除了讲述混合(合成事件与原生事件混用)事件,事件冒泡也是我们经常需要处理的事情,这篇文章结合React进行介绍。 1.React事件系统 1-... 步骤三: 给元素内子元素点时不需要隐藏它的方法加上阻止事件冒泡事件, 这样就不会冒泡到顶层的document e.nativeEvent.stopImmediatePropagation(); 转载于:https://www.cn...
ReactNative实现左滑删除列表 需求中要开发一个可以侧滑删除的列表,发现ReactNative并不未供这种组件。ReactNative本身其实封装了具有侧滑功能的FlatList在以下目录,但已经被弃用了,研究了一下没有搞懂 ./node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableFlatList 之后尝试寻找一些第三方库,一个比较好用的是react-native-swipe-list-view,可以
当我们点击更多时候,页面出现一个弹层,点击叉叉,再次点击更多或者点击其中某个城市,这个弹层都会消失,但是现在我们希望点击页面其他任意区域弹层也会消失,为此,我们使用react实现它。 首先我们在react的生命周期函数中增加监听器,给整个页面最顶级(window)增加一个点击事件处理函数 componentDidMount() { window.addEventListener('mouseup', this.handleMouseUp, false) componentWill
* Component that alerts if you click outside of it class OutsideAlerter extends Component { constructor(props) { super(props); this.setWrapperRef = this.setWrapperRef.bi... vue 报警告:Failed to resolve component:ConsTtem IFthis is a native custom element,make sure to exclude 95295 react报错 Uncaught Error: Objects are not valid as a React child (found: object with keys {a} ... 51162 antd Dropdown组件使用时报错:React.Children.only expected to receive a single React element child Fullcalendar @fullcalendar/react 样式错乱丢失问题和导致页面卡顿崩溃问题