<div class="popup-content chattingroom">클래스 이름 사이에 공백을 넣으면 두 클래스가 동시에 적용되는 것을 의미한다.
.popup-content.chattingroom{ left: 900px; display: block; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./style.css"> </head> <body> <div class="custom-button" onclick="openPopup();"></div> <div class="popup-wrap"> <div class="popup-content"> <span onclick="openPopup();"></span> <div class="content-wrapper"> <img src="https://blog.kakaocdn.net/dna/csnaXD/btqxB6Hdt3R/AAAAAAAAAAAAAAAAAAAAACOsYz9Dk08Taj47SHt3jzXtMw38QipPJjYO2VohyVru/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1777561199&allow_ip=&allow_referer=&signature=vs3It3VXfyCeiNilP3k5StMj0Ss%3D" alt="이미지 설명"> <div class="offset"> <img src="https://play-lh.googleusercontent.com/4ExClCk0jBhi_0PjUgWzvvAaoPBv1kcbhDchdTMKmARqtwj3RNX1-whKqYznY3IWtI8" alt=""> <p>인터파크입니다😀</p> <p>안녕하세요? 국내외 항공권 숙소 여행 최저가 예약부터 뮤지컬 콘서트 연극 티켓까지 모두 한번에 예약하세요😁</p> <div class="inquire"> <h3 class="content-wrapper2">새 문의하기</h3> </div> </div> </div> <div class="chatting"> 채팅💬 </div> <div class="imgsize"> <img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMTExMDFfMjkx%2FMDAxNjM1NzcyNTAyMzM2.cJE1tVC6KDvRbLggbBVEvvTt44ThhLU0wXelkyRh_bgg.ogMtpmeg-v7VIqtsSBpxHCNzt--aP7oHwL3PVm2RgiQg.JPEG.yunalee1997%2F4cc82b04dee244c22d13aee91e4b5e58.jpg&type=sc960_832" alt=""> <p onclick="chattingroom()">User1</p> </div> <div class="border-bottom"></div> <div class="imgsize"> <img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMTExMDFfMjkx%2FMDAxNjM1NzcyNTAyMzM2.cJE1tVC6KDvRbLggbBVEvvTt44ThhLU0wXelkyRh_bgg.ogMtpmeg-v7VIqtsSBpxHCNzt--aP7oHwL3PVm2RgiQg.JPEG.yunalee1997%2F4cc82b04dee244c22d13aee91e4b5e58.jpg&type=sc960_832" alt=""> <p onclick="chattingroom()">User2</p> </div> <div class="border-bottom"></div> <div class="imgsize"> <img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMTExMDFfMjkx%2FMDAxNjM1NzcyNTAyMzM2.cJE1tVC6KDvRbLggbBVEvvTt44ThhLU0wXelkyRh_bgg.ogMtpmeg-v7VIqtsSBpxHCNzt--aP7oHwL3PVm2RgiQg.JPEG.yunalee1997%2F4cc82b04dee244c22d13aee91e4b5e58.jpg&type=sc960_832" alt=""> <p onclick="chattingroom()">User3</p> </div> <div class="border-bottom"></div> <div class="imgsize"> <img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMTExMDFfMjkx%2FMDAxNjM1NzcyNTAyMzM2.cJE1tVC6KDvRbLggbBVEvvTt44ThhLU0wXelkyRh_bgg.ogMtpmeg-v7VIqtsSBpxHCNzt--aP7oHwL3PVm2RgiQg.JPEG.yunalee1997%2F4cc82b04dee244c22d13aee91e4b5e58.jpg&type=sc960_832" alt=""> <p onclick="chattingroom()">User4</p> </div> <div class="border-bottom"></div> <div class="imgsize"> <img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMTExMDFfMjkx%2FMDAxNjM1NzcyNTAyMzM2.cJE1tVC6KDvRbLggbBVEvvTt44ThhLU0wXelkyRh_bgg.ogMtpmeg-v7VIqtsSBpxHCNzt--aP7oHwL3PVm2RgiQg.JPEG.yunalee1997%2F4cc82b04dee244c22d13aee91e4b5e58.jpg&type=sc960_832" alt=""> <p onclick="chattingroom()">User5</p> </div> <div class="border-bottom"></div> </div> <div class="popup-content chattingroom"> <span onclick="chattingpage();"></span> <div class="content-wrapper"> <img src="https://blog.kakaocdn.net/dna/csnaXD/btqxB6Hdt3R/AAAAAAAAAAAAAAAAAAAAACOsYz9Dk08Taj47SHt3jzXtMw38QipPJjYO2VohyVru/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1777561199&allow_ip=&allow_referer=&signature=vs3It3VXfyCeiNilP3k5StMj0Ss%3D" alt="이미지 설명"> <h3>인터파크에 문의하기</h3> <h5>⨳ 보통 수십 분 내 답변</h5> <p class="font-size">인터파크</p> <div class="offsetchatting"> <div style="font-size: 14px;">안녕하세요? 고객의 편의성을 돕는 인터파크입니다.</div> <div style="font-size: 14px;">문의를 남겨주시면 최대한 신속하게 답변 드리겠습니다.😀</div> <img src="https://play-lh.googleusercontent.com/4ExClCk0jBhi_0PjUgWzvvAaoPBv1kcbhDchdTMKmARqtwj3RNX1-whKqYznY3IWtI8" alt="" style="width: 30px; height: 30px; margin-left: -30px; "> <div style="position: relative; text-align: center;"> <div onclick="enableInput()" contentEditable="true" style="background-color: rgb(255, 255, 255); width: 250px; height: 40px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, 340%); border-radius: 10px; display: flex; align-items: center; justify-content: flex-start; padding-left: 10px;"> <p id="message" style="text-align: left; margin: 0; color: rgb(58, 56, 54); font-size: 13px;">메시지를 입력해주세요.</p> </div> </div> </div> </body> <script src="./index.js"></script> </html>
body{ margin: 0; padding: 0; } .popup-wrap{ /* 브라우저 크기 vw 가로 */ /* 브라우저 크기 vh 세로 */ /* 100vw 보고있는 브라우저 창의 전체 너비 */ /* 100vh 보고있는 브라우저 창의 전체 높이 */ width: 100vw; height: 100vh; position: fixed; display: none; background-color: rgba(0, 0, 0, 0.5); } /* popup-wrap클래스와 is-active 둘다 클래스를 가지고 있을때 */ /* 태그 한개가 클래스를 두개 가지고 있을때 */ .popup-wrap.is-active{ display: block; } .popup-wrap .popup-content{ background-color: #fff; border-radius:12px; width: 300px; height: 500px; /* 보고있는 브라우저 기준으로 위치를 맞출수 있다. fixed */ position: fixed; top: 50%; left: 500px; transform: translate(-50%, -50%); } .popup-wrap .popup-content span { width: 30px; height: 30px; /* 안보이면 block 속성이 없는거다.. */ display: block; position: absolute; right: 0; cursor: pointer; } .popup-wrap .popup-content span::after, .popup-wrap .popup-content span::before { content: ''; width: 15px; height: 4px; background-color: black; border-radius: 5px; display: block; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(45deg); } .popup-wrap .popup-content span::before { transform: translate(-50%, -50%) rotate(-45deg); } .custom-button { position: fixed; bottom: 20px; right: 20px; width: 50px; height: 50px; background-color: antiquewhite; border: none; border-radius: 20px; cursor: pointer; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); background-image: url("https://image.fmkorea.com/files/attach/new/20201219/1135415169/2380230120/3269864399/997c818d2ed1029cde9e9a29ce518f31.png"); background-size: cover; background-position: center; } .content-wrapper{ text-align: center; cursor: pointer; } .content-wrapper{ text-align: center; margin: auto; } .content-wrapper img { width: 150px; height: auto; margin-right: 15px; margin: 0; } .offset{ background-color: white; width: 270px; margin: auto; height: 160px; border: 1px solid white; border-radius: 10px; box-shadow: rgba(255, 255, 255, 0.12) 0px 0px 2px 0px inset, rgba(0, 0, 0, 0.05) 0px 0px 2px 1px, rgba(0, 0, 0, 0.08) 0px 2px 6px; } .offsetchatting{ background-color: white; width: 230px; margin: auto; height: 100px; border: 1px solid white; border-radius: 10px; box-shadow: rgba(255, 255, 255, 0.12) 0px 0px 2px 0px inset, rgba(0, 0, 0, 0.05) 0px 0px 2px 1px, rgba(0, 0, 0, 0.08) 0px 2px 6px; text-align: left; transform: perspective(600px) rotateX(5deg) translateY(5px); } .offset p { margin: 10; margin-top:10px ; width: 180px; } .inquire{ background-color: powderblue; width: 240px; margin: auto; height: 40px; border: 1px solid powderblue; border-radius: 10px; } .popup-wrap .popup-content .offset img { max-width: 15%; float: left; height: auto; } .imgsize{ display: flex; margin-left: 10px; margin-top: 10px; height: 40px; } .chatting{ display: flex; margin-left: 15px; } .popup-wrap .popup-content .offset p { width: 100%; margin: 10px 0; } .popup-wrap .popup-content .offset .inquire { display: flex; justify-content: center; align-items: center; height: 20%; } .popup-wrap .popup-content .offset .inquire .content-wrapper2 { background-color: powderblue; width: 240px; height: 10px; border: 1px solid powderblue; border-radius: 10px; display: flex; justify-content: center; align-items: center; color: white; font-size: 16px; } .border-bottom{ border-bottom: 1px solid gray; } .imgsize{ display: flex; align-items: center; cursor: pointer; } .imgsize img{ margin-right: 10px; width: 40px; height: 40px; } .popup-content.chattingroom{ left: 900px; display: none; } .font-size{ font-size: 5px; color: gray; display: flex; margin-left: 40px; }
// 팝업 열어주는 함수 function openPopup(){ let popup = document.querySelector(".popup-wrap"); // 디버깅 습관 console.log(popup); console.log(popup.className); console.log(popup.classList); // popup.className // popup.classList // popup.className을 사용하면 문자열을 그대로 대입해주면 되고 // popup.classList을 사용하면 메소드를 사용하면 된다. // // popup.className 써보자 // 클래스 구분을 줘야 하기때문에 ' is-active'앞에 한칸 띄워줬다. // popup.className = popup.className + " is-active"; // popup.classList.add("is-active"); // 와 메소드 편하네 // 조건문으로 해보자 클래스가 있는지 확인을 하고 있으면 붙히지말고 // 없으면 붙히자.. // popup.classList.contains("is-active") : is-active 클래스가 // 있는지 확인 // 문자열 버전 // let strArr = popup.className.split(" "); // if(strArr.indexOf("is-active") != -1){ // // class 있으면 // // 문자열 제거해서 클래스를 지울수도 있고. // }else{ // // class 없으면 // popup.className = popup.className + " is-active"; // } // 메소드 사용해서 조건 추가 if(popup.classList.contains("is-active")){ // is-active 있으면 제거할거임 ㅎㅎ // remove 클래스 제거 메소드 popup.classList.remove("is-active"); var chattingRoom = document.querySelector('.popup-content.chattingroom'); chattingRoom.style.display = 'none'; }else{ // is-active 없으면 추가할거임 // add 클래스 추가 메소드 popup.classList.add("is-active"); } } // 어렵고 힘든게 정상... function chattingroom(){ var chattingRoom = document.querySelector('.popup-content.chattingroom'); chattingRoom.style.display = 'block'; } function chattingpage(){ var chattingRoom = document.querySelector('.popup-content.chattingroom'); chattingRoom.style.display = 'none'; } function enableInput(){ let messageElement = document.getElementById("message"); messageElement.contentEditable = true; messageElement.focus(); }
.popup-wrap{ /* 브라우저 크기 vw 가로 */ /* 브라우저 크기 vh 세로 */ /* 100vw 보고있는 브라우저 창의 전체 너비 */ /* 100vh 보고있는 브라우저 창의 전체 높이 */ width: 100vw; height: 100vh; position: fixed; display: none; background-color: rgba(0, 0, 0, 0.5);}
.popup-content.chattingroom{ left: 900px; display: none;}
두개를 display:none으로 해놓아서 처음에는 화면이 안뜨게 한다.
하지만 .custom-button으로 클릭할수 있는 맨 처음 상하단에 버튼같은게 있는데
클릭하면 openPopup() 이 실행되서 아래 구문이 실행된다.
<div class="custom-button" onclick="openPopup();"></div> <div class="popup-wrap"> <div class="popup-content">
function openPopup(){ let popup = document.querySelector(".popup-wrap"); if(popup.classList.contains("is-active")){ // is-active 있으면 제거할거임 ㅎㅎ // remove 클래스 제거 메소드 popup.classList.remove("is-active"); var chattingRoom = document.querySelector('.popup-content.chattingroom'); chattingRoom.style.display = 'none'; }else{ // is-active 없으면 추가할거임 // add 클래스 추가 메소드 popup.classList.add("is-active"); } }팝업창을 열면 containes is-active가 활성화되고
팝업창을 끄면 remove("is-active)가 활성화되는데 만약 그 이전에 user1이라는 채팅방에 들어가서 팝업창을 더 띄웠을때도 같이 꺼지게 설정해놓았다.
?? 왜 user를 클릭전에는 popup-content chattingroom이 왜 안보이는지 설명하자면
if (popup.classList.contains("is-active")) { // is-active 클래스가 있는 경우 popup.classList.remove("is-active"); // is-active 클래스 제거 var chattingRoom = document.querySelector('.popup-content.chattingroom'); chattingRoom.style.display = 'none'; // 팝업 내용 숨김 처리 } else { // is-active 클래스가 없는 경우 popup.classList.add("is-active"); // is-active 클래스 추가 }1. 초기 상태에서 popup 요소는 is-active 클래스를 가지고 있지 않으므로 else 블록이 실행되고
2. popup-classList.add("is-active") 코드는 popup 요소에 "is-active" 클래스를 추가한다.
3. 이로 인해 popup요소는 활성화 상태로 변경된다.
4. 그러나 이 단계에서는 chattingRoom 이라는 클래스를 가진 요소가 초기에 display: none 으로 설정되어 있으므로 보이지 않는다.
아래 코드는 chattingroom 부분인데
<div class="imgsize"> <img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMTExMDFfMjkx%2FMDAxNjM1NzcyNTAyMzM2.cJE1tVC6KDvRbLggbBVEvvTt44ThhLU0wXelkyRh_bgg.ogMtpmeg-v7VIqtsSBpxHCNzt--aP7oHwL3PVm2RgiQg.JPEG.yunalee1997%2F4cc82b04dee244c22d13aee91e4b5e58.jpg&type=sc960_832" alt=""> <p onclick="chattingroom()">User1</p>function chattingroom(){ var chattingRoom = document.querySelector('.popup-content.chattingroom'); chattingRoom.style.display = 'block'; }.popup-content.chattingroom{ left: 900px; display: none; }
user1을 클릭하기 이전에는 display:none으로 설정해 놓아서 안보이는거고
자바스크립트 부분 queryselector를 활용해서 chattingroom의 요소를 가져온후 (onclick의 요소)
클릭을 하면 chattingRoom.style.display = 'block'으로 설정해놓아서
클릭하면 user1의 chattingroom 이 보이게 된다.



😱또 팀프로제트시에
1. 태그 속성의 기본 body나 span div 등등은 css에 적용하지말고
2. class 나 value(가급적 영어로 한글로 해도 되지만) 모두 영어로 해야되는데 특히 class는 무조건 영어로
'node.js프로젝트(김아현,이무헌,박민우,신근호)' 카테고리의 다른 글
| project day-5 (axios 사용해서 mysql에 채팅 내용과 유저아이디 기록) (0) | 2023.06.13 |
|---|---|
| project day-4 (0) | 2023.06.12 |
| 프로젝트 도중 고칠것 (0) | 2023.06.12 |
| 팀프로젝트 day-2 영화 예매 좌석 구현 (css/js 를 숙련시켜보자) (1) | 2023.06.08 |
| sequelize사용 팀프로젝트 -1day (hasmany belongsTo ) (0) | 2023.06.05 |