最新消息:20190529 VPS服务器已从腾讯云香港换为Vultr新加坡,主题仍用朋友推荐的大前端D8

【已解决】ReactJS中阻止点击事件不让Modal窗口消失

ReactJS crifan 848浏览 0评论

折腾:

【记录】ReactJS中参考spring-picker自己去实现弹框选择

期间,对于代码:

  render () {
    let modal = null;
    // if (this.state.isVisible) {
    if (this.props.visible) {
      modal = (
        <div class={style.modal_overlay} onClick={this.props.onCancel}>
          <div class={style.modal}>
            {this.props.children}
          </div>
        </div>
      );
    }
    return (
      <ReactCSSTransitionGroup
        transitionName="modal-transition"
        transitionEnterTimeout={120}
        transitionLeaveTimeout={120}>
        { modal }
      </ReactCSSTransitionGroup>
    );
  }

但是,无法阻止下面的modal窗口,被点击时,还是消失掉的问题:

改为:

  omitModalClick(e){
    console.log(`omitModalClick: e=${e}`);
  }
  render () {
    let modal = null;
    // if (this.state.isVisible) {
    if (this.props.visible) {
      modal = (
        <div class={style.modal_overlay} onClick={this.props.onCancel}>
          <div class={style.modal} onClick={this.omitModalClick}>

 

问题依旧。

然后改为:

  componentDidUpdate() {
    console.log(`BaseModal componentDidUpdate: this.modalOverlay=${this.modalOverlay}`);
    if (this.modalOverlay && !this.modalOverlay.onclick) {
      // 点击阴影背景时cancel() popup
      this.modalOverlay.onclick = (e) => {
        e.stopPropagation();
        this.props.onCancel && this.props.onCancel();
      };
      // 点击modal阻止默认行为
      // 原理:react event listener中无法阻止原生事件,所以用原生事件来替代react事件
      this.modal.onclick = (e) => e.stopPropagation();
      console.log(`modal onclick stopPropagation`);
    }
  }
        // <div class={style.modal_overlay} ref={(mol) => {this.modalOverlay = mol;}}>
        //   <div class={style.modal} ref={(m) => {this.modal = m;}}>
        // <div class={style.modal_overlay} onClick={this.props.onCancel}>
        //   <div class={style.modal} onClick={this.props.onCancel}>
          // <div class={style.modal} onClick={this.omitModalClick}>
  // omitModalClick(e){
  //   console.log(`omitModalClick: e=${e}`);
  // }
  render () {
    let modal = null;
    // if (this.state.isVisible) {
    if (this.props.visible) {
      modal = (
        <div class={style.modal_overlay} ref={(mol) => {this.modalOverlay = mol;}}>
          <div class={style.modal} ref={(m) => {this.modal = m;}}>
            {this.props.children}
          </div>
        </div>
      );
    }
    return (
      <ReactCSSTransitionGroup
        transitionName="modal-transition"
        transitionEnterTimeout={120}
        transitionLeaveTimeout={120}>
        { modal }
      </ReactCSSTransitionGroup>
    );
  }

结果就会出现:

第一次是正常的

第二次,点击Modal overlay后,也都无法消失的问题了。

Handling Events – React

但是:

  modalOverlayOnClick(e){
    e.preventDefault();
    console.log(`BaseModal modalOverlayOnClick:`);
    console.log(e);
    // console.log(this.props.onCancel);
    if (this.props.onCancel) {
      this.props.onCancel();
    }
  }
  modalOnClick(e){
    e.preventDefault();
    console.log(`BaseModal modalOnClick:`);
    console.log(e);
  }
  render () {
    let modal = null;
    // if (this.state.isVisible) {
    if (this.props.visible) {
      modal = (
        <div class={style.modal_overlay} onClick={this.modalOverlayOnClick}>
          <div class={style.modal} onClick={this.modalOnClick}>
            {this.props.children}
          </div>
        </div>
      );
    }

但是

e.preventDefault()

并没有阻止事件继续传递到父级的modal overlay

reactjs e.preventDefault not work

reactjs – React onClick and preventDefault() link refresh/redirect? – Stack Overflow

【总结】

然后用:

    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();

替代:

   e.preventDefault();

变为:

  modalOverlayOnClick(e){
    // e.preventDefault();
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
    console.log(`BaseModal modalOverlayOnClick:`);
    console.log(e);
    // console.log(this.props.onCancel);
    if (this.props.onCancel) {
      this.props.onCancel();
    }
  }
  modalOnClick(e){
    // e.preventDefault();
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
    console.log(`BaseModal modalOnClick:`);
    console.log(e);
  }
  render () {
    let modal = null;
    // if (this.state.isVisible) {
    if (this.props.visible) {
      modal = (
        <div class={style.modal_overlay} onClick={this.modalOverlayOnClick}>
          <div class={style.modal} onClick={this.modalOnClick}>
            {this.props.children}
          </div>
        </div>
      );
    }
    return (
      <ReactCSSTransitionGroup
        transitionName="modal-transition"
        transitionEnterTimeout={120}
        transitionLeaveTimeout={120}>
        { modal }
      </ReactCSSTransitionGroup>
    );
  }

即可达到对应的效果:

对于最底层的modal overlay层

和在其之上的 modal层

(1)点击modal overlay:

后,可以消失:

(2)点击overlay区:

overlay不消失:

(3)并且,当切换出去到其他页面后,再进入此页面后,对应当代码逻辑依然生效

-》之前的问题就是重新进入此页面,上述逻辑就失效了。

转载请注明:在路上 » 【已解决】ReactJS中阻止点击事件不让Modal窗口消失

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
68 queries in 0.091 seconds, using 18.85MB memory