一、打开弹框时,背景位置固定,弹窗可滚动
- 给body添加样式
position: fixed; width: 100%;
就可以固定背景,不许背景滚动,但这个时候会直接定位到顶部 - 为了解决上述直接定位到顶部的问题,可以记录弹框打开之前的位置,给body添加样式的同时设置body距离顶部的距离
- 最后,关闭弹框时,删除body的样式
style.scss
.modal-wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
position: fixed;
background: rgba(0, 0, 0, 0.6);
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1999;
}
.page-hidden {
position: fixed;
width: 100%;
}
.hide {
display: none;
}
index.jsx
import 'babel-polyfill';
import React, { useState, useEffect } from 'react';
// [document.scrollingElement兼容性处理](https://github.com/yangg/scrolling-element)
import 'scrolling-element';
// 设置style兼容性处理
import { setStyle } from '../../../libs/utils';
import './style.scss';
const modalWrapper = (WrappedComponent) => {
const hoc = (props) => {
const [scrollTop, setScrollTop] = useState(0);
const allowBodyScrolling = () => {
setStyle(document.body, { top: '0px' });
document.body.classList.remove('page-hidden');
// 在给页面设置了doctype的时候,documentElement.scrollTop(1)/body.scrollTop(2), safari不支持(1), chrome不支持(2)
if (scrollTop > 0) {
if (document.scrollingElement) {
document.scrollingElement.scrollTop = scrollTop;
} else {
document.body.scrollTop = scrollTop;
document.documentElement.scrollTop = scrollTop;
window.pageYOffset = scrollTop;
}
}
};
const forbidBodyScrolling = () => {
let top = document.scrollingElement ? document.scrollingElement.scrollTop : Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop);
setScrollTop(top);
setStyle(document.body, { top: `${-top}px` });
document.body.classList.add('page-hidden');
};
useEffect(() => {
if (props.config.show) {
forbidBodyScrolling();
} else {
allowBodyScrolling();
}
}, [props.config.show]);
return (
<div className={`modal-wrapper${props.config.show ? '' : ' hide'}`}>
<WrappedComponent {...props} />
</div>
);
};
return hoc;
};
export default modalWrapper;

export const setStyle = (element, params = {}) => {
if (!element) return;
if (Object.getOwnPropertyDescriptor(document.body.style, 'font-size').writable) { // 检查style对象的属性是否可编辑
Object.keys(params).forEach((key) => {
element.style[key] = params[key];
});
}
let cssText = element.style.cssText;
const tmpArr = cssText.split(';');
let existAttributes = {};
tmpArr.forEach((item) => {
let res = item.split(':');
if (res && res.length > 1) {
let key = res[0].trim();
let value = res[1].trim();
existAttributes[key] = value;
}
});
element.style.cssText = Object.keys(existAttributes).map(key => `${key}: ${existAttributes[key]}`).join(';');
};
使用方法
const Modal = ({ config }) => {
const { show, onClose, onOk, imgSrc } = config;
return (
<div className="modal">
<img className="close-btn" onClick={onClose} />
<div className="content" >
<img className="img" alt="img" src={imgSrc} />
<div className="button" onClick={onOk}>我知道了</div>
</div>
</div>
);
};
export default modalWrapper(Modal);
网友评论