React类组件中Antd Modal滚动至底部启用同意按钮方案问询
解决Ant Design Modal滚动到底部才启用同意按钮的问题
核心思路
Ant Design的Modal组件本身不支持直接传入ref,但你设置的bodyStyle={{ height: '400px', overflowY: 'auto'}}是作用于Modal内部的内容容器,实际滚动的是这个容器。所以我们可以给包裹条款文本的div添加ref,通过监听这个容器的滚动事件,判断是否滚动到底部,从而控制按钮的禁用状态。
修改后的完整代码
import React, { Component } from 'react'; import { Modal, Button } from 'antd'; class TermsModal extends Component { constructor(props) { super(props); this.state = { visible: false, agreeTerm: true // 初始禁用按钮 }; // 创建内容容器的ref this.contentRef = React.createRef(); } handleScroll = () => { const container = this.contentRef.current; if (!container) return; // 判断是否滚动到底部:留10px误差兼容不同浏览器滚动精度 const isBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 10; this.setState({ agreeTerm: !isBottom // 滚动到底部则启用按钮(agreeTerm设为false) }); }; componentDidUpdate(prevProps, prevState) { // Modal从关闭变打开时,添加滚动监听 if (!prevState.visible && this.state.visible) { this.contentRef.current?.addEventListener('scroll', this.handleScroll); } // Modal从打开变关闭时,移除监听并重置状态 if (prevState.visible && !this.state.visible) { this.contentRef.current?.removeEventListener('scroll', this.handleScroll); this.setState({ agreeTerm: true }); } } componentWillUnmount() { // 组件卸载时清理监听,避免内存泄漏 this.contentRef.current?.removeEventListener('scroll', this.handleScroll); } // 示例:打开Modal的触发方法 openModal = () => { this.setState({ visible: true }); }; render() { return ( <> <Button onClick={this.openModal}>查看条款</Button> <Modal title={<h1><b>Terms and Conditions</b></h1>} open={this.state.visible} width={800} bodyStyle={{ height: '400px', overflowY: 'auto'}} closable={false} footer={ <Button type="primary" disabled={this.state.agreeTerm} onClick={() => this.setState({ visible: false })} > Accept </Button> } onCancel={() => this.setState({ visible: false })} > {/* 给包裹条款的div绑定ref */} <div ref={this.contentRef}> {/* 此处替换为你的实际条款内容 */} <p>条款内容段落1...</p> <p>条款内容段落2...</p> {/* 省略大量条款内容 */} <p>条款内容最后一行...</p> </div> </Modal> </> ); } } export default TermsModal;
关键说明
- ref绑定目标:将ref绑定到Modal内部的内容div,而非Modal组件本身,因为这个div才是实际产生滚动的容器。
- 监听时机控制:仅在Modal打开时添加滚动监听,关闭时立即移除,避免无效监听占用资源。
- 滚动判断逻辑:通过
scrollTop + 容器可视高度 >= 内容总高度 - 10判断是否触底,减去10px是为了兼容不同浏览器的滚动精度差异,提升用户体验。 - 状态重置:Modal关闭时重置按钮禁用状态,确保下次打开Modal时按钮保持初始禁用状态。
内容的提问来源于stack exchange,提问作者The_elevator
相关产品推荐
相关产品推荐

