#html #css #reactjs
#HTML #css #reactjs
Вопрос:
у меня есть всплывающее окно, которое появляется при нажатии кнопки добавить. проблема в том, что всплывающее окно отображается внутри div карты.
ниже приведен мой код,
.outer_wrapper {
display: flex;
flex-direction: column;
position: relative;
justify-content: flex-start;
align-items: center;
overflow: hidden;
flex: 1;
z-index: 1;
}
.control_wrapper {
width: calc(100vw - 16px);
margin: 24px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
@media screen and (max-width: 1320px) {
.control_wrapper {
max-width: 784px;
}
}
.wrapper {
max-height: calc(100vh - 216px);
transition: max-height 300ms ease-in-out;
display: flex;
justify-content: center;
overflow-x: hidden;
overflow-y: scroll;
}
.cards {
display: flex;
flex-wrap: wrap;
}
@media screen and (max-width: 1320px) {
.cards {
padding: 0 calc(50vw - 400px);
}
}
.card {
max-width: 384px;
height: 256px;
margin: 8px;
display: flex;
flex-direction: column;
align-items: flex-end;
}
@media screen and (max-width: 1320px) {
.card {
width: calc(50% - 16px);
transform: translate3D(0px, 0px, 0px) scale(1);
}
}
.content {
flex: 1;
width: 100%;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.name {
display: flex;
flex: 1;
flex-direction: column;
padding: 10px 0px 10px 32px;
white-space: nowrap;
overflow: hidden;
}
.button_wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-right: 16px;
margin-left: 16px;
}
.overlay {
/* this is within the card and not expanding outside card div */
position: fixed;
top: 60px;
transition: top 300ms ease-in-out;
bottom: 60px;
left: 0;
right: 0;
z-index: 100;
display: flex;
justify-content: center;
align-items: center;
}
.dialog {
padding: 16px;
width: 384px;
max-height: calc(100% - 200px);
display: flex;
flex-direction: column;
}
.container {
align-items: center;
padding-bottom: 16px;
margin-bottom: 16px;
}
.item {
display: flex;
justify-content: space-between;
align-items: center;
height: 48px;
}
.dialog_footer {
height: 24px;
margin: 0 -16px -16px;
}
.message {
position: absolute;
bottom: 24px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="outer_wrapper">
<div class="control_wrapper"></div>
<div class="wrapper">
<div class="cards">
<div class="card">
<a class="content"></a>
<div class="footer">
<a class="name">
<div class="button_wrapper">
<button>add</button>
<div class="overlay">
<!--
//this is the one that is inside card div only i want
//it to occupy full screen height and width
-->
<div class="dialog">
<span>some </span>
<input type="text" placeholder="input..." />
<div class="container">
<span>something</span>
<div class="list">
<div class="item"></div>
</div>
<div class="dialog_footer"></div>
</div>
<div class="message"></div>
</div>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
Я не уверен, как разместить оверлейный div за пределами div карты и соответствовать ширине и высоте экрана.
я не уверен, что проблема связана с наложением div или dialog div
может кто-нибудь помочь мне с этим. Спасибо.
Редактировать:
как это происходит в react
function Parent() {
return (
<Wrapper>
<Cards>
{currentList.map((item, index) => {
return (
<Card
key={index}
$bgUrl={item.thumbnailUrl}
$index={index}
>
<Content to={toUrl} />
<Footer>
<Name to={toUrl}>
<span>{site.name}</span>
<span></span>
</Name>
<AddItem/>
)}
</Cards>
</Wrapper>
);
}
const Wrapper = styled.div`
max-height: calc(100vh -46 96}px);
display: flex;
overflow-x: hidden;
overflow-y: scroll;
`;
const Cards = styled.div`
display: flex;
flex-wrap: wrap;
`;
const Card = styled.div<{
width: calc(33.33% - 16px);
display: flex;
flex-direction: column;
align-items: flex-end;
background-size: cover;
`;
function AddItem({isDialogOpen}: props) {
return (
<AddItemWrapper>
<button onClick={onAddClick}>Add</button>
{isDialogOpen amp;amp; (
<Overlay>
<Dialog></Dialog>
</Overlay>
)}
</AddItemWrapper>
);
}
const AddItemWrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-right: 16px;
`;
const Overlay = styled.div`
position: fixed;
top: 60px;
bottom: 40px;
left: 0;
right: 0;
z-index: 100;
display: flex;
justify-content: center;
align-items: center;
`;
const Dialog = styled.div`
padding: 16px;
width: 384px;
max-height: calc(100% - 200px);
display: flex;
flex-direction: column;
`;
Ответ №1:
Если вы уже используете React, вы можете использовать порталы для создания всплывающих окон
// Parent component
export default function App() {
const [isOpen, setIsOpen] = useState(false);
const popupRef = useRef(null);
const [popupSt, setPopupSt] = useState();
return (
<>
<div
style={BUTTON_WRAPPER_STYLES}
onClick={() => console.log("clicked")}
ref={(current) => {
popupRef.current = current;
setPopupSt(popupRef.current);
}}
>
<button onClick={() => setIsOpen(true)}>Open Modal</button>
<Popup
open={isOpen}
onClose={() => setIsOpen(false)}
popupRef={popupRef}
>
Fancy Popup
</Popup>
</div>
<div style={OTHER_CONTENT_STYLES}>Other Content</div>
</>
);
}
// Popup component
export default function Popup({ open, children, onClose, popupRef }) {
if (!open || !popupRef.current) return null;
return ReactDom.createPortal(
<>
<div style={OVERLAY_STYLES} />
<div style={MODAL_STYLES}>
<button onClick={onClose}>Close Popup</button>
Hi, this is popup
</div>
</>,
document.getElementById("portal")
);
}
// index.html
..
<div id="portal"></div>
..
Комментарии:
1. Потому что до первого рендеринга в DOM нет элемента, и
document.getElementById
он не может получить доступ ни к одному элементу. Оно будет отображатьсяTarget container is not a DOM element
. Итак, я использовал useRef в родительском компоненте и отправил его в popupComponent.
Ответ №2:
Вы помещаете наложение внутри карты, так что теперь его атрибуты положения относятся к карте. Поместите наложение вне карты как отдельный элемент (на том же уровне, что и карта), и оно должно работать.
Комментарии:
1. спасибо, но могу ли я сделать это, не помещая наложение за пределы карты?
2. Что плохого в том, чтобы поместить наложение вне карты? Это отдельный элемент, так что даже лучше для семантики
3. Это в основном тот же код, за исключением того, что вы вырезаете наложение изнутри карты и вставляете его сразу после закрытия <div class=»card»>
4. или на самом деле я не могу этого сделать, поскольку это наложение является div внутри компонента react, который также используется другим компонентом