折腾:
【记录】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后,也都无法消失的问题了。
但是:
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窗口消失