モード領域の外部をクリックしてモードを閉じる
19098 ワード
🤯 質問する
オープンプロジェクトは、何か感じがあれば、私たちはかなりの精力を費やして実現したと思います...つまり、思った以上に意外なところで、気づかなかったミスを発見するということです.
たとえば、
...!!! 🥲
コメント内のより多くのビューをコンポーネントに分離し、より多くのビューを展開するかどうかを状態にして、コメントごとに管理するという問題が発生しました.他のコメントの「もっと」をクリックしても、以前クリックした「もっと」を無効にすることはできません!
🤔 検索方法
[その他のビュー]アイコン(
true
)をクリックして[申告/削除モード]を開き、この状態で[外部]をクリックするとモードが無効になり、モードが消えます.要するに、状態は再びfalse
に変わるべきである.Google検索でモードエリア外をクリックしてモードをオフにする方法は2つあります.
1.外部領域全体をラップした後(
ModalBackdrop
)、モードがアクティブになったら外部をクリックしてモードを無効にします.export default function DropdownMenu() {
const [openDropdown, setOpenDropdown] = useState<boolean>(false);
const openDropdownHandler = () => {
setOpenDropdown(false);
}
return (
<>
<DropDownWrap>
{openDropdow && (
<ModalBackdrop onClick={openDropdownHandler}>
<MenuList>
<div>수정</div>
<div>삭제</div>
</MenuList>
</ModalBackdrop>
)}
</DropDownWrap>
</>
);
}
ModalBackdrop
)、モードがアクティブな場合はイベントターゲットが外部refの場合はモードを無効にします.export default function DropdownMenu() {
const [openDropdown, setOpenDropdown] = useState<boolean>(false);
const outSection = useRef<HTMLDivElement>(null);
const openDropdownHandler = (event: React.MouseEvent<HTMLDivElement>) => {
if (outSection.current === event.target)
setOpenDropdown(false);
}
return (
<>
<DropDownWrap>
{openDropdow && (
<ModalBackdrop ref={outSection} onClick={openDropdownHandler}>
<MenuList>
<div>수정</div>
<div>삭제</div>
</MenuList>
</ModalBackdrop>
)}
</DropDownWrap>
</>
);
}
我々のプロジェクトでは、上記の2つの方法は使用されていません.計算が完了したため、より多くのビューアイコンにposition: absolute
で表示されるため、外部領域をバンドルすることはできません.そうすれば.
appsoluteでは、ドロップダウンメニューが右端に貼られているので、どのくらい離れているかを正確に計算する必要がありますが、反応型にして計算するのは難しいし、成功する保証はありません.
だからよく考えてみると、そのドロップダウンモードが開いたとき、
「外のクリックが感じられるのでは?」
外をクリックしたときに開いた状態を
false
にして閉じるといいです!そう思ったのは
addEventListener
.🛠 解決する
現在、私の問題は素子内で
onClick
で解決できないので、現在位置の素子バーをクリックすると、クリックイベントが受信できる必要があります.そのためwindow.addEventListener('click', ...)
を使用した.要素自体がレンダリングされると、
openDropdown
がオンになると、イベントリスナーはuseEffect
にラップされ、それが実行される.1回目のレンダリング時に無条件に実行!export default function DropdownMenu() {
const [openDropdown, setOpenDropdown] = useState<boolean>(false);
const openDropdownHandler = () => {
setOpenDropdown(false);
}
useEffect(() => {
if (openDropdown) { // 모달이 열려 있으면
window.addEventListener(
'click', // 클릭이 일어났을 때
() => {
setOpenDropdown(false); // 모달을 닫는다!
},
{ once: true }, // 한번만 실행되며 기억되지 않음
);
}
});
{ once: true }
に設定されている条件はwindowで上のイベントリスナーを覚えているのでその条件は設定されておらず、実行するときだけ、最初の1回は起動していましたが、モードが閉じて再度押すと、開かない!また、モードリスト内では、
stopPropagation
を歩いて、クリックイベントは受け付けられません!では外をクリックするだけでモードがオフになります!😂🛠 コード#コード#
export default function DropdownMenu() {
const [openDropdown, setOpenDropdown] = useState<boolean>(false);
const openDropdownHandler = () => {
setOpenDropdown(false);
}
useEffect(() => {
if (openDropdown) {
window.addEventListener(
'click',
() => {
setOpenDropdown(false);
},
{ once: true },
);
}
});
return (
<>
<DropDownWrap>
{openDropdow && (
<MenuList onClick={(e) => e.stopPropagation()}>
<div>수정</div>
<div>삭제</div>
</MenuList>
</ModalBackdrop>
)}
</DropDownWrap>
</>
);
やっとできた...🤯グーグルをあちこちで遊びながら、いろいろな方法を学びました.
でもできなかったら、眠れないかもしれないので、少し探してみたかったのですが、その日が終わってよかったです.休む.😭
でも、今ブログで整理しているときに思いついたのは…では、そのビューをクリックするたびに
useEffect
を実行してレンダリングしますか?!今は文字だけなのであまり負担はありませんが、後で画像やgifを入れることができれば...🤷♀️ △それなら、考えてみましょう.リファレンス
https://dkmqflx.github.io/frontend/2021/04/26/react-modal-close/
https://white-salt.tistory.com/25
https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener
https://pa-pico.tistory.com/20
Reference
この問題について(モード領域の外部をクリックしてモードを閉じる), 我々は、より多くの情報をここで見つけました https://velog.io/@pearpearb/42byte-모달-영역-바깥쪽-클릭시-모달-닫기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol