我想在Reactjs中添加addEventListener(),如果我在此模型之外单击,该模型将关闭

问题描述 投票:0回答:1
class Model extends Component {
    render() {
        return (
            <ProductConsumer>
                {(value) => {
                const {modelOpen, closeModel} = value;
                const{img, title, price} = value.modelProduct;

                if (!modelOpen) {
                    return null;
                }
                else  {
                    return (
                    <ModalContainer>
                        <div className="container">
                            <div className="row">
                                <div id="model" className=" cl-8 mx-auto xolo-md-6 collg-4 text-center text-capitalize p-5">
                                    <h5> Item added to cart </h5>
                                    <img src={img} className="img-fluid" alt="product" />
                                    <h5> {title} </h5>
                                    <h5 className="text-muted"> price : $ {price} </h5>
                                    <Link to="/">
                                        <ButtonContainer onClick = {() => closeModel()}>
                                            continue shopping 
                                        </ButtonContainer>
                                    </Link>

                                    <Link to="/cart">
                                        <ButtonContainer cart onClick={() => closeModel()}>
                                            go to cart 
                                        </ButtonContainer>
                                    </Link>
                                </div>
                            </div>
                        </div>

                    </ModalContainer>
                    );
                }}
             }
            </ProductConsumer>
        );
    }
}

export default Model;
html reactjs events javascript-events
1个回答
0
投票

您可以使用以下组件检查点击是在外部还是内部。

import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class OutsideClick extends Component {
  constructor (props) {
    super(props)
    this.getContainer = this.getContainer.bind(this)
    this.isTouch = false
    this.handle = this.handle.bind(this)
    this.checkIfClickWithinListenBoundary = this.checkIfClickWithinListenBoundary.bind(this);
    this.checkifClickWithinIgnoreBoundary = this.checkifClickWithinIgnoreBoundary.bind(this);
  }

  componentDidMount () {
    document.addEventListener('touchend', this.handle, true)
    document.addEventListener('click', this.handle, true)
  }

  componentWillUnmount () {
    document.removeEventListener('touchend', this.handle, true)
    document.removeEventListener('click', this.handle, true)
  }

  getContainer (ref) {
    this.container = ref
  }

  checkIfClickWithinListenBoundary(node) {
    if (!this.props.listenClickWithinClass) {
      return true;
    }

    const el = document.querySelector(`.${this.props.listenClickWithinClass}`)
    if (!el) {
      return el.contains(node)
    }
    return false
  }

  checkifClickWithinIgnoreBoundary(node) {
    if (!this.props.ignoreClickWithinClass) {
      return true;
    }
    const el = document.querySelector(`.${this.props.ignoreClickWithinClass}`)
    if (el) {
      return !el.contains(node)
    }
    return false
  }

  handle (e) {
    if (e.type === 'touchend') {
      this.isTouch = true
    }
    if (e.type === 'click' && this.isTouch) {
      return
    }
    const { onClickOutside } = this.props
    const el = this.container
    if (!el.contains(e.target) && this.checkIfClickWithinListenBoundary(e.target) && this.checkifClickWithinIgnoreBoundary(e.target)) {
      onClickOutside(e)
    }
  }

  render () {
    const {
      children, onClickOutside, listenClickWithinClass, ignoreClickWithinClass, ...props
    } = this.props
    return <div {...props} ref={this.getContainer}>{children}</div>
  }
}

OutsideClick.propTypes = {
  onClickOutside: PropTypes.func.isRequired,
  listenClickWithinClass: PropTypes.string,
  ignoreClickWithinClass: PropTypes.string,
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node
  ])
}

OutsideClick.defaultProps = {
  children: null,
  listenClickWithinClass: null,
  ignoreClickWithinClass: null
}

您可以使用这种方式。

return (
   <OutsideClick onClickOutside={() => this.closeModel()} >
      <ModalContainer>
         .......
      </ModalContainer>
   </OutsideClick>
)
© www.soinside.com 2019 - 2024. All rights reserved.