diff --git a/README.md b/README.md index 14a9bf0..60834b0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # html-css-js-seminar -멋쟁이사자처럼 12기 2주차 html-css-js 세미나 레포지토리 입니다. \ No newline at end of file +멋쟁이사자처럼 12기 3주차 html-css-js 세미나 레포지토리 입니다. \ No newline at end of file diff --git a/instagram.css b/instagram.css new file mode 100644 index 0000000..55123b9 --- /dev/null +++ b/instagram.css @@ -0,0 +1,271 @@ +.main-container { + display: flex; + flex-direction: column; + width: 700px; + margin: auto; +} + +.header { + display: flex; + justify-content: space-between; + width: 100%; + height: 30px; + border-bottom: 2px solid #d3d3d3; + padding-bottom: 10px; +} + +.header .logo { + height: 100%; +} + +.header .search { + padding: 3px; + border: 2px solid #d3d3d3; + border-radius: 2px; +} + +.header .icon-list { + height: 100%; +} + +.story-container { + display: flex; + flex-direction: row; + justify-content: space-between; + margin-top: 10px; + padding-right: 20%; + padding-left: 20%; + height: 20%; +} + +.story-container .story-element { + display: flex; + flex-direction: column; + align-items: center; +} + +.story-container .story { + width: 40px; + height: 40px; + border: 2px solid orange; + border-radius: 50%; + background-color: gray; +} + +.story-container .story-owner { + margin-top: 2px; + font-size: 8px; +} + +.article-container { + display: flex; + flex-direction: column; + width: 60%; + margin: 10px auto; + border: 2px solid #d3d3d3; +} + +/* profile-container 부분 시작 */ +.profile-container { + padding: 10px; + display: flex; + justify-content: space-between; +} + +.profile { + width: 20%; + display: flex; +} + +.profile-name { + margin-left: 5px; + font-weight: bold; +} + +.profile-image { + width: 20px; + border-radius: 10px; +} + +.menu { + width: 20px; + height: 20px; + background-image: radial-gradient(circle, black 2px, transparent 2.1px); + background-size: 100% 33.33%; +} +/* profile-container 부분 끝 */ + +/* 이미지 부분 시작*/ +.article { + width: 100%; +} +/* 이미지 부분 끝*/ + +/* button-container 부분 시작 */ +.button-container { + border-bottom: 2px solid #d3d3d3; + padding-top: 5px; +} +.feed-buttons:hover { + opacity: 0.7; + cursor: pointer; +} +.feed-buttons { + width: 40px; + margin-left: 3px; +} +/* button-container 부분 끝 */ + +/* comment container 부분 시작*/ +.comment-container { + padding: 5px 0px; + display: flex; + width: 100%; +} +.smile { + width: 30px; +} +.smile:hover { + cursor: pointer; + opacity: 0.7; +} + +.comment { + height: 25px; + border: none; + width: 80%; +} + +.comment-button { + border: none; + background-color: rgb(0, 0, 0, 0); + color: blue; + opacity: 50%; +} +.comment-button:hover { + opacity: 20%; + cursor: pointer; +} +/* comment container 부분 끝*/ + +/* 피드 부분 끝*/ + +.footer-message { + display: flex; + justify-content: center; + color: gray; + font-size: 15px; +} + +.story-modal { + display: none; /* 모달창 숨겨 놓기 */ + position: fixed; + z-index: 1; /* 모달창을 제일 앞에 두기 */ + padding-top: 100px; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; /* 스크롤 허용 auto */ + cursor: pointer; /* 마우스 손가락모양 */ + background-color: rgba(0, 0, 0, 0.8); /* 0.8은 투명도*/ +} + +#story-image { + border-radius: 20px; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); /* 모달 가운데에 놓기 */ +} + +#profile-modal { + display: none; + width: 325px; + height: 250px; +} + +#like-count-text { + padding-left: 6px; + padding-bottom: 6px; +} + +#red-heart { + display: none; +} + +.comment-wrapper:hover > .comment-delete-icon { + display: inline; +} + +.comment-delete-icon { + width: 12px; + height: 12px; + cursor: pointer; + display: none; +} + +.alert-container { + width: 20%; + height: 10%; + display: none; + justify-content: space-around; + align-items: center; + position: fixed; + right: -100%; + top: 20%; + background-color: grey; + opacity: 0.9; + border-radius: 10px; + transition: right 0.5s ease-out; +} +.alert-container .alert-profile-image { + display: flex; + margin-right: 10px; + width: 30px; + height: 30px; + border-radius: 15px; +} +.alert-container .alert-message { + display: flex; + color: white; + opacity: 1; +} + +.alert-origin-image-container { + display: flex; +} + +.alert-origin-image-container .alert-origin-image { + display: flex; + width: 30px; + height: 30px; +} +.emoji-container { + display: none; + position: absolute; + flex-direction: column; + width: 250px; + top: 63.6%; + left: 37.7%; + height: 70px; + background-color: grey; + border-radius: 10px; +} +.emoji-text { + display: flex; + font-size: 14px; + margin-top: 6px; + margin-left: 12px; + margin-bottom: 10px; + align-items: center; + color: white; +} +.emoji-list { + display: flex; + flex-direction: row; + margin-left: 10px; + align-items: center; + gap: 3px; + font-size: 20px; +} diff --git a/instagram.html b/instagram.html new file mode 100644 index 0000000..ec9e6a8 --- /dev/null +++ b/instagram.html @@ -0,0 +1,118 @@ + + + + + + + Liongram + + +
+
+ + + +
+
+
+ +
+
+ likelion_snu님이 게시물을 좋아합니다. +
+
+ +
+
+
+
+
+
+
내 스토리
+
+
+
+
xeesoxee
+
+
+
+
e0_jin_03
+
+
+
+
j._.woonly
+
+
+
+
jennierubyjane
+
+
+
+ +
+
+
+
+ + likelion_snu +
+ +
+
+ +
+ +
+ + + + +
+ 좋아요 + 1003 +
+
+
+
+ + + +
+
+
+
최고 인기 이모티콘
+
+ 😊 + 😍 + 😘 + 😜 + 😳 + 🙂 + 🙏 + 🚀 + 😀 + 😁 +
+
+
+
+
+ +
+ + + diff --git a/instagram.js b/instagram.js new file mode 100644 index 0000000..354459e --- /dev/null +++ b/instagram.js @@ -0,0 +1,246 @@ +// 실습 1 + +const storyModal = document.querySelector(".story-modal"); +const storyElements = document.querySelectorAll(".story-element"); + +storyElements.forEach((storyElement) => { + storyElement.addEventListener("click", () => { + storyModal.style.display = "block"; + }); +}); + +document.addEventListener("click", function (event) { + if (event.target === storyModal) { + storyModal.style.display = "none"; + } +}); + +// 이벤트 버블링을 찾아보면 된다 + +// 실습 2 +const profile_container = document.querySelector(".profile-container"); +const profile_modal = document.getElementById("profile-modal"); + +profile_container.addEventListener("mouseover", () => { + profile_modal.style.display = "block"; + profile_modal.style.position = "absolute"; +}); + +profile_container.addEventListener("mouseout", () => { + profile_modal.style.display = "none"; +}); + +// 실습 3 +const likeCount = document.getElementById("like-count"); +const blackHeart = document.getElementById("black-heart"); +const redHeart = document.getElementById("red-heart"); + +// TODO1. 검정색 하트를 눌렀을 때 +blackHeart.addEventListener("click", () => { + // 빨간 하트를 보여주고 검정 하트는 숨기기 + redHeart.style.display = "inline"; + blackHeart.style.display = "none"; + + // likeCount 요소의 내부 텍스트를 취득하세요 + const count = parseInt(likeCount.innerText); // PUT YOUR CODE HERE... + + // 좋아요 갯수를 하나 늘려서 likeCount 요소의 내부 텍스트로 저장하세요. + likeCount.innerText = count + 1; // PUT YOUR CODE HERE... +}); + +// TODO2. 빨간색 하트를 눌렀을 때 +redHeart.addEventListener("click", () => { + // 검정 하트는 보여주고 빨간 하트는 숨기기 + blackHeart.style.display = "inline"; + redHeart.style.display = "none"; + + // likeCount 요소의 내부 텍스트를 취득하세요 + const count = parseInt(likeCount.innerText); // PUT YOUR CODE HERE... + + // 좋아요 갯수를 하나 감소시켜 likeCount 요소의 내부 텍스트로 저장하세요. + likeCount.innerText = count - 1; // PUT YOUR CODE HERE... +}); + +const commentsCreateForm = document.querySelector(".comments-create-form"); +const commentContainer = document.querySelector(".written-comments-container"); +const commentInput = document.querySelector(".comment"); + +// 댓글의 내용을 저장할 자료구조 +const commentsList = []; +let commentId = 0; + +// form 태그 제출 시 이벤트 핸들링. event(e)를 인자로 받아 event 정보를 취득. 매우 중요 +commentsCreateForm.addEventListener("submit", (e) => { + // TODO1. form 태그가 클릭 되었을 때 페이지 이동을 막고 댓글 내용을 취득하기 + e.preventDefault(); + const commentText = commentInput.value; + if (!commentText) return; + commentsList.push(commentText); + + // TODO2. 댓글 내용이 표시될 HTML노드를 만들어주기 + // 이렇게 string 형식으로 HTML요소를 만들어서 HTML파일에 삽입할 수 있어요! + commentId = commentsList.length; + const commentNode = ` +
+ ${commentText} + comment +
+ `; + + // TODO3. "written-comments-container"에 댓글 HTML노드를 추가해주기 + // 채팅창 값은 비워주기 + commentContainer.innerHTML = commentContainer.innerHTML + commentNode; + commentInput.value = ""; +}); + +// 실습 5 + +const deleteComment = (id) => { + // TODO1. commentsList 의 id번째 원소를 하나 삭제합니다. + // 우리가 각 comment의 id 를 commentsList 에서의 순서로 설정했기에 가능합니다. + commentsList.splice(id, 1); + + // TODO2. 새로운 commentsList에 map 함수를 호출하여 + // 댓글 HTML 노드들로 이루어진 배열을 만듭니다. + // join 함수를 이용해 배열 원소들을 하나의 스트링으로 만들어 + // commentContainer의 innerHTML에 저장합니다. + + commentContainer.innerHTML = commentsList + .map( + (comment, index) => ` +
+ ${comment} + comment +
` + ) + .join(""); +}; + +const footer = document.querySelector(".footer-message"); +footer.innerText = `Ⓒ ${new Date().getFullYear()} INSTAGRAM FROM META`; + +const logo = document.querySelector(".logo"); +const logoIcons = document.querySelectorAll(".icon-list"); +const profileImage = document.querySelectorAll(".profile"); +const moreBtn = document.querySelector(".menu"); +const storyModalElements = document.querySelectorAll(".story-element"); +const alertContainer = document.querySelector(".alert-container"); + +blackHeart.addEventListener("mouseover", () => { + blackHeart.style.cursor = "pointer"; + blackHeart.style.opacity = "0.7"; +}); +blackHeart.addEventListener("mouseout", () => { + blackHeart.style.opacity = "1"; + blackHeart.style.cursor = "default"; +}); +redHeart.addEventListener("mouseover", () => { + redHeart.style.cursor = "pointer"; + redHeart.style.opacity = "0.7"; +}); +redHeart.addEventListener("mouseout", () => { + redHeart.style.opacity = "1"; + redHeart.style.cursor = "default"; +}); +storyModalElements.forEach((element) => { + element.addEventListener("mouseover", () => { + element.style.cursor = "pointer"; + element.style.opacity = "0.7"; + }); +}); +storyModalElements.forEach((element) => { + element.addEventListener("mouseout", () => { + element.style.opacity = "1"; + element.style.cursor = "default"; + }); +}); +moreBtn.addEventListener("click", () => { + moreBtn.style.cursor = "pointer"; + moreBtn.style.opacity = "0.5"; +}); +moreBtn.addEventListener("mouseout", () => { + moreBtn.style.opacity = "1"; + moreBtn.style.cursor = "default"; +}); +logo.addEventListener("click", () => { + location.reload(true); +}); +profileImage.forEach((image) => { + image.addEventListener("mouseover", () => { + image.style.cursor = "pointer"; + image.style.opacity = "0.7"; + }); +}); +profileImage.forEach((image) => { + image.addEventListener("mouseout", () => { + image.style.opacity = "1"; + image.style.cursor = "default"; + }); +}); +logoIcons.forEach((icon) => { + icon.addEventListener("mouseover", () => { + icon.style.cursor = "pointer"; + icon.style.opacity = "0.7"; + }); +}); +logoIcons.forEach((icon) => { + icon.addEventListener("mouseout", () => { + icon.style.opacity = "1"; + icon.style.cursor = "default"; + }); +}); +logo.addEventListener("mouseover", () => { + logo.style.cursor = "pointer"; + logo.style.opacity = "0.7"; +}); +logo.addEventListener("mouseout", () => { + logo.style.opacity = "1"; + logo.style.cursor = "default"; +}); + +blackHeart.addEventListener("click", () => { + alertContainer.style.display = "flex"; + setTimeout(() => { + alertContainer.style.right = "0"; + }, 100); + setTimeout(function () { + alertContainer.style.right = "-100%"; + setTimeout(function () { + alertContainer.style.display = "none"; + }, 500); + }, 3000); +}); + +const emojiElements = document.querySelectorAll(".emoji-element"); +const emojiContainer = document.querySelector(".emoji-container"); +const smileBtn = document.querySelector(".smile-btn"); +smileBtn.addEventListener("click", () => { + if (emojiContainer.style.display === "flex") { + emojiContainer.style.display = "none"; + } else emojiContainer.style.display = "flex"; +}); + +emojiElements.forEach((emojiElement) => { + emojiElement.addEventListener("click", () => { + commentInput.value = commentInput.value + emojiElement.innerText; + }); +}); +emojiElements.forEach((emojiElement) => { + emojiElement.addEventListener("mouseover", () => { + emojiElement.style.cursor = "pointer"; + emojiElement.style["font-size"] = "24px"; + }); +}); + +emojiElements.forEach((emojiElement) => { + emojiElement.addEventListener("mouseout", () => { + emojiElement.style.cursor = "default"; + emojiElement.style["font-size"] = "20px"; + }); +});