模态弹出窗口无法正常工作(希望背景页面变暗)
Modal pop-up not working properly (want the background page to dim)
有一个按钮覆盖在页面上,按下按钮后,页面应该变暗并显示模式弹出窗口。
然而,对于我的代码,弹出窗口只是显示,但背景页面没有受到任何影响。然而,模式打开和关闭正确。
按钮代码:
class MessageBrokerButton extends Component {
constructor(props) {
super(props)
this.state = {
isShowing: false
}
}
openModalHandler = (e) => {
this.setState({
isShowing: true
});
e.preventDefault();
}
closeModalHandler = () => {
this.setState({
isShowing: false
});
}
render() {
return (
<div>
<button className='message-broker' onClick={this.openModalHandler}>
Message Broker
</button>
<div className='message-icon'></div>
{ this.state.isShowing ?
<Popup
show={this.state.isShowing}
close={this.closeModalHandler}>
Test
</Popup>
: null
}
</div>
)
}
}
模态代码:
const Popup = (props) => {
return (
<div>
<button onClick={props.close}>CLOSE</button>
<p> {props.children}</p>
</div>
)
}
按钮所在页面的相关代码:
class Page extends Component {
constructor(props) {
super(props);
this.state = {
};
};
render() {
let page100 =
<div>
<MessageBrokerButton></MessageBrokerButton>
</div>
if (this.props.currentPage !== this.state.page) {
page100 = null;
}
return (
<form onSubmit={this.handleFormSubmit}>
{page100}
</form>
);
}
}
我知道我绝对没有考虑正确的样式规则,也没有考虑单击 MessageBrokerButton 后如何更改页面 class。但是我不确定要更改哪些部分以及我应该更改什么。
有多种方法可以做到这一点。您可以做的是创建一个新的 Shadow-component,它是 Page 的子组件(或者您的实际根组件)。然后给这个 Shadow 一个 state 属性,告诉组件是否渲染阴影 -div 或不。
这一切都非常简单。最复杂的部分通常是想出一些合理的状态管理系统,这样你就可以在不传递 "enable shadow" 处理程序的情况下触发 Shadow。我建议检查一下 Redux。
使用 z-index 样式确保阴影出现在页面和模式之间。例如阴影 z-index 1,模态容器 2。此外,请确保阴影和模态容器都定位为绝对位置,因为它们都应覆盖页面。
这是一个伪简化:
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {
hasShadow: false,
modal: null, // Modal can be a React-component, like the Popup.
};
}
handleHasShadow = hasShadow => {
this.setState({ hasShadow });
}
handleSetModal = modal => {
this.setState({ modal });
}
render() {
return (
<div>
<form ...>
{
this.props.currentPage === this.state.page
? <MessageBrokerButton handleHasShadow={this.handleHasShadow} />
: null
}
</form>
<Shadow isEnabled={this.state.hasShadow} />
{/* You can give modal as a prop too! */}
<ModalContainer>{modal}</ModalContainer>
</div>
);
}
}
Shadow.jsx
const Shadow = ({ isEnabled }) => {
return isEnabled ? (
<div
style={{
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
background: '#000000',
opacity: 0.5,
zIndex: 1,
}}
/>
) : null;
}
现在您只需使用 this.props.handleHasShadow(true/false) 函数来 enable/disable 阴影。阴影将与父(页面)组件一样大。
您可能还想确保焦点停留在模态框内。否则用户将能够从模式中退出。这里的关键词是 focus-trap.
有一个按钮覆盖在页面上,按下按钮后,页面应该变暗并显示模式弹出窗口。
然而,对于我的代码,弹出窗口只是显示,但背景页面没有受到任何影响。然而,模式打开和关闭正确。
按钮代码:
class MessageBrokerButton extends Component {
constructor(props) {
super(props)
this.state = {
isShowing: false
}
}
openModalHandler = (e) => {
this.setState({
isShowing: true
});
e.preventDefault();
}
closeModalHandler = () => {
this.setState({
isShowing: false
});
}
render() {
return (
<div>
<button className='message-broker' onClick={this.openModalHandler}>
Message Broker
</button>
<div className='message-icon'></div>
{ this.state.isShowing ?
<Popup
show={this.state.isShowing}
close={this.closeModalHandler}>
Test
</Popup>
: null
}
</div>
)
}
}
模态代码:
const Popup = (props) => {
return (
<div>
<button onClick={props.close}>CLOSE</button>
<p> {props.children}</p>
</div>
)
}
按钮所在页面的相关代码:
class Page extends Component {
constructor(props) {
super(props);
this.state = {
};
};
render() {
let page100 =
<div>
<MessageBrokerButton></MessageBrokerButton>
</div>
if (this.props.currentPage !== this.state.page) {
page100 = null;
}
return (
<form onSubmit={this.handleFormSubmit}>
{page100}
</form>
);
}
}
我知道我绝对没有考虑正确的样式规则,也没有考虑单击 MessageBrokerButton 后如何更改页面 class。但是我不确定要更改哪些部分以及我应该更改什么。
有多种方法可以做到这一点。您可以做的是创建一个新的 Shadow-component,它是 Page 的子组件(或者您的实际根组件)。然后给这个 Shadow 一个 state 属性,告诉组件是否渲染阴影 -div 或不。
这一切都非常简单。最复杂的部分通常是想出一些合理的状态管理系统,这样你就可以在不传递 "enable shadow" 处理程序的情况下触发 Shadow。我建议检查一下 Redux。
使用 z-index 样式确保阴影出现在页面和模式之间。例如阴影 z-index 1,模态容器 2。此外,请确保阴影和模态容器都定位为绝对位置,因为它们都应覆盖页面。
这是一个伪简化:
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {
hasShadow: false,
modal: null, // Modal can be a React-component, like the Popup.
};
}
handleHasShadow = hasShadow => {
this.setState({ hasShadow });
}
handleSetModal = modal => {
this.setState({ modal });
}
render() {
return (
<div>
<form ...>
{
this.props.currentPage === this.state.page
? <MessageBrokerButton handleHasShadow={this.handleHasShadow} />
: null
}
</form>
<Shadow isEnabled={this.state.hasShadow} />
{/* You can give modal as a prop too! */}
<ModalContainer>{modal}</ModalContainer>
</div>
);
}
}
Shadow.jsx
const Shadow = ({ isEnabled }) => {
return isEnabled ? (
<div
style={{
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
background: '#000000',
opacity: 0.5,
zIndex: 1,
}}
/>
) : null;
}
现在您只需使用 this.props.handleHasShadow(true/false) 函数来 enable/disable 阴影。阴影将与父(页面)组件一样大。
您可能还想确保焦点停留在模态框内。否则用户将能够从模式中退出。这里的关键词是 focus-trap.