diff --git a/README.md b/README.md index 9682c00..211db27 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ โ”ฃ ๐Ÿ“‚ chaeyoung โ”ƒ โ”ฃ ๐Ÿ“‚ week1 โ”ƒ โ”— ๐Ÿ“‚ week2 โ€ฆ -โ”ฃ ๐Ÿ“‚ jooyoung +โ”ฃ ๐Ÿ“‚ juyoung โ”ƒ โ”ฃ ๐Ÿ“‚ week1 โ”ƒ โ”— ๐Ÿ“‚ week2 โ€ฆ โ”— ๐Ÿ“‚ yunha diff --git a/juyoung/week1/chapter_4_interactive/4-1_interactive/01_intractive.html b/juyoung/week1/chapter_4_interactive/4-1_interactive/01_intractive.html new file mode 100644 index 0000000..30c7ff0 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-1_interactive/01_intractive.html @@ -0,0 +1,30 @@ + + + + + + + 4-1_interactive-01_interactive.html + + + + + + +
+

Interactive Web

+
+
+
+ Interactive Web +

+ ์ธํ„ฐ๋ ‰ํ‹ฐ๋ธŒ ์›น์€ ์‚ฌ์šฉ์ž์™€ ์›น ์‚ฌ์ดํŠธ๊ฐ€ ์„œ๋กœ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•˜๋ฉฐ, ์ด๋ฅผ ์œ„ํ•ด ๋™์  ์ปจํ…์ธ  ์ƒ์„ฑ, ์‚ฌ์šฉ์ž ํ–‰๋™ ๋ถ„์„ ๋ฐ ๋ฐ˜์˜ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
+
+ ์ด๋Ÿฌํ•œ ์ƒํ˜ธ์ž‘์šฉ์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX)์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ํฐ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. +

+
+
+
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-2_fade/01_variables.html b/juyoung/week1/chapter_4_interactive/4-2_fade/01_variables.html new file mode 100644 index 0000000..9de9cb7 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-2_fade/01_variables.html @@ -0,0 +1,22 @@ + + + + + + + 4-2_fade-01_variables.html + + + + + + +
+

Variables

+
+
DIV ์š”์†Œ
+

P ์š”์†Œ

+
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-2_fade/02_opacity.html b/juyoung/week1/chapter_4_interactive/4-2_fade/02_opacity.html new file mode 100644 index 0000000..390f6d5 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-2_fade/02_opacity.html @@ -0,0 +1,27 @@ + + + + + + + 4-2_fade-02_opacity.html + + + + + + +
+

Opacity & Visibility

+
+
+

Opacity : ํˆฌ๋ช…๋„๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ  1์ด๋ฉด ์™„์ „ ๋ถˆํˆฌ๋ช…, 0์ด๋ฉด ์™„์ „ ํˆฌ๋ช…์„ ๋งํ•˜๋Š”๋ฐ, ์š”์†Œ๊ฐ€ ํˆฌ๋ช…ํ•˜์ง€๋งŒ ํด๋ฆญ์ด๋‚˜ ํ„ฐ์น˜๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , ๋ฌธ์„œ์˜ ํ๋ฆ„์—์„œ๋„ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค.

+

+ Visibility : ๋ณด์ด๋Š”์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์†์„ฑ์œผ๋กœ visible ์†์„ฑ๊ณผ hidden ์†์„ฑ์œผ๋กœ ์š”์†Œ์˜ ๋…ธ์ถœ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๋•Œ์—๋„ ์š”์†Œ๋Š” ๋ณด์ด์ง€ ์•Š์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ฌธ์„œ์˜ ํ๋ฆ„์—์„œ ์ฐจ์ง€ํ•˜๋Š” ๊ณต๊ฐ„์€ ์œ ์ง€๊ฐ€ + ๋ฉ๋‹ˆ๋‹ค. +

+
+
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-2_fade/03_transition.html b/juyoung/week1/chapter_4_interactive/4-2_fade/03_transition.html new file mode 100644 index 0000000..dea0a4e --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-2_fade/03_transition.html @@ -0,0 +1,75 @@ + + + + + + + 4-2_fade-03_transition.html + + + + + + + +
+

Transition

+
+

Transition Examples

+
+
+

opacity

+ +
+
+ ease + ease-in + ease-out + bezier +
+
+
+
+

transform - translate

+ +
+
+ ease + ease-in + ease-out + bezier +
+
+
+
+

transform - rotate

+ +
+
+ ease + ease-in + ease-out + bezier +
+
+
+
+

transform - scale

+ +
+
+ ease + ease-in + ease-out + bezier +
+
+
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-3_card/01_hover_focus_active.html b/juyoung/week1/chapter_4_interactive/4-3_card/01_hover_focus_active.html new file mode 100644 index 0000000..a14440e --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-3_card/01_hover_focus_active.html @@ -0,0 +1,23 @@ + + + + + + + 4-3_card-01_hover_focus_active.html + + + + + + +
+

Hover, Focus, Active

+
    +
  1. +
  2. +
  3. +
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-3_card/02_transform.html b/juyoung/week1/chapter_4_interactive/4-3_card/02_transform.html new file mode 100644 index 0000000..d604359 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-3_card/02_transform.html @@ -0,0 +1,56 @@ + + + + + + + 4-3_card-02_transform.html + + + + + + +
+

Transform

+
    +
  1. + +
    +
    + Card Flip +

    + Lorem ipsum dolor sit amet consectetur adipisicing elit. Aspernatur, vero vitae. Ducimus, quibusdam dicta! Eligendi porro repudiandae adipisci labore laborum ullam, corrupti et sint + dolor dignissimos. Suscipit ut architecto tenetur. +

    +
    +
    +
  2. +
  3. + +
    +
    + Rotate Card +

    + Lorem ipsum dolor sit amet consectetur adipisicing elit. Aspernatur, vero vitae. Ducimus, quibusdam dicta! Eligendi porro repudiandae adipisci labore laborum ullam, corrupti et sint + dolor dignissimos. Suscipit ut architecto tenetur. +

    +
    +
    +
  4. +
  5. + +
    +
    + Card Effect +

    + Lorem ipsum dolor sit amet consectetur adipisicing elit. Aspernatur, vero vitae. Ducimus, quibusdam dicta! Eligendi porro repudiandae adipisci labore laborum ullam, corrupti et sint + dolor dignissimos. Suscipit ut architecto tenetur. +

    +
    +
    +
  6. +
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-3_card/03_animation.html b/juyoung/week1/chapter_4_interactive/4-3_card/03_animation.html new file mode 100644 index 0000000..29f1cb1 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-3_card/03_animation.html @@ -0,0 +1,35 @@ + + + + + + + 4-3_card-03_animation.html + + + + + + +
+

Animation

+
+

3D Image Gallery

+ +
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-4_svg/01_basic.html b/juyoung/week1/chapter_4_interactive/4-4_svg/01_basic.html new file mode 100644 index 0000000..071e6be --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-4_svg/01_basic.html @@ -0,0 +1,39 @@ + + + + + + + 4-4_svg-01_basic.html + + + + + + +
+

SVG

+
+ + + + + + + + + + + + + + + + + + + +
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-4_svg/02_animate.html b/juyoung/week1/chapter_4_interactive/4-4_svg/02_animate.html new file mode 100644 index 0000000..e3eb4b9 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-4_svg/02_animate.html @@ -0,0 +1,117 @@ + + + + + + + 4-4_svg-02_animate.html + + + + + + +
+

SVG

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-4_svg/03_stylesheet.html b/juyoung/week1/chapter_4_interactive/4-4_svg/03_stylesheet.html new file mode 100644 index 0000000..429fd76 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-4_svg/03_stylesheet.html @@ -0,0 +1,52 @@ + + + + + + + 4-4_svg-03_stylesheet.html + + + + + + +
+

SVG

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-5_media_query/01_media_query.html b/juyoung/week1/chapter_4_interactive/4-5_media_query/01_media_query.html new file mode 100644 index 0000000..6c5d363 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-5_media_query/01_media_query.html @@ -0,0 +1,53 @@ + + + + + + + 4-5_media_query-01_media_query.html + + + + + + +
+

Media Query

+
+

Media Query Examples

+ +
+

Lorem ipsum media_min_1025

+
+ +
+

Lorem ipsum media_max_1024

+
+ +
+

Lorem ipsum orientation_landscape

+
+ +
+

Lorem ipsum media_min_640_and_max_1024

+
+ +
+

Lorem ipsum media_min_640_and_max_1024_level4

+
+ +
+

Lorem ipsum media_print

+
+ +
+

Lorem ipsum prefers_scheme_dark

+
+ +
+

Lorem ipsum prefers_reduced_motion

+
+
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/4-5_media_query/02_supports.html b/juyoung/week1/chapter_4_interactive/4-5_media_query/02_supports.html new file mode 100644 index 0000000..e174b84 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/4-5_media_query/02_supports.html @@ -0,0 +1,29 @@ + + + + + + + 4-5_media_query-02_supports.html + + + + + + +
+

Supports

+
+ + + + ๋‹ฌ๊ฑ€ + + +
+ + progress : 20% +
+
+ + diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-1_interactive/01_interactive.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-1_interactive/01_interactive.css new file mode 100644 index 0000000..d081175 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-1_interactive/01_interactive.css @@ -0,0 +1,90 @@ +@charset "utf-8"; + +:root { + --duration: 800ms; + --delay: 300ms; + --bezier: cubic-bezier(0.25, 0.1, 0.27, 0.54); +} + +main { + width: 1400px; + margin: 30px auto; +} + +.container { + margin: 50px auto 0; + padding: 50px; + background-color: gray; +} + +.image_wrap { + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + position: relative; + width: 400px; + height: 500px; + margin: 0 auto; + background: url('../../../img/unsplash/kid.jpg') no-repeat 50% bottom / cover; + border: 2px solid seashell; + overflow: hidden; + transition: background-position var(--duration); +} + +.image_wrap::before { + content: ''; + position: absolute; + left: 0; + top: 0; + z-index: 1; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.4); + transform: translateY(100%); + transition: transform var(--duration); + transition-timing-function: var(--bezier); +} + +.image_wrap .texts { + position: relative; + z-index: 2; + padding: 50px 20px 50px 50px; + text-align: right; +} + +.image_wrap .title { + display: block; + font-size: 30px; + color: aliceblue; + text-transform: uppercase; + opacity: 0; + transition: opacity var(--duration); +} + +.image_wrap .details { + margin-top: 20px; + font-size: 18px; + word-break: keep-all; + line-height: 1.4; + color: white; + text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.2); + text-transform: uppercase; + opacity: 0; + transition: opacity var(--duration); + transition-delay: var(--delay); +} + +/* hover */ +.image_wrap:hover { + background-position: 100% bottom; +} + +.image_wrap:hover::before { + transform: translateY(0); +} + +.image_wrap:hover .title, +.image_wrap:hover .details { + opacity: 1; +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/01_variables.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/01_variables.css new file mode 100644 index 0000000..b7650b0 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/01_variables.css @@ -0,0 +1,38 @@ +@charset "utf-8"; + +:root { + --bg-color: #e8fff4; + --text-color: #3a31ee; + --border-color: #2ac0b3; + + --padding-size-10: 10px; + --padding-size-20: 20px; + --padding-size-30: 30px; + + --margin-size-10: 10px; + --margin-size-20: 20px; + --margin-size-30: 30px; + --margin-size-40: 40px; + --margin-size-50: 50px; +} + +body { + background-color: var(--bg-color); + color: var(--text-color2, black); +} + +.container { + max-width: 1024px; + margin: var(--margin-size-50) auto; + padding: var(--padding-size-30); + border: 3px solid var(--border-color); + color: var(--text-color); +} + +.container * { + margin: var(--padding-size-10); +} + +.container p { + color: var(--text-color2, red); +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/02_opacity.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/02_opacity.css new file mode 100644 index 0000000..6b608e9 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/02_opacity.css @@ -0,0 +1,47 @@ +@charset "utf-8"; + +:root { + --bg-color: #e8fff4; + --text-color: #3a31ee; + --border-color: #2ac0b3; + --duration: 2s; +} + +@property --custom-opacity { + syntax: ''; + initial-value: 0; + inherits: false; +} + +@property --custom-visibility { + syntax: 'visible | hidden'; + initial-value: hidden; + inherits: false; +} + +body { + background-color: var(--bg-color); +} + +.container { + max-width: 1024px; + margin: 30px auto; + padding: 50px; + border: 3px solid var(--border-color); + color: var(--text-color); + transition: + opacity var(--duration), + visibility var(--duration); + opacity: var(--custom-opacity); + visibility: var(--custom-visibility); +} + +.heading_1:hover + .container { + --custom-opacity: 1; + --custom-visibility: visible; +} + +.container p { + padding: 15px 0; + line-height: 1.8; +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/03_transition.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/03_transition.css new file mode 100644 index 0000000..31d1b8f --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-2_fade/03_transition.css @@ -0,0 +1,122 @@ +@charset "utf-8"; + +:root { + --bg-color: #e8fff4; + --border-color: #2ac0b3; + --duration: 1.4s; + --box-width: 80px; + --box-height: 40px; + --box-color: #ffe560; + --heading2-size: 26px; + --heading3-size: 22px; +} + +body { + background-color: var(--bg-color); +} + +.container { + max-width: 1024px; + margin: 30px auto; + padding: 50px; + border: 3px solid var(--border-color); +} + +.container h2 { + margin-bottom: 10px; + font-size: var(--heading2-size); +} + +.container h3 { + font-size: var(--heading3-size); +} + +.container article { + margin-bottom: 20px; + border: 2px solid var(--border-color); +} + +.container article span { + display: flex; + align-items: center; + justify-content: center; + width: var(--box-width); + height: var(--box-height); + margin: 20px; + background-color: var(--box-color); + border: 1px solid var(--border-color); +} + +.container .head { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 20px 0; +} + +.container .head button { + cursor: pointer; + width: 80px; + height: 30px; + background-color: sandybrown; + color: #fff; + text-align: center; +} + +.container .body { + display: flex; + align-items: center; +} + +.ease { + transition-timing-function: ease; +} + +.ease-in { + transition-timing-function: ease-in; +} + +.ease-out { + transition-timing-function: ease-out; +} + +.cubic { + transition-timing-function: cubic-bezier(0.91, 0.45, 0.14, 0.69); +} + +[data-transition] { + transition-duration: var(--duration); + transition-property: all; +} + +.opacity [data-transition] { + opacity: 0; +} + +.translate [data-transition] { + transform: translateX(0); +} + +.rotate [data-transition] { + transform: rotateY(0); +} + +.scale [data-transition] { + transform: scale(0.7); +} + +.opacity.active [data-transition] { + opacity: 1; +} + +.translate.active [data-transition] { + transform: translateX(100%); +} + +.rotate.active [data-transition] { + transform: rotateY(180deg); +} + +.scale.active [data-transition] { + transform: scale(1.3); +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/01_hover_focus_active.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/01_hover_focus_active.css new file mode 100644 index 0000000..f132e10 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/01_hover_focus_active.css @@ -0,0 +1,62 @@ +@charset "utf-8"; + +:root { + --bg-color: #e8fff4; + --text-color: #3a31ee; + --border-color: #2ac0b3; + --duration: 700ms; + --hover-color: white; + --hover-bg-color: rgb(133, 154, 144); + --focus-color: rgb(255, 225, 170); + --focus-bg-color: rgb(14, 115, 255); + --active-color: rgb(72, 246, 52); + --active-bg-color: rgb(148, 55, 255); +} + +body { + background-color: var(--bg-color); +} + +.container { + display: flex; + align-items: center; + justify-content: space-between; + max-width: 1024px; + margin: 50px auto; + padding: 30px; + border: 3px solid var(--border-color); + color: var(--text-color); +} + +.container li { + width: 100px; + height: 100px; + border: 2px solid var(--border-color); +} + +.container li button { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + background-color: transparent; + transition: + background-color var(--duration), + color var(--duration); +} + +.container li[data-type='hover'] button:hover { + color: var(--hover-color); + background-color: var(--hover-bg-color); +} + +.container li[data-type='focus'] button:focus { + color: var(--focus-color); + background-color: var(--focus-bg-color); +} + +.container li[data-type='active'] button:active { + color: var(--active-color); + background-color: var(--active-bg-color); +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/02_transform.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/02_transform.css new file mode 100644 index 0000000..a741e2d --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/02_transform.css @@ -0,0 +1,111 @@ +@charset "utf-8"; + +:root { + --bg-color: #e8fff4; + --text-color: #3a31ee; + --duration: 700ms; + --delay: 300ms; + --card-back-bg: #333; + --timing-function: cubic-bezier(0.275, 0.785, 0.34, 1.375); +} + +body { + background-color: var(--bg-color); +} + +.container { + display: flex; + align-items: center; + gap: 30px; + max-width: 1024px; + margin: 50px auto; + padding: 30px; + color: var(--text-color); +} + +.card { + flex: 1 1 150px; + height: 240px; + perspective: 1000px; + cursor: pointer; +} + +.card_inner { + display: block; + position: relative; + width: 100%; + height: 100%; + transform-style: preserve-3d; + transition: transform var(--duration) var(--delay); +} + +.card:hover .card_inner { + transform: rotateY(180deg); +} + +.card_front, +.card_back { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + padding: 25px 30px; + border: 1px solid #ccc; + backface-visibility: hidden; +} + +.card_front { + background-position: center center; + background-size: cover; +} + +.card:nth-of-type(1) .card_front { + background-image: url(../../../img/unsplash/item_05.jpg); + filter: sepia(0.8); +} + +.card:nth-of-type(2) .card_front { + background-image: url(../../../img/unsplash/item_06.jpg); + filter: grayscale(0.3); +} + +.card:nth-of-type(3) .card_front { + background-image: url(../../../img/unsplash/item_07.jpg); + filter: blur(1px); +} + +.card_back { + flex-direction: column; + background-color: var(--card-back-bg); + transform: rotateY(180deg); +} + +.title { + display: block; + font-size: 30px; +} + +.desc { + margin-top: 20px; + font-size: 13px; + line-height: 1.4; + color: #fff; +} + +.text_shadow_neon { + color: #fff; + background-color: var(--card-back-bg); + text-shadow: + 0 0 5px #fff, + 0 0 10px #fff, + 0 0 15px #fff, + 0 0 20px #49ff18, + 0 0 30px #49ff18, + 0 0 40px #49ff18, + 0 0 55px #49ff18, + 0 0 75px #49ff18; +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/03_animation.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/03_animation.css new file mode 100644 index 0000000..dc8de8b --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-3_card/03_animation.css @@ -0,0 +1,95 @@ +@charset "utf-8"; + +:root { + --bg-color: #e8fff4; + --duration: 10s; + --carousel-width: 240px; + --carousel-height: 140px; + --carousel-translate-z: 400px; + --carousel-rotate-deg: 40deg; +} + +body { + background-color: var(--bg-color); +} + +.container { + max-width: 1024px; + margin: 50px auto; + padding: 30px; + color: var(--text-color); + text-align: center; +} + +/* CSS Nesting */ +.carousel_wrap { + position: relative; + width: var(--carousel-width); + height: var(--carousel-height); + margin: 0 auto; + perspective: 1000px; + .carousel { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + animation: carousel var(--duration) infinite linear; + transform-style: preserve-3d; + &:hover { + animation-play-state: paused; + } + .item { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + &:nth-of-type(1) { + transform: rotateY(0deg) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(2) { + transform: rotateY(var(--carousel-rotate-deg)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(3) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 2)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(4) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 3)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(5) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 4)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(6) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 5)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(7) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 6)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(8) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 7)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(9) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 8)) translateZ(var(--carousel-translate-z)); + } + &:nth-of-type(10) { + transform: rotateY(calc(var(--carousel-rotate-deg) * 9)) translateZ(var(--carousel-translate-z)); + } + .img { + transition: transform 0.3s ease-out; + &:hover { + transform: scale(1.5); + } + } + } + } +} + +@keyframes carousel { + from { + transform: rotateY(0deg); + } + to { + transform: rotateY(360deg); + } +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/01_basic.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/01_basic.css new file mode 100644 index 0000000..53146c4 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/01_basic.css @@ -0,0 +1,6 @@ +@charset "utf-8"; + +.svg_wrap { + max-width: 420px; + margin: 50px auto; +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/02_animate.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/02_animate.css new file mode 100644 index 0000000..002a394 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/02_animate.css @@ -0,0 +1,10 @@ +@charset "utf-8"; + +.svg_wrap { + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + max-width: 800px; + margin: 50px auto; +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/03_stylesheet.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/03_stylesheet.css new file mode 100644 index 0000000..dd0676f --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-4_svg/03_stylesheet.css @@ -0,0 +1,129 @@ +@charset "utf-8"; + +.svg_wrap { + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + max-width: 600px; + margin: 50px auto; +} + +/* circle animation */ +@keyframes circleAnimation { + from { + r: 10; + cx: 20; + } + to { + r: 30; + cx: 60; + } +} + +.animateCircle { + animation: circleAnimation 2s infinite alternate; +} + +/* rect animation */ +@keyframes rectAnimation { + from { + transform: rotate(0deg); + fill: red; + } + to { + transform: rotate(360deg); + fill: blue; + } +} + +.animateRect { + transform-origin: center; + animation: rectAnimation 2s infinite alternate-reverse ease-in; +} + +/* linear gradient */ +@keyframes startGradientAnimation { + 0% { + stop-color: red; + } + 50% { + stop-color: yellow; + } + 100% { + stop-color: red; + } +} + +@keyframes endGradientAnimation { + 0% { + stop-color: blue; + } + 50% { + stop-color: green; + } + 100% { + stop-color: blue; + } +} + +@keyframes rotate { + 0% { + transform: rotate(0) scale(0); + } + 100% { + transform: rotate(360deg) scale(0.8); + } +} + +.start { + animation: startGradientAnimation 3s infinite; +} + +.end { + animation: endGradientAnimation 3s infinite; +} + +.gradient_polygon { + transform-origin: center; + transform-box: fill-box; + animation: rotate 2s infinite alternate cubic-bezier(0.63, 0.26, 0.21, 0.72); +} + +/* mask animation */ +@keyframes maskAnimation { + 0% { + r: 20; + } + 50% { + r: 80; + } + 100% { + r: 20; + } +} + +.animateMask { + animation: maskAnimation 2s infinite; +} + +/* path animation */ +@keyframes lineAnimation { + to { + stroke-dashoffset: 0; + } +} + +.triangle { + width: 185px; + height: 165px; +} + +.triangle path { + stroke-width: 2; + fill: transparent; + stroke: black; + stroke-dasharray: 542; + stroke-dashoffset: 542; + animation: lineAnimation 3s cubic-bezier(0.63, 0.26, 0.21, 0.22) forwards infinite alternate; +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-5_media_query/01_media_query.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-5_media_query/01_media_query.css new file mode 100644 index 0000000..e25c4b1 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-5_media_query/01_media_query.css @@ -0,0 +1,119 @@ +@charset "utf-8"; + +.main { + max-width: 1024px; + margin: 0 auto; +} + +.media_query { + margin-top: 30px; + padding: 30px; + background-color: rgb(175, 232, 255); +} + +.media_query article { + padding: 20px; +} + +/* min-width: 1025px */ +.media_min_1025 { + font-size: 15px; + color: blue; +} + +@media screen and (min-width: 1025px) { + .media_min_1025 { + font-size: 30px; + color: red; + } +} + +/* max-width: 1025px */ +.media_max_1024 { + background-color: red; + color: #fff; +} + +@media screen and (max-width: 1024px) { + .media_max_1024 { + background-color: blue; + } +} + +/* orientation_landscape */ +.orientation_landscape { + background-color: purple; + color: #fff; +} + +@media screen and (orientation: landscape) { + .orientation_landscape { + background-color: salmon; + } +} + +/* min-width: 640px and max-width: 1024px */ +.media_min_640_and_max_1024 { + background-color: slateblue; + color: #fff; +} + +@media (min-width: 640px) and (max-width: 1024px) { + .media_min_640_and_max_1024 { + background-color: violet; + } +} + +/* min-width: 640px and max-width: 1024px */ +.media_min_640_and_max_1024_level4 { + background-color: slateblue; + color: #fff; +} + +@media (640px <= width <= 1024px) { + .media_min_640_and_max_1024_level4 { + background-color: violet; + } +} + +/* print */ +.media_print { + color: red; + font-size: 30px; +} + +@media print { + article { + display: none; + } + .media_print { + display: block; + color: blue; + font-size: 80px; + } +} + +/* prefers-color-scheme: dark */ +.prefers_scheme_dark { + color: red; + background: white; +} + +@media all and (prefers-color-scheme: dark) { + .prefers_scheme_dark { + color: #fff; + background: black; + } +} + +/* prefers-reduced-motion: reduce */ +.prefers_reduced_motion { + transform: rotate(30deg); + transform-origin: 0 0; +} + +@media (prefers-reduced-motion: reduce) { + .prefers_reduced_motion { + transform: none; + } +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-5_media_query/02_supports.css b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-5_media_query/02_supports.css new file mode 100644 index 0000000..b6fc189 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/chapter_4/4-5_media_query/02_supports.css @@ -0,0 +1,52 @@ +@charset "utf-8"; + +.main { + max-width: 1024px; + margin: 0 auto; +} + +.supports { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 30px; + margin-top: 30px; + background-color: rgb(175, 232, 255); +} + +/* webp */ +.webp { + width: 200px; + height: 200px; + margin: 30px; + background-size: cover; + background-image: url('../../../img/unsplash/item_05.jpg'); +} + +@supports (background-image: image-set(url('../../../img/sample.webp') 1x)) { + .webp { + background-image: image-set(url('../../../img/sample.webp') 1x); + } +} + +/* progress -webkit-, -moz- */ +progress { + width: 300px; + height: 10px; +} + +@supports (-webkit-appearance: progress-bar) { + ::-webkit-progress-bar { + background-color: red; + } + ::-webkit-progress-value { + background-color: blue; + } +} + +@supports (-moz-appearance: progress-bar) { + progress { + background-color: black; + } +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/common.css b/juyoung/week1/chapter_4_interactive/public/css/common.css new file mode 100644 index 0000000..8d965a3 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/common.css @@ -0,0 +1,24 @@ +@charset "utf-8"; + +@layer base { + .sr-only { + position: absolute; + overflow: hidden; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + border: 0; + clip: rect(0, 0, 0, 0); + } + + h1 { + font-size: 30px; + } + + .heading_1 { + margin-top: 50px; + text-align: center; + font-weight: bold; + } +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/icons.css b/juyoung/week1/chapter_4_interactive/public/css/icons.css new file mode 100644 index 0000000..ec66ce7 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/icons.css @@ -0,0 +1,23 @@ +@charset "utf-8"; + +@layer base { + .icn { + display: block; + width: 1.4em; + height: 1.4em; + background-size: cover; + background-position: 0 0; + } + + .icn_mail { + background-image: url('../img/freesvg/icn_mail.svg'); + } + + .icn_eye { + background-image: url('../img/freesvg/icn_eye_open.svg'); + } + + .icn_eye_close { + background-image: url('../img/freesvg/icn_eye_close.svg'); + } +} diff --git a/juyoung/week1/chapter_4_interactive/public/css/reset.css b/juyoung/week1/chapter_4_interactive/public/css/reset.css new file mode 100644 index 0000000..a16b546 --- /dev/null +++ b/juyoung/week1/chapter_4_interactive/public/css/reset.css @@ -0,0 +1,117 @@ +@charset "utf-8"; +@layer base { + /*** + The new CSS reset - version 1.11.2 (last updated 15.11.2023) + GitHub page: https://github.com/elad2412/the-new-css-reset + ***/ + + /* + Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property + - The "symbol *" part is to solve Firefox SVG sprite bug + - The "html" element is excluded, otherwise a bug in Chrome breaks the CSS hyphens property (https://github.com/elad2412/the-new-css-reset/issues/36) + */ + *:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) { + all: unset; + display: revert; + } + + /* Preferred box-sizing value */ + *, + *::before, + *::after { + box-sizing: border-box; + } + + /* Fix mobile Safari increase font-size on landscape mode */ + html { + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; + } + + /* Reapply the pointer cursor for anchor tags */ + a, + button { + cursor: revert; + } + + /* Remove list styles (bullets/numbers) */ + ol, + ul, + menu, + summary { + list-style: none; + } + + /* For images to not be able to exceed their container */ + img { + max-inline-size: 100%; + max-block-size: 100%; + } + + /* removes spacing between cells in tables */ + table { + border-collapse: collapse; + } + + /* Safari - solving issue when using user-select:none on the text input doesn't working */ + input, + textarea { + -webkit-user-select: auto; + } + + /* revert the 'white-space' property for textarea elements on Safari */ + textarea { + white-space: revert; + } + + /* minimum style to allow to style meter element */ + meter { + -webkit-appearance: revert; + appearance: revert; + } + + /* preformatted text - use only for this feature */ + :where(pre) { + all: revert; + box-sizing: border-box; + } + + /* reset default text opacity of input placeholder */ + ::placeholder { + color: unset; + } + + /* fix the feature of 'hidden' attribute. + display:revert; revert to element instead of attribute */ + :where([hidden]) { + display: none; + } + + /* revert for bug in Chromium browsers + - fix for the content editable attribute will work properly. + - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/ + :where([contenteditable]:not([contenteditable='false'])) { + -moz-user-modify: read-write; + -webkit-user-modify: read-write; + overflow-wrap: break-word; + -webkit-line-break: after-white-space; + -webkit-user-select: auto; + } + + /* apply back the draggable feature - exist only in Chromium and Safari */ + :where([draggable='true']) { + -webkit-user-drag: element; + } + + /* Revert Modal native behavior */ + :where(dialog:modal) { + all: revert; + box-sizing: border-box; + } + + /* Remove details summary webkit styles */ + ::-webkit-details-marker { + display: none; + } +} diff --git a/juyoung/week1/chapter_4_interactive/public/img/apple.jpeg b/juyoung/week1/chapter_4_interactive/public/img/apple.jpeg new file mode 100644 index 0000000..b7402fd Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/apple.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/egg.jpeg b/juyoung/week1/chapter_4_interactive/public/img/egg.jpeg new file mode 100644 index 0000000..dd26a56 Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/egg.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/grape.jpeg b/juyoung/week1/chapter_4_interactive/public/img/grape.jpeg new file mode 100644 index 0000000..8f6a3e5 Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/grape.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/grapefruit.jpeg b/juyoung/week1/chapter_4_interactive/public/img/grapefruit.jpeg new file mode 100644 index 0000000..7a444b5 Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/grapefruit.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/melon.jpeg b/juyoung/week1/chapter_4_interactive/public/img/melon.jpeg new file mode 100644 index 0000000..5d3b50a Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/melon.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/milk.jpeg b/juyoung/week1/chapter_4_interactive/public/img/milk.jpeg new file mode 100644 index 0000000..6eb306a Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/milk.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/orange.jpeg b/juyoung/week1/chapter_4_interactive/public/img/orange.jpeg new file mode 100644 index 0000000..361dde7 Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/orange.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/potato.jpeg b/juyoung/week1/chapter_4_interactive/public/img/potato.jpeg new file mode 100644 index 0000000..43b64a1 Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/potato.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/pumkin.jpeg b/juyoung/week1/chapter_4_interactive/public/img/pumkin.jpeg new file mode 100644 index 0000000..e1233a7 Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/pumkin.jpeg differ diff --git a/juyoung/week1/chapter_4_interactive/public/img/watermelon.jpeg b/juyoung/week1/chapter_4_interactive/public/img/watermelon.jpeg new file mode 100644 index 0000000..330aca3 Binary files /dev/null and b/juyoung/week1/chapter_4_interactive/public/img/watermelon.jpeg differ diff --git a/juyoung/week2/chapter_5_javascript/5-1_javascript/01_javascript.html b/juyoung/week2/chapter_5_javascript/5-1_javascript/01_javascript.html new file mode 100644 index 0000000..5c57ef6 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-1_javascript/01_javascript.html @@ -0,0 +1,58 @@ + + + + + + + 5-1_javascript-01_javascript.html + + + + + + +
+

JavaScript

+
+

JavaScript ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

+
+

JavaScript ์ด์•ผ๊ธฐ

+

+ JavaScript์™€ Java๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ด๋ฉฐ, ๊ฐ๊ฐ์˜ ์–ธ์–ด๋Š” ํŠน์ •ํ•œ ๋ชฉ์ ๊ณผ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
+ ๋‘ ์–ธ์–ด์˜ ์ด๋ฆ„์ด ๋น„์Šทํ•œ ๊ฒƒ์€ ๋งˆ์ผ€ํŒ… ์ „๋žต์˜ ์ผํ™˜์ด์—ˆ์œผ๋ฉฐ, ์‹ค์ œ๋กœ๋Š” ์„œ๋กœ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. +

+
+
+

Inline JavaScript ์‚ฌ์šฉํ•˜๊ธฐ

+

+ Inline JavaScript๋Š” HTML ์š”์†Œ ๋‚ด์— ์ง์ ‘ JavaScript๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
+ ์ฝ”๋“œ ์–‘์„ ์ ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜๋Š” ์žˆ๋Š”๋ฐ, HTML๊ณผ JavaScript ์ฝ”๋“œ๊ฐ€ ํ˜ผ์žฌํ•˜์—ฌ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€ ๋ณด์ˆ˜์— ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
+ ์•„๋ž˜ type์ด button์ธ button ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๊ฒŒ ๋˜๋ฉด onclick์œผ๋กœ ์—ฐ๊ฒฐ๋œ alert ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๊ฒŒ ๋˜๊ณ , ์‹œ์Šคํ…œ ๋Œ€ํ™”์ƒ์ž๋กœ "ํด๋ฆญํ–ˆ์–ด์š”?"๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +

+ +
+
+

Internal JavaScript ์‚ฌ์šฉํ•˜๊ธฐ

+

+ Internal JavaScript๋Š” HTML ํŒŒ์ผ ๋‚ด๋ถ€์—์„œ script ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ JavaScript ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
+ head ์š”์†Œ ๋˜๋Š” body ์š”์†Œ ๋‚ด๋ถ€์— ์œ„์น˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ฃผ๋กœ HTML DOM Tree๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ๋‚œ ํ›„์— ์ ์šฉ๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ body ์š”์†Œ ๋‹ซ๊ธฐ ์ง์ „์— ์ž‘์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +
+ ์ด ๋ฐฉ๋ฒ•๋„ ์œ ์ง€๋ณด์ˆ˜์™€ ๊ฐ€๋…์„ฑ์— ์ทจ์•ฝํ•˜๋ฏ€๋กœ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +

+ +
+
+

External JavaScript ์‚ฌ์šฉํ•˜๊ธฐ

+

External JavaScript๋Š” JavaScript ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  HTML ํŒŒ์ผ์—์„œ ์ด๋ฅผ ๋กœ๋“œํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ๊ฐ€์žฅ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์ด๋ฉฐ, ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.

+ +
+
+
+ + + + diff --git a/juyoung/week2/chapter_5_javascript/5-2_javascript_env/01_eslint_prettier.html b/juyoung/week2/chapter_5_javascript/5-2_javascript_env/01_eslint_prettier.html new file mode 100644 index 0000000..e4f135d --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-2_javascript_env/01_eslint_prettier.html @@ -0,0 +1,19 @@ + + + + + + + 5-1_javascript_env-01_eslint_prettier.html + + + + + + + +
+

ESLint, Prettier

+
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-3_dom/01_dom.html b/juyoung/week2/chapter_5_javascript/5-3_dom/01_dom.html new file mode 100644 index 0000000..477f843 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-3_dom/01_dom.html @@ -0,0 +1,100 @@ + + + + + + + 5-3_dom-01_dom.html + + + + + + + +
+

DOM API

+
+

getElement

+ + + +
document.getElementsByClassName
+ document.getElementsByClassName + +

document.getElementsByTagName

+

document.getElementsByTagName

+
+
+

querySelector

+ + + +
document.querySelectorAll
+ document.querySelectorAll +

document.querySelectorAll

+
+
+

๋…ธ๋“œ ์กฐ์ž‘

+
๋…ธ๋“œ ์ƒ์„ฑ ํ›„ ์ถ”๊ฐ€
+
์ž์‹ ๋…ธ๋“œ ์ถ”๊ฐ€
+
+ ์ž์‹ ๋…ธ๋“œ ์‚ญ์ œ + ์ž์‹ ๋…ธ๋“œ +
+
์†์„ฑ ์ œ๊ฑฐ
+
ํ…์ŠคํŠธ ๋…ธ๋“œ ์ƒ์„ฑ
+
๋…ธ๋“œ ๋ณต์‚ฌํ•ด์„œ ์ถ”๊ฐ€
+
+
+

๋‹ค๋ฅธ ๋…ธ๋“œ์— ์ ‘๊ทผํ•˜๊ธฐ

+ +
+ parentNode +
+ childNode +
childNode childNode
+
+
+ +
+
current
+
+ +
+
firstChild/firstElementChild
+
middle
+
lastChild/lastElementChild
+
+
+
+

ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ์กฐ์ž‘

+ +
+
+ innerText๋ž€ ๋ฌด์—‡์ธ๊ฐ€? +
+
+ +
+
+ innerHTML๋ž€ ๋ฌด์—‡์ธ๊ฐ€? +
+
+ +
+
+ textContent๋ž€ ๋ฌด์—‡์ธ๊ฐ€? +
+
+
+
+

์š”์†Œ์˜ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฉ”์„œ๋“œ

+ +
์ด ์š”์†Œ์˜ ์œ„์น˜๋Š”?
+ +
์ด ์š”์†Œ์˜ ํฌ๊ธฐ๋Š”?
+
+
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-4_event/01_mouse.html b/juyoung/week2/chapter_5_javascript/5-4_event/01_mouse.html new file mode 100644 index 0000000..09cb45d --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-4_event/01_mouse.html @@ -0,0 +1,32 @@ + + + + + + + 5-4_event-01_mouse.html + + + + + + + +
+

Mouse Event

+
+ + +
+ + +

* ์šฐ์ธก ๋งˆ์šฐ์Šค๋ฅผ ๋ˆŒ๋Ÿฌ์„œ ์ดˆ๊ธฐํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

+
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-4_event/02_keyboard.html b/juyoung/week2/chapter_5_javascript/5-4_event/02_keyboard.html new file mode 100644 index 0000000..c7bfe72 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-4_event/02_keyboard.html @@ -0,0 +1,44 @@ + + + + + + + 5-4_event-02_keyboard.html + + + + + + + + +
+

Keyboard Event

+

-

+
+

KeyDown

+
+ +
+ +
+
+

KeyPress

+
+ +
+
+
+

KeyUp

+
+ +
+
+ +
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-4_event/03_scroll.html b/juyoung/week2/chapter_5_javascript/5-4_event/03_scroll.html new file mode 100644 index 0000000..5f90366 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-4_event/03_scroll.html @@ -0,0 +1,33 @@ + + + + + + + 5-4_event-03_scroll.html + + + + + + + +
+

Scroll Event Example

+
+
Scroll Item
+
Scroll Item
+
Scroll Item
+
+ +
+ +

IntersectionObserver API Example

+
+
Intersection Item
+
Intersection Item
+
Intersection Item
+
+
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-5_function/01_function.html b/juyoung/week2/chapter_5_javascript/5-5_function/01_function.html new file mode 100644 index 0000000..017d9b5 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-5_function/01_function.html @@ -0,0 +1,49 @@ + + + + + + + 5-5_function-01_function.html + + + + + + + +
+

Function

+
+

ํ•จ์ˆ˜์˜ ์žฌ์‚ฌ์šฉ์„ฑ - form ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(form validation)

+
+ + + +
+
+
+

ํ•จ์ˆ˜์˜ ๊ฐ€๋…์„ฑ - ๋‚ ์งœ์™€ ์‹œ๊ฐ„ ํ‘œ์‹œ

+
+ +
+
+

ํ•จ์ˆ˜์˜ ๋ชจ๋“ˆ์„ฑ - ์„ธ๊ธˆ ๋ฐ˜์˜๋œ ์ƒํ’ˆ ๊ณ„์‚ฐ

+

10๊ฐœ ์ด์ƒ ๊ตฌ๋งค์‹œ ํ• ์ธ์œจ 20%

+

์„ธ๊ธˆ 8%

+

๊ฐ 1,200์›

+
+ +
+
+

ํ•จ์ˆ˜์˜ ์œ ์ง€๋ณด์ˆ˜์„ฑ - ์‚ฌ์šฉ์ž ์ •๋ณด ์—…๋ฐ์ดํŠธ

+
+ +
+
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-5_function/02_expression.html b/juyoung/week2/chapter_5_javascript/5-5_function/02_expression.html new file mode 100644 index 0000000..7b9d545 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-5_function/02_expression.html @@ -0,0 +1,49 @@ + + + + + + + 5-5_function-02_expression.html + + + + + + + +
+

Function

+
+

ํ•จ์ˆ˜์˜ ์žฌ์‚ฌ์šฉ์„ฑ - form ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(form validation)

+
+ + + +
+
+
+

ํ•จ์ˆ˜์˜ ๊ฐ€๋…์„ฑ - ๋‚ ์งœ์™€ ์‹œ๊ฐ„ ํ‘œ์‹œ

+
+ +
+
+

ํ•จ์ˆ˜์˜ ๋ชจ๋“ˆ์„ฑ - ์„ธ๊ธˆ ๋ฐ˜์˜๋œ ์ƒํ’ˆ ๊ณ„์‚ฐ

+

10๊ฐœ ์ด์ƒ ๊ตฌ๋งค์‹œ ํ• ์ธ์œจ 20%

+

์„ธ๊ธˆ 8%

+

๊ฐ 1,200์›

+
+ +
+
+

ํ•จ์ˆ˜์˜ ์œ ์ง€๋ณด์ˆ˜์„ฑ - ์‚ฌ์šฉ์ž ์ •๋ณด ์—…๋ฐ์ดํŠธ

+
+ +
+
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-6_async/01_sync_async.html b/juyoung/week2/chapter_5_javascript/5-6_async/01_sync_async.html new file mode 100644 index 0000000..7564163 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-6_async/01_sync_async.html @@ -0,0 +1,22 @@ + + + + + + + 5-6_async-01_sync_async.html + + + + + + + +
+

Sync & Async

+
+ + +
+ + diff --git a/juyoung/week2/chapter_5_javascript/5-6_async/02_fetch_axios.html b/juyoung/week2/chapter_5_javascript/5-6_async/02_fetch_axios.html new file mode 100644 index 0000000..9fb5c08 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/5-6_async/02_fetch_axios.html @@ -0,0 +1,25 @@ + + + + + + + 5-6_async-02_fetch_axios.html + + + + + + + + +
+

Fetch & Axios

+
+ +
+ + +
+ + diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-1_javascript/01_javascript.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-1_javascript/01_javascript.css new file mode 100644 index 0000000..e10a155 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-1_javascript/01_javascript.css @@ -0,0 +1,38 @@ +@charset "utf-8"; + +.container { + max-width: 1024px; + margin: 30px auto; +} + +.contents { + margin-bottom: 30px; +} + +.contents h3 { + font-size: 30px; + line-height: 1.4; + font-weight: bold; +} + +.contents p { + line-height: 1.6; + font-size: 16px; +} + +.contents button { + width: 100%; + max-width: 200px; + padding: 12px 0; + margin-top: 10px; + background-color: dodgerblue; + color: #fff; + text-align: center; + font-size: 20px; + cursor: pointer; + transition: background-color 0.3s; +} + +.contents button:hover { + background-color: rgb(27, 99, 255); +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-3_dom/01_dom.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-3_dom/01_dom.css new file mode 100644 index 0000000..bef20cd --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-3_dom/01_dom.css @@ -0,0 +1,117 @@ +@charset "utf-8"; + +section { + width: 100%; + max-width: 1024px; + margin: 50px auto 0; + padding: 30px; + background-color: skyblue; + line-height: 1.5; +} + +h2 { + font-size: 24px; +} + +/* getElementsByClassName */ +[data-id='test_data'] { + background-color: gold; +} + +/* getElementsByTagName */ +[data-id='test-color'] { + color: orange; +} + +.test-color { + background-color: #666; +} + +/* querySelector */ +#data-id { + background-color: rgba(255, 22, 192, 70%); +} + +/* querySelectorAll */ +[data-query] { + color: red; +} + +/* ๋…ธ๋“œ ์กฐ์ž‘ */ +.node_manipulation .create_element { + color: blue; +} + +.node_manipulation .color-purple { + color: purple; +} + +/* ๊ทผ์ฒ˜ ๋…ธ๋“œ ์ ‘๊ทผ */ +.node_traversing > div { + position: relative; + padding: 20px; +} + +.node_traversing > div ~ div::before { + content: ''; + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 1px; + background-color: black; +} + +.node_traversing .parent[data-traversing] { + background-color: #ecefef; +} + +.node_traversing .child[data-traversing] { + color: red; +} + +.node_traversing #child_child { + color: blue; +} + +.node_traversing .prev[data-traversing], +.node_traversing .next[data-traversing] { + color: purple; +} + +.node_traversing .first[data-traversing], +.node_traversing .last[data-traversing] { + color: blue; +} + +/* ์š”์†Œ์˜ ์œ„์น˜์™€ ํฌ๊ธฐ */ +.position_width { + position: relative; + width: 500px; + margin-bottom: 300px; + padding: 150px; + border: 5px solid dodgerblue; +} + +.position_width .position { + position: absolute; + right: 10px; + left: 15px; + top: 10px; + padding: 10px; + border: 3px solid dodgerblue; + border-left-width: 5px; + background-color: white; +} + +.position_width .size { + position: absolute; + left: 10px; + right: 35px; + bottom: 10px; + padding: 15px; + border: 1px solid gray; + border-left-width: 10px; + background-color: white; +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/01_mouse.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/01_mouse.css new file mode 100644 index 0000000..3cfd906 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/01_mouse.css @@ -0,0 +1,123 @@ +@charset "utf-8"; + +:root { + --range-track-color: #494a55b5; + --range-thumb-color: #000000b3; + --canvas-border-color: #3a3a3a; + --canvas-bg-color: #fafafa; +} + +main { + width: 100%; + max-width: 1024px; + margin: 50px auto 0; +} + +/* custom input[type="color"] */ +input[type='color'] { + width: 100%; + height: 100%; + border: 0; + padding: 0; + background: none; + cursor: pointer; + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; +} + +input[type='color']::-webkit-color-swatch-wrapper { + padding: 0; +} + +input[type='color']::-webkit-color-swatch { + border: 0; + border-radius: 0; +} + +input[type='color']::-moz-color-swatch, +input[type='color']::-moz-focus-inner { + border: 0; +} + +input[type='color']::-moz-focus-inner { + padding: 0; +} + +/* custom input[type="range"] */ +input[type='range'] { + width: 100%; + height: 100%; + overflow: hidden; + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; +} + +input[type='range']::-webkit-slider-runnable-track { + width: 100%; + height: 100%; + cursor: pointer; + border: 1px solid var(--range-track-color); +} + +input[type='range']::-webkit-slider-thumb { + -webkit-appearance: none; + width: 20%; + min-width: 30px; + height: 100%; + background: var(--range-thumb-color); + cursor: pointer; + box-shadow: -100vw 0 0 100vw var(--range-track-color); +} + +/* styles */ +.options { + display: flex; + gap: 20px; + width: 100%; + margin-top: 10px; +} + +.options > label { + display: flex; + align-items: center; + height: 30px; +} + +.options input { + flex-shrink: 0; + margin-right: 10px; +} + +.options .color_picker input { + width: 40px; +} + +.options .pencil_range input { + width: 150px; +} + +.paint { + margin: 40px 0 10px; + border: 3px solid var(--canvas-border-color); + background-color: var(--canvas-bg-color); +} + +.btn { + display: block; + width: 100px; + height: 50px; + background-color: #3a3a3a; + color: #fafafa; + text-align: center; + cursor: pointer; +} + +.btn:hover { + background-color: #1a1a1a; +} + +p { + margin-top: 10px; +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/02_keyboard.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/02_keyboard.css new file mode 100644 index 0000000..a7d6cf9 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/02_keyboard.css @@ -0,0 +1,61 @@ +@charset "utf-8"; + +:root { + --border-color: #333; +} + +main { + width: 100%; + max-width: 1024px; + margin: 50px auto 0; +} + +.info { + font-size: 3rem; + text-align: center; +} + +.keyboard { + margin-top: 30px; + padding: 20px; + border: 3px solid var(--border-color); +} + +.keyboard h2 { + display: block; + width: 100%; + font-size: 1.2rem; + margin-bottom: 20px; + padding-bottom: 20px; + border-bottom: 3px solid var(--border-color); +} + +.keyboard button { + position: relative; + height: 40px; + margin: 5px; + padding: 10px; + background: #fff; + box-shadow: 0px 1px 1px black; + border-bottom: 2px solid var(--border-color); + border-radius: 3px; + font-size: 1.1rem; +} + +.keyboard button.pressed { + box-shadow: inset 0px 1px 5px black; + border-bottom-color: transparent; +} + +.btn_refresh { + margin-top: 30px; + padding: 10px 20px; + background-color: #fff; + border: 3px solid var(--border-color); + cursor: pointer; +} + +.btn_refresh:hover { + background-color: #333; + color: #fff; +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/03_scroll.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/03_scroll.css new file mode 100644 index 0000000..aea368b --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-4_event/03_scroll.css @@ -0,0 +1,50 @@ +@charset "utf-8"; + +main { + width: 100%; + max-width: 1024px; + margin: 50px auto 0; +} + +h1 { + margin-top: 30px; + color: dodgerblue; +} + +hr { + border-top: 3px dashed dodgerblue; +} + +.big_vertical { + height: 100vh; +} + +.scroll_item, +.intersection_item { + padding: 20px 0; + opacity: 0; + font-size: 3vw; + color: #000; + transition: + opacity 1s, + font-size 1s 0.5s, + color 1s 0.8s; +} + +.scroll_item.animated, +.intersection_item.animated { + opacity: 1; + font-size: 5vw; +} + +.blue { + color: rgba(22, 22, 222); +} + +.purple { + color: rgba(113, 33, 144); +} + +.pink { + color: rgba(223, 33, 144); +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-5_function/01_function.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-5_function/01_function.css new file mode 100644 index 0000000..ab23987 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-5_function/01_function.css @@ -0,0 +1,59 @@ +@charset "utf-8"; + +main { + width: 100%; + max-width: 1024px; + margin: 50px auto 200px; +} + +article { + padding: 30px 0; + border-bottom: 2px solid #cecece; +} + +article:first-of-type { + margin-top: 30px; + border-top: 2px solid #cecece; +} + +h2 { + display: block; + margin-bottom: 20px; + font-size: 1.3rem; + font-weight: bold; +} + +p { + font-size: 0.9rem; + line-height: 1.4; +} + +input { + padding: 10px; + border: 1px solid #cecece; +} + +button { + padding: 10px 20px; + border: 2px dashed #cecece; + font-weight: bold; + cursor: pointer; + transition: + background-color 0.3s, + color 0.3s, + border 0.3s; +} + +button:hover, +button:focus { + background-color: #333333; + border-color: transparent; + color: #ffffff; +} + +.result { + background-color: #ececec; + width: 100%; + margin: 30px 0; + padding: 30px; +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-6_async/01_sync_async.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-6_async/01_sync_async.css new file mode 100644 index 0000000..0230bcc --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-6_async/01_sync_async.css @@ -0,0 +1,32 @@ +@charset "utf-8"; + +main { + width: 100%; + max-width: 1024px; + margin: 50px auto 200px; +} + +button { + padding: 10px 20px; + border: 2px dashed #cecece; + font-weight: bold; + cursor: pointer; + transition: + background-color 0.3s, + color 0.3s, + border 0.3s; +} + +button:hover, +button:focus { + background-color: #333333; + border-color: transparent; + color: #ffffff; +} + +.result { + background-color: #ececec; + width: 100%; + margin: 30px 0; + padding: 30px; +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-6_async/02_fetch_axios.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-6_async/02_fetch_axios.css new file mode 100644 index 0000000..c345b9f --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/5-6_async/02_fetch_axios.css @@ -0,0 +1,68 @@ +@charset "utf-8"; + +main { + width: 100%; + max-width: 1024px; + margin: 50px auto 200px; +} + +button { + padding: 10px 20px; + border: 2px dashed #cecece; + font-weight: bold; + cursor: pointer; + transition: + background-color 0.3s, + color 0.3s, + border 0.3s; +} + +button:hover, +button:focus { + background-color: #333333; + border-color: transparent; + color: #ffffff; +} + +.result { + position: relative; + width: 100%; + min-height: 150px; + margin: 30px 0; + padding: 30px; + background-color: #ececec; +} + +.spinner { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.4); +} + +.spinner::before { + content: ''; + display: block; + position: absolute; + left: 50%; + top: 50%; + width: 50px; + height: 50px; + margin-left: -25px; + margin-top: -25px; + border: 3px solid rgba(0, 0, 0, 0.2); + border-radius: 50%; + border-left-color: rgba(255, 109, 109, 0.6); + animation: spin 0.8s ease-in infinite; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/common.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/common.css new file mode 100644 index 0000000..8d965a3 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/common.css @@ -0,0 +1,24 @@ +@charset "utf-8"; + +@layer base { + .sr-only { + position: absolute; + overflow: hidden; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + border: 0; + clip: rect(0, 0, 0, 0); + } + + h1 { + font-size: 30px; + } + + .heading_1 { + margin-top: 50px; + text-align: center; + font-weight: bold; + } +} diff --git a/juyoung/week2/chapter_5_javascript/public/css/chapter_5/reset.css b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/reset.css new file mode 100644 index 0000000..0fff047 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/css/chapter_5/reset.css @@ -0,0 +1,90 @@ +@charset "utf-8"; +@layer base { + + *:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) { + all: unset; + display: revert; + } + + *, + *::before, + *::after { + box-sizing: border-box; + } + + html { + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; + } + + a, + button { + cursor: revert; + } + + ol, + ul, + menu, + summary { + list-style: none; + } + + img { + max-inline-size: 100%; + max-block-size: 100%; + } + + table { + border-collapse: collapse; + } + + input, + textarea { + -webkit-user-select: auto; + } + + textarea { + white-space: revert; + } + + meter { + -webkit-appearance: revert; + appearance: revert; + } + + :where(pre) { + all: revert; + box-sizing: border-box; + } + + ::placeholder { + color: unset; + } + + + :where([hidden]) { + display: none; + } + + :where([contenteditable]:not([contenteditable='false'])) { + -moz-user-modify: read-write; + -webkit-user-modify: read-write; + overflow-wrap: break-word; + -webkit-line-break: after-white-space; + -webkit-user-select: auto; + } + + :where([draggable='true']) { + -webkit-user-drag: element; + } + + :where(dialog:modal) { + all: revert; + box-sizing: border-box; + } + + ::-webkit-details-marker { + display: none; + } +} diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-1_javascript/01_javascript.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-1_javascript/01_javascript.js new file mode 100644 index 0000000..a3705eb --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-1_javascript/01_javascript.js @@ -0,0 +1,3 @@ +document.querySelector('.js-clickOut').onclick = function () { + alert('js-clickOut ํด๋ž˜์Šค ์„ ํƒ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํด๋ฆญํ–ˆ๋‚˜์š”?'); +}; diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-2_javascript_env/01_eslint_prettier.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-2_javascript_env/01_eslint_prettier.js new file mode 100644 index 0000000..87064d5 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-2_javascript_env/01_eslint_prettier.js @@ -0,0 +1,9 @@ +const test = () => { + console.log('test'); +}; + +const test2 = () => { + test(); +}; + +test2(); diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-3_dom/01_dom.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-3_dom/01_dom.js new file mode 100644 index 0000000..5141644 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-3_dom/01_dom.js @@ -0,0 +1,146 @@ +/** + * ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•˜๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ + */ + +// document.getElementById +document.getElementById('example_id').style.color = 'red'; + +// document.getElementsByClassName - ์ƒ‰์ƒ ๋ณ€๊ฒฝ +document.getElementsByClassName('example_class')[0].style.color = 'blue'; +document.getElementsByClassName('example_class')[1].style.color = 'purple'; + +// document.getElementsByClassName - ์†์„ฑ ์ถ”๊ฐ€ +document.getElementsByClassName('example_class')[1].setAttribute('data-id', 'test_data'); + +// document.getElementsByTagName - ์Šคํƒ€์ผ, ์†์„ฑ, ํด๋ž˜์Šค ์ถ”๊ฐ€ +document.getElementsByTagName('p')[0].style.backgroundColor = 'lightgrey'; +document.getElementsByTagName('p')[1].setAttribute('data-id', 'test-color'); +document.getElementsByTagName('p')[1].classList.add('test-color'); + +// document.querySelector - ์†์„ฑ ๊ฐ’ ์ œ๊ฑฐ +document.querySelector('.test_class').removeAttribute('type'); +document.querySelector('.test_class').setAttribute('id', 'data-id'); + +// document.querySelectorAll - ์†์„ฑ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐฐ์—ด์„ ๊ตฌํ•˜๊ธฐ +// document.querySelectorAll('[data-id="test"]').map(($element) => { +// $element.classList.add('test'); +// }); +[...document.querySelectorAll('[data-id="test"]')].map(($element, index) => { + if (0 === index) { + $element.removeAttribute('data-id'); + $element.setAttribute('data-query', 'test'); + return $element; + } +}); +document.querySelectorAll('[data-id="test"]')[1].setAttribute('data-query', 'test'); + +/** + * ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์กฐ์ž‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ + */ +// document.createElement - span ์š”์†Œ ์ƒ์„ฑ +const $spanTag = document.createElement('span'); +$spanTag.classList.add('color-purple'); +$spanTag.innerText = '์•ˆ๋…•ํ•˜์„ธ์š”.'; +document.querySelector('.node_manipulation .create_element').append($spanTag); + +// appendChild - div ์š”์†Œ ์ƒ์„ฑ ํ•ด์„œ appendChild +const $divTag = document.createElement('div'); +$divTag.innerHTML = '๋„ค, ์•ˆ๋…•ํ•˜์„ธ์š”.'; +document.querySelector('.appendchild').appendChild($divTag); + +// removeChild - ์ž์‹ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œ +const $childTag = document.querySelector('.removechild span'); +document.querySelector('.removechild').removeChild($childTag); + +// removeAttribute - ์†์„ฑ ์ œ๊ฑฐ +document.getElementsByClassName('remove_attribute')[0].removeAttribute('data-id'); + +// createTextNode - ํ…์ŠคํŠธ ๋…ธ๋“œ ์ƒ์„ฑ +const textNode = document.createTextNode('์•ˆ๋…•ํ•˜์‹ญ๋‹ˆ๊นŒ?'); +const $fragment = document.createDocumentFragment(); +$fragment.appendChild(textNode); +document.querySelector('.create_textnode').appendChild($fragment); + +// cloneNode - ๋…ธ๋“œ ๋ณต์‚ฌ +const $originNode = document.querySelector('.clone_node'); +const $copyTag = $originNode.cloneNode(true); +$originNode.appendChild($copyTag); + +/** + * ๊ทผ์ฒ˜ ๋…ธ๋“œ์— ์ ‘๊ทผํ•˜๋Š” ๋ฉ”์„œ๋“œ + */ +// parentNode - ๋ถ€๋ชจ ๋…ธ๋“œ ์ ‘๊ทผํ•˜๊ธฐ +const $childChildElement = document.getElementById('child_child'); +const $parentElement = $childChildElement.parentElement; +const $parentParentElement = $childChildElement.parentNode.parentNode; +$parentElement.setAttribute('data-traversing', 'true'); +$parentParentElement.setAttribute('data-traversing', 'true'); + +// previousSibling/nextSibling, previousElementSibling/nextElementSibling +// ์ด์ „ ๋…ธ๋“œ ๋˜๋Š” ๋‹ค์Œ ๋…ธ๋“œ ์„ ํƒํ•˜๊ธฐ +const $current = document.querySelector('.current'); +console.warn(`previousSibling : `, $current.previousSibling); +console.warn(`previousElementSibling : `, $current.previousElementSibling); +console.warn(`nextSibling : `, $current.nextSibling); +console.warn(`nextElementSibling : `, $current.nextElementSibling); +$current.previousElementSibling.setAttribute('data-traversing', true); +$current.nextElementSibling.setAttribute('data-traversing', true); + +// firstChild/lastChild, firstElementChild/lastElementChild +// ์ฒซ๋ฒˆ์งธ ๋…ธ๋“œ์™€ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ ์„ ํƒํ•˜๊ธฐ +const $first_last = document.querySelector('.first_last'); +console.warn(`firstChild : `, $first_last.firstChild); +console.warn(`lastChild : `, $first_last.lastChild); +$first_last.firstElementChild.style.color = 'red'; +$first_last.lastElementChild.style.color = 'blue'; + +/** + * ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ + */ +const contentsText = `
+ innerText +
`; +const contentsHTML = `
+ innerHTML +
+ `; +const contentsTextContent = `
+ textContent +
`; +document.querySelector('.inner_text div').innerText = contentsText; +document.querySelector('.inner_html div').innerHTML = contentsHTML; +document.querySelector('.text_content div').textContent = contentsTextContent; + +/** + * ์š”์†Œ์˜ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ์•Œ์•„๋‚ด๋Š” ๋ฉ”์„œ๋“œ + */ +// getBoundingClientRect +const $positionWidth = document.querySelector('.position_width'); +const positionWidth = $positionWidth.getBoundingClientRect(); +console.warn(positionWidth); + +// offsetLeft, offsetTop, clientLeft, clientTop +const $jsPosition = $positionWidth.querySelector('.js-position'); +const $temp = document.createElement('div'); +$temp.innerHTML = `
+ ${`$jsPosition.offsetLeft: ${$jsPosition.offsetLeft}, + $jsPosition.offsetTop: ${$jsPosition.offsetTop}`} +
+
+ ${`$jsPosition.clientLeft: ${$jsPosition.clientLeft}, + $jsPosition.clientTop: ${$jsPosition.clientTop}`} +
`; +$jsPosition.appendChild($temp); + +// offsetWidth, offsetHeight, clientWidth, clientHeight +const $jsSize = $positionWidth.querySelector('.js-size'); +const $temp2 = document.createElement('div'); +$temp2.innerHTML = `
+ ${`$jsSize.offsetWidth: ${$jsSize.offsetWidth}, + $jsSize.offsetHeight: ${$jsSize.offsetHeight}`} +
+
+ ${`$jsSize.clientWidth: ${$jsSize.clientWidth}, + $jsSize.clientHeight: ${$jsSize.clientHeight}`} +
`; +$jsSize.appendChild($temp2); diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/01_mouse.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/01_mouse.js new file mode 100644 index 0000000..03e06f4 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/01_mouse.js @@ -0,0 +1,88 @@ +'use strict'; + +const $canvas = document.querySelector('.js-painter'); +const $context = $canvas.getContext('2d'); +const $colorPicker = document.querySelector('.js-colorPicker input'); +const $pencilRange = document.querySelector('.js-pencilRange input'); +const $eraseAll = document.querySelector('.js-eraseAll'); +const mouse = { + isDown: false, + x: 0, + y: 0, +}; +const initialValue = { + color: '#3c3c3c', + width: 10, + lineCap: 'round', +}; + +document.addEventListener('DOMContentLoaded', () => { + const { lineCap, color, width } = initialValue; + $context.lineCap = lineCap; + $context.strokeStyle = color; + $context.lineWidth = width; + $colorPicker.value = color; + $pencilRange.value = width; + $eraseAll.dispatchEvent(new Event('click')); + $colorPicker.dispatchEvent(new Event('change')); + $pencilRange.dispatchEvent(new Event('input')); +}); + +$colorPicker.addEventListener('change', (event) => { + const color = event.target.value; + event.target.parentElement.querySelector('.current_color_picker').innerHTML = color; + $context.strokeStyle = color; +}); + +$pencilRange.addEventListener('input', (event) => { + const width = event.target.value; + event.target.parentElement.querySelector('.current_pencil_range').innerHTML = width + 'px'; + $context.lineWidth = width; +}); + +$canvas.addEventListener('mousedown', (event) => { + mouse.isDown = true; + [mouse.x, mouse.y] = [event.offsetX, event.offsetY]; +}); + +$canvas.addEventListener('mouseup', () => { + mouse.isDown = false; +}); + +$canvas.addEventListener('mouseout', () => { + mouse.isDown = false; +}); + +$canvas.addEventListener('mousemove', (event) => { + if (false === mouse.isDown) { + return; + } + const [drawX, drawY] = [event.offsetX, event.offsetY]; + $context.beginPath(); + $context.moveTo(mouse.x, mouse.y); + $context.lineTo(drawX, drawY); + $context.stroke(); + mouse.x = drawX; + mouse.y = drawY; +}); + +$eraseAll.addEventListener('click', () => { + $context.clearRect(0, 0, $canvas.width, $canvas.height); +}); + +document.addEventListener('contextmenu', (event) => { + event.preventDefault(); + mouse.isDown = false; + if (false === confirm('์ดˆ๊ธฐํ™” ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) { + return; + } + const { lineCap, color, width } = initialValue; + $context.lineCap = lineCap; + $context.strokeStyle = color; + $context.lineWidth = width; + $colorPicker.value = color; + $pencilRange.value = width; + $eraseAll.dispatchEvent(new Event('click')); + $colorPicker.dispatchEvent(new Event('change')); + $pencilRange.dispatchEvent(new Event('input')); +}); diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/02_keyboard.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/02_keyboard.js new file mode 100644 index 0000000..53a708a --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/02_keyboard.js @@ -0,0 +1,68 @@ +'use strict'; + +/** + * DOMContentLoaded - HTML DOM ํŠธ๋ฆฌ๊ฐ€ ๋ Œ๋”๋ง์ด ์™„๋ฃŒ ๋œ ๋‹ค์Œ, ์ถ”๊ฐ€์ ์ธ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค์šด๋กœ๋“œ๋˜๊ณ  ์‹คํ–‰๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + * @see + * https://developer.mozilla.org/ko/docs/Web/API/Document/DOMContentLoaded_event + */ +document.addEventListener('DOMContentLoaded', () => { + const $keyContainers = document.querySelectorAll('.key_container'); + const $info = document.querySelector('.js-info'); + const $refresh = document.querySelector('.js-refresh'); + const keys = ['Q', 'W', 'E', 'R', 'A', 'S', 'D', 'F', 'Z', 'X', 'C', 'V']; + const KEY_COUNT = 4; + + $keyContainers.forEach((container, containerIndex) => { + for (let i = 0; i < KEY_COUNT; i++) { + const keyIndex = containerIndex * KEY_COUNT + i; + if (keyIndex < keys.length) { + const key = keys[keyIndex]; + const $button = document.createElement('button'); + $button.textContent = key; + $button.setAttribute('type', 'button'); + $button.dataset.key = key.toLowerCase(); + container.appendChild($button); + } + } + }); + + document.addEventListener('keydown', (event) => { + const allowKeys = [...document.querySelectorAll('[data-type="keydown"] button')].map((key) => key.dataset.key); + $info.textContent = `type = ${event.type}, key = ${event.key}`; + console.log('KeyDown:', event.key); + if (!allowKeys.includes(event.key)) { + return; + } + const $target = document.querySelector(`[data-key="${event.key}"]`); + $target.classList.add('pressed'); + }); + + // document.addEventListener('keypress', (event) => { + // const allowKeys = [...document.querySelectorAll('[data-type="keypress"] button')].map((key) => key.dataset.key); + // $info.textContent = `type = ${event.type}, key = ${event.key}`; + // console.log('KeyPress:', event.key); + // if (!allowKeys.includes(event.key)) { + // return; + // } + // const $target = document.querySelector(`[data-key="${event.key}"]`); + // $target.classList.toggle('pressed'); + // }); + + document.addEventListener('keyup', (event) => { + const allowKeys = [...document.querySelectorAll('[data-type="keyup"] button')].map((key) => key.dataset.key); + $info.textContent = `type = ${event.type}, key = ${event.key}`; + console.log('KeyUp:', event.key); + if (!allowKeys.includes(event.key)) { + return; + } + const $target = document.querySelector(`[data-key="${event.key}"]`); + $target.classList.add('pressed'); + }); + + $refresh.addEventListener('click', () => { + [...document.querySelectorAll(`[data-key]`)].forEach((key) => { + key.classList.remove('pressed'); + }); + $info.textContent = '-'; + }); +}); diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/03_scroll.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/03_scroll.js new file mode 100644 index 0000000..434d06e --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-4_event/03_scroll.js @@ -0,0 +1,42 @@ +'use strict'; + +const COLORS = ['blue', 'purple', 'pink']; + +/** + * Scroll Event + */ +window.addEventListener('scroll', function () { + const $elements = document.querySelectorAll('.scroll_item'); + $elements.forEach(($element, index) => { + const elementPos = $element.getBoundingClientRect(); + console.log('elementPos.top', elementPos.top); + console.log('elementPos.bottom', elementPos.bottom); + console.log('window.innerHeight', window.innerHeight); + + if (elementPos.top < window.innerHeight && elementPos.bottom >= 0) { + $element.classList.add('animated'); + $elements[index].classList.add(COLORS[index]); + } + }); +}); + +/** + * IntersectionObserver API + */ +const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + console.log('intersectionObserver API', entry); + if (entry.isIntersecting) { + entry.target.classList.add('animated'); + entry.target.classList.add(entry.target.dataset.color); + } + }); + }, + { threshold: 0.8 }, +); + +document.querySelectorAll('.intersection_item').forEach(($element, index) => { + $element.dataset.color = COLORS[index]; + observer.observe($element); +}); diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-5_function/01_function.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-5_function/01_function.js new file mode 100644 index 0000000..5659b69 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-5_function/01_function.js @@ -0,0 +1,155 @@ +'use strict'; + +/** + * DOMContentLoaded - HTML DOM ํŠธ๋ฆฌ๊ฐ€ ๋ Œ๋”๋ง์ด ์™„๋ฃŒ ๋œ ๋‹ค์Œ, ์ถ”๊ฐ€์ ์ธ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค์šด๋กœ๋“œ๋˜๊ณ  ์‹คํ–‰๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + * @see + * https://developer.mozilla.org/ko/docs/Web/API/Document/DOMContentLoaded_event + */ +document.addEventListener('DOMContentLoaded', () => { + document.getElementById('login').addEventListener('submit', checkForm); + document.querySelector('.readable .js-dateTime').addEventListener('click', (event) => renderDateTime(event)); + document.querySelector('.modulable .js-calculator').addEventListener('click', renderCalcResult); + + const userInfo = { + name: 'yeongminKim', + email: 'yeongmin@yeongmin.com', + age: 38, + }; + renderUserInfo(userInfo); // ์ดˆ๊ธฐ ์‚ฌ์šฉ์ž ์ •๋ณด ๋ Œ๋”๋ง + document.querySelector('.maintainable .js-update').addEventListener('click', (e) => handleUpdateClick(e, userInfo)); +}); + +/** + * ํ•จ์ˆ˜์˜ ์žฌ์‚ฌ์šฉ์„ฑ - form ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(form validation) + */ +function isValidEmail(email) { + const regex = /\S+@\S+\.com$/; + return regex.test(email); +} + +function isValidPassword(password) { + return 10 <= password.length; +} + +function checkForm(event) { + // ํผ์˜ ๊ธฐ๋ณธ ์ œ์ถœ ๋™์ž‘ ๋ฐฉ์ง€ + event.preventDefault(); + + const $form = event.target; + const $email = $form.querySelector('.form_email input'); + const $password = $form.querySelector('.form_password input'); + + if (false === isValidEmail($email.value)) { + $email.focus(); + alert('์ด๋ฉ”์ผ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.'); + return; + } else if (false === isValidPassword($password.value)) { + $password.focus(); + alert('๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”.'); + return; + } + alert('๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.'); + $form.reset(); + $email.focus(); +} + +/** + * ํ•จ์ˆ˜์˜ ๊ฐ€๋…์„ฑ - ๋‚ ์งœ์™€ ์‹œ๊ฐ„ ํ‘œ์‹œ + */ +function formatDate(date) { + const options = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }; + return date.toLocaleDateString('ko-KR', options); +} + +function formatTime(date) { + const options = { hour: '2-digit', minute: '2-digit' }; + return date.toLocaleTimeString('ko-KR', options); +} + +function renderDateTime(event) { + const $readable = event.target.closest('.readable'); + const $result = $readable.querySelector('.result'); + + if ($result.innerText) { + return; + } + + const now = new Date(); + const $fragment = document.createDocumentFragment(); + const $date = document.createElement('p'); + const $time = document.createElement('p'); + $date.innerHTML = formatDate(now); + $time.innerText = formatTime(now); + $fragment.appendChild($date); + $fragment.appendChild($time); + $result.appendChild($fragment); +} + +/** + * ํ•จ์ˆ˜์˜ ๋ชจ๋“ˆ์„ฑ - ์„ธ๊ธˆ ๋ฐ˜์˜๋œ ์ƒํ’ˆ ๊ณ„์‚ฐ + * 10๊ฐœ ์ด์ƒ ๊ตฌ๋งค์‹œ ํ• ์ธ์œจ 20% + * ์„ธ๊ธˆ 8% + * ๊ฐ 1,200์› + */ +function formatCurrency(number) { + return `${number.toLocaleString()}์›`; +} + +function calcResult(price, discount, tax) { + const quantity = parseInt(prompt('๊ตฌ๋งคํ•  ์ƒํ’ˆ์˜ ์ˆ˜๋Ÿ‰์„ ์ž…๋ ฅํ•˜์„ธ์š”:'), 10); + + if (isNaN(quantity) || quantity <= 0) { + return '์˜ฌ๋ฐ”๋ฅธ ์ˆ˜๋Ÿ‰์„ ์ž…๋ ฅํ•˜์„ธ์š”.'; + } + + let totalPrice = price * quantity; + + if (10 <= quantity) { + totalPrice *= 1 - discount; + } + + totalPrice *= 1 + tax; + + return formatCurrency(Math.round(totalPrice)); +} + +function renderCalcResult(event) { + const $modulable = event.target.closest('.modulable'); + const $result = $modulable.querySelector('.result'); + const price = 1200; + const discount = 0.2; // 20%; + const tax = 0.08; // 8% + + $result.textContent = calcResult(price, discount, tax); +} + +/** + * ํ•จ์ˆ˜์˜ ์œ ์ง€๋ณด์ˆ˜์„ฑ - ์‚ฌ์šฉ์ž ์ •๋ณด ์—…๋ฐ์ดํŠธ + */ +function updateUserInfo(currentInfo, updateInfo) { + const updatedUserInfo = { ...currentInfo }; + Object.entries(updateInfo).forEach(([key, newValue]) => { + // ํ‚ค๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜, ํƒ€์ž…์ด ์ผ์น˜ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜, ๊ฐ’์ด ๋™์ผํ•œ ๊ฒฝ์šฐ, ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + if (!(key in updatedUserInfo) || typeof newValue !== typeof updatedUserInfo[key] || updatedUserInfo[key] === newValue) { + return; + } + // ๋ชจ๋“  ๊ฒ€์‚ฌ๋ฅผ ํ†ต๊ณผํ•œ ๊ฒฝ์šฐ, ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. + updatedUserInfo[key] = newValue; + }); + return updatedUserInfo; +} + +function handleUpdateClick(event, currentInfo) { + const updateName = prompt('์—…๋ฐ์ดํŠธ ํ•  ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”.'); + const updatedInfo = updateUserInfo(currentInfo, { name: updateName }); + renderUserInfo(updatedInfo); +} + +function renderUserInfo(userInfo) { + const $maintainable = document.querySelector('.maintainable'); + const $result = $maintainable.querySelector('.result'); + const { name, email, age } = userInfo; + $result.innerHTML = `

name : ${name}

+

email: ${email}

+

age: ${age}

`; +} diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-5_function/02_expression.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-5_function/02_expression.js new file mode 100644 index 0000000..2091268 --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-5_function/02_expression.js @@ -0,0 +1,132 @@ +'use strict'; + +const isValidEmail = function (email) { + const regex = /\S+@\S+\.com$/; + return regex.test(email); +}; + +const isValidPassword = function (password) { + return 10 <= password.length; +}; + +const checkForm = function (event) { + event.preventDefault(); + + const $form = event.target; + const $email = $form.querySelector('.form_email input'); + const $password = $form.querySelector('.form_password input'); + + if (!isValidEmail($email.value)) { + $email.focus(); + alert('์ด๋ฉ”์ผ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.'); + return; + } else if (!isValidPassword($password.value)) { + $password.focus(); + alert('๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”.'); + return; + } + alert('๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.'); + $form.reset(); + $email.focus(); +}; + +const formatDate = function (date) { + const options = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }; + return date.toLocaleDateString('ko-KR', options); +}; + +const formatTime = function (date) { + const options = { hour: '2-digit', minute: '2-digit' }; + return date.toLocaleTimeString('ko-KR', options); +}; + +const renderDateTime = function (event) { + const $readable = event.target.closest('.readable'); + const $result = $readable.querySelector('.result'); + + if ($result.innerText) { + return; + } + + const now = new Date(); + const $fragment = document.createDocumentFragment(); + const $date = document.createElement('p'); + const $time = document.createElement('p'); + $date.innerHTML = formatDate(now); + $time.innerText = formatTime(now); + $fragment.appendChild($date); + $fragment.appendChild($time); + $result.appendChild($fragment); +}; + +const formatCurrency = function (number) { + return `${number.toLocaleString()}์›`; +}; + +const calcResult = function (price, discount, tax) { + const quantity = parseInt(prompt('๊ตฌ๋งคํ•  ์ƒํ’ˆ์˜ ์ˆ˜๋Ÿ‰์„ ์ž…๋ ฅํ•˜์„ธ์š”:'), 10); + + if (isNaN(quantity) || quantity <= 0) { + return '์˜ฌ๋ฐ”๋ฅธ ์ˆ˜๋Ÿ‰์„ ์ž…๋ ฅํ•˜์„ธ์š”.'; + } + + let totalPrice = price * quantity; + + if (10 <= quantity) { + totalPrice *= 1 - discount; + } + + totalPrice *= 1 + tax; + + return formatCurrency(Math.round(totalPrice)); +}; + +const renderCalcResult = function (event) { + const $modulable = event.target.closest('.modulable'); + const $result = $modulable.querySelector('.result'); + const price = 1200; + const discount = 0.2; // 20%; + const tax = 0.08; // 8% + + $result.textContent = calcResult(price, discount, tax); +}; + +const updateUserInfo = function (currentInfo, updateInfo) { + const updatedUserInfo = { ...currentInfo }; + Object.entries(updateInfo).forEach(([key, newValue]) => { + if (!(key in updatedUserInfo) || typeof newValue !== typeof updatedUserInfo[key] || updatedUserInfo[key] === newValue) { + return; + } + updatedUserInfo[key] = newValue; + }); + return updatedUserInfo; +}; + +const handleUpdateClick = function (event, currentInfo) { + const updateName = prompt('์—…๋ฐ์ดํŠธ ํ•  ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”.'); + const updatedInfo = updateUserInfo(currentInfo, { name: updateName }); + renderUserInfo(updatedInfo); +}; + +const renderUserInfo = function (userInfo) { + const $maintainable = document.querySelector('.maintainable'); + const $result = $maintainable.querySelector('.result'); + const { name, email, age } = userInfo; + $result.innerHTML = `

name : ${name}

+

email: ${email}

+

age: ${age}

`; +}; + +document.addEventListener('DOMContentLoaded', () => { + document.getElementById('login').addEventListener('submit', checkForm); + document.querySelector('.readable .js-dateTime').addEventListener('click', renderDateTime); + document.querySelector('.modulable .js-calculator').addEventListener('click', renderCalcResult); + + const userInfo = { + name: 'yeongminKim', + email: 'yeongmin@yeongmin.com', + age: 38, + }; + renderUserInfo(userInfo); + document.querySelector('.maintainable .js-update').addEventListener('click', (e) => handleUpdateClick(e, userInfo)); +}); diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-6_async/01_sync_async.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-6_async/01_sync_async.js new file mode 100644 index 0000000..c1f404e --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-6_async/01_sync_async.js @@ -0,0 +1,41 @@ +'use strict'; + +const syncFunction = ($result) => { + const startTime = new Date().getTime(); + while (new Date().getTime() < startTime + 1000); + $result.innerHTML += `
๋™๊ธฐ ๋`; +}; + +const asyncFunction = ($result, isTrue) => { + $result.innerHTML = '๋น„๋™๊ธฐ ์‹œ์ž‘'; + + new Promise((resolve, reject) => { + setTimeout(() => { + if (isTrue) { + resolve('๋น„๋™๊ธฐ ์„ฑ๊ณต'); + } else { + reject('๋น„๋™๊ธฐ ์‹คํŒจ'); + } + }, 2000); + }) + .then((msg) => { + $result.innerHTML += `
msg : ${msg}`; + }) + .catch((err) => { + $result.innerHTML += `
err : ${err}`; + }); + + // ๋น„๋™๊ธฐ ์ž‘์—…์ด ์ง„ํ–‰๋˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์ž‘์—…๋„ ์‹คํ–‰์ด ๋œ๋‹ค. + setTimeout(() => { + $result.innerHTML += '
๋‹ค๋ฅธ ์ž‘์—…๋„ ์‹คํ–‰์ด ๋ฉ๋‹ˆ๋‹ค.'; + }, 1000); +}; + +document.addEventListener('DOMContentLoaded', () => { + const $result = document.querySelector('.result'); + document.querySelector('.js-sync').addEventListener('click', () => { + $result.innerText = `๋™๊ธฐ ์‹œ์ž‘`; + setTimeout(() => syncFunction($result), 1000); + }); + document.querySelector('.js-async').addEventListener('click', () => asyncFunction($result, true)); +}); diff --git a/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-6_async/02_fetch_axios.js b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-6_async/02_fetch_axios.js new file mode 100644 index 0000000..4d04d0e --- /dev/null +++ b/juyoung/week2/chapter_5_javascript/public/js/chapter_5/5-6_async/02_fetch_axios.js @@ -0,0 +1,45 @@ +'use strict'; + +const axios = window.axios; + +const setLoader = (isShow) => { + const $spinner = document.createElement('div'); + $spinner.classList.add('spinner'); + if (isShow && null === document.querySelector('.spinner')) { + document.querySelector('.result').appendChild($spinner); + } else { + document.querySelector('.spinner')?.remove(); + } +}; + +const renderHTML = (data) => { + const $result = document.querySelector('.result'); + $result.innerHTML = data; +}; + +const fetchAPI = () => { + setLoader(true); + fetch('https://jsonplaceholder.typicode.com/posts/1') + .then((response) => response.json()) + .then((json) => { + setLoader(false); + renderHTML(json.body); + }) + .catch((error) => console.error('Fetch Error:', error)); +}; + +const axiosAPI = () => { + setLoader(true); + axios + .get('https://jsonplaceholder.typicode.com/posts/2') + .then((response) => { + setLoader(false); + renderHTML(response.data.body); + }) + .catch((error) => console.error('Axios Error:', error)); +}; + +document.addEventListener('DOMContentLoaded', () => { + document.querySelector('.js-fetch').addEventListener('click', fetchAPI); + document.querySelector('.js-axios').addEventListener('click', axiosAPI); +}); diff --git a/juyoung/week3/chapter_6_loader/01_spinner_ui.html b/juyoung/week3/chapter_6_loader/01_spinner_ui.html new file mode 100644 index 0000000..bcb6b77 --- /dev/null +++ b/juyoung/week3/chapter_6_loader/01_spinner_ui.html @@ -0,0 +1,67 @@ + + + + + + + Spinner UI + + + + + + + + + + + + diff --git a/juyoung/week3/chapter_6_loader/02_svg_ui.html b/juyoung/week3/chapter_6_loader/02_svg_ui.html new file mode 100644 index 0000000..cb9b034 --- /dev/null +++ b/juyoung/week3/chapter_6_loader/02_svg_ui.html @@ -0,0 +1,123 @@ + + + + + + + 02_svg_ui.html + + + + + + + + + + + + + diff --git a/juyoung/week3/chapter_6_loader/03_skeleton_ui.html b/juyoung/week3/chapter_6_loader/03_skeleton_ui.html new file mode 100644 index 0000000..0f6172c --- /dev/null +++ b/juyoung/week3/chapter_6_loader/03_skeleton_ui.html @@ -0,0 +1,75 @@ + + + + + + + 03_skeleton_ui.html + + + + + + + + + + + + diff --git a/juyoung/week3/chapter_8_dashboard/01_dashboard.html b/juyoung/week3/chapter_8_dashboard/01_dashboard.html new file mode 100644 index 0000000..6672ed1 --- /dev/null +++ b/juyoung/week3/chapter_8_dashboard/01_dashboard.html @@ -0,0 +1,561 @@ + + + + + + + 01_dashboard.html + + + + + + + + + + +
+
+
+ +

๊ณต๋ถ€ ๋‹ค์ด์–ด๋ฆฌ

+
+
+ + + + + +
+
+ +
+

์ฃผ์š” ๋‚ด์šฉ

+
+
+

์ปค๋ฎค๋‹ˆํ‹ฐ

+ +
    +
  • + + ์˜์–ด ์ฑ… ์•„์ด์ฝ˜ + +
    +
    +

    ์˜ค๋Š˜ ์ €๋… ์˜์–ด ์Šคํ„ฐ๋”” ๊ฐ™์ด ํ•˜์‹ค๋ถ„

    + +
    + + ๐Ÿ“š ์˜ค๋Š˜ ์ €๋… 8์‹œ์— ์˜์–ด ๋‹จ์–ด ํ…Œ์ŠคํŠธ๋ž‘ ํšŒํ™” ์—ฐ์Šต ๊ฐ™์ด ํ•˜์‹ค ๋ถ„ ๊ตฌํ•ด์š”! ํ˜ผ์ž๋ณด๋‹ค ๊ฐ™์ด ํ•˜๋ฉด ํ›จ์”ฌ ๋œ ์ง€๋ฃจํ•ด์š” :) + +

    3์›” 10์ผ

    +
    +
  • +
  • + + ์ˆ˜ํ•™ ์•„์ด์ฝ˜ + +
    +
    +

    ์ˆ˜ํ•™ ๋ฌธ์ œํ’€์ด ์Šคํ„ฐ๋”” ์ธ์› ๋ชจ์ง‘

    + +
    + + โœ๏ธ ์˜ค๋Š˜ ์˜คํ›„ 3์‹œ์— ๋ฏธ์ ๋ถ„ ๋ฌธ์ œ ๊ฐ™์ด ํ’€ ์Šคํ„ฐ๋””์› ๊ตฌํ•ด์š”. ๋‚œ์ด๋„ ์ค‘~์ƒ, ํ’€์ด ๋ฐฉ๋ฒ• ์„œ๋กœ ๊ณต์œ ํ•ด๋ด์š”! + +

    3์›” 10์ผ

    +
    +
  • +
  • + + ๊ณผํ•™ ์•„์ด์ฝ˜ + +
    +
    +

    ๊ณผํ•™ ์‹คํ—˜ ๋ ˆํฌํŠธ ๊ฐ™์ด ์“ฐ์‹ค ๋ถ„

    + +
    + + ๐Ÿ”ฌ ๊ณผํ•™ ์‹คํ—˜ ๊ฒฐ๊ณผ ์ •๋ฆฌํ•˜๋ฉด์„œ ๋ ˆํฌํŠธ ๊ฐ™์ด ์“ฐ์‹ค ๋ถ„ ์žˆ๋‚˜์š”? ์ž๋ฃŒ ์กฐ์‚ฌ ๊ฐ™์ด ํ•˜๋ฉด ํ›จ์”ฌ ๋นจ๋ฆฌ ๋๋‚ผ ์ˆ˜ ์žˆ์–ด์š”! + +

    2์›” 25์ผ

    +
    +
  • +
  • + + ์‚ฌํšŒ/์—ญ์‚ฌ ์•„์ด์ฝ˜ + +
    +
    +

    [๊ณต์ง€] ํ•œ๊ตญ์‚ฌ ๊ธฐ์ถœ ๋ฌธ์ œ ์Šคํ„ฐ๋”” ์˜คํ”ˆ

    + +
    + + ๐Ÿ“– ๋งค์ฃผ ํ† ์š”์ผ ์˜ค์ „ 10์‹œ, ํ•œ๊ตญ์‚ฌ ๊ธฐ์ถœ ๋ฌธ์ œ ์Šคํ„ฐ๋””๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์ด ๊ฐœ๋… ์ •๋ฆฌํ•˜๊ณ  ์˜ค๋‹ต๋„ ๋ถ„์„ํ•ด์š”! + +

    2์›” 10์ผ

    +
    +
  • +
  • + + ๊ตญ์–ด ์•„์ด์ฝ˜ + +
    +
    +

    ๊ตญ์–ด ๋น„๋ฌธํ•™ ๋…ํ•ด ์†Œ๋ชจ์ž„

    + +
    + + ๐Ÿ“˜ ๋น„๋ฌธํ•™ ๋…ํ•ด ์–ด๋ ค์šฐ์‹  ๋ถ„๋“ค ๊ฐ™์ด ์—ฐ์Šตํ•ด์š”! ์ง€๋ฌธ ์ฝ๋Š” ๋ฐฉ๋ฒ•์ด๋ž‘ ์‹œ๊ฐ„ ๊ด€๋ฆฌ ํŒ๋„ ๊ณต์œ ํ•ด์š” :) + +

    1์›” 20์ผ

    +
    +
  • +
+
+ +
+
+

๊ณต๋ถ€ ๊ณ„ํš

+
์‹œํ—˜ D-20
+
+
+
    +
  1. + 80 + ์˜์–ด ๋‹จ์–ด +
  2. +
  3. + 60 + ์ˆ˜ํ•™ ๋ฌธ์ œ +
  4. +
  5. + 10 + ๊ณผํ•™ ๊ฐœ๋… +
  6. +
  7. + 20 + ๊ตญ์–ด ๋น„๋ฌธํ•™ +
  8. +
+
+ + +
+
+ +
    +
  • +
    +
    + 2024๋…„ 3์›” 3์ผ + +
    + ์˜์–ด + ์˜๋‹จ์–ด ์•”๊ธฐ & ๊ตฌ๋ฌธ ๋…ํ•ด +
    +
    + + 55% +
    +
  • +
  • +
    +
    + 2024๋…„ 3์›” 1์ผ + +
    + ์ˆ˜ํ•™ + ๋ฏธ์ ๋ถ„ ๋ฌธ์ œํ’€์ด +
    +
    + + 10% +
    +
  • +
  • +
    +
    + 2024๋…„ 2์›” 28์ผ + +
    + ๊ณผํ•™ + ๋ฌผ๋ฆฌยทํ™”ํ•™ ๊ฐœ๋… ์ •๋ฆฌ +
    +
    + + 90% +
    +
  • +
  • +
    +
    + 2024๋…„ 2์›” 20์ผ + +
    + ๊ตญ์–ด + ๋น„๋ฌธํ•™ ์ง€๋ฌธ ์—ฐ์Šต +
    +
    + + 22% +
    +
  • +
  • +
    +
    + 2024๋…„ 2์›” 15์ผ + +
    + ์‚ฌํšŒ + ํ•œ๊ตญ์‚ฌ ๊ธฐ์ถœ ํ’€์ด +
    +
    + + 5% +
    +
  • +
  • +
    +
    + 2024๋…„ 2์›” 5์ผ + +
    + ๋ชจ์˜๊ณ ์‚ฌ + ์ „ ๊ณผ๋ชฉ ์‹ค์ „ ์—ฐ์Šต +
    +
    + + 100% +
    +
  • +
+
+
+
+
+ + diff --git a/juyoung/week3/public/css/chapter_6/01_spinner_ui.css b/juyoung/week3/public/css/chapter_6/01_spinner_ui.css new file mode 100644 index 0000000..6d19ba8 --- /dev/null +++ b/juyoung/week3/public/css/chapter_6/01_spinner_ui.css @@ -0,0 +1,158 @@ +@charset "utf-8"; + +:root { + --duration: 0.3s; + --showing-duration: 1s; + --spinner: 3em; + --spinner-line-width: 0.3em; +} + +/* ๋ฃจํŠธ ์š”์†Œ ๊ธ€๊ผด ํฌ๊ธฐ ์„ค์ • */ +html { + font-size: 16px; +} + +body { + background-image: linear-gradient(45deg, rgba(176, 224, 230, 0.7) 0%, rgba(135, 206, 235, 0.7) 30%, rgba(100, 149, 237, 0.7) 70%, rgba(70, 130, 180, 0.8) 100%); +} + +.card_list { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100vh; + padding: 0 1rem; +} + +.card { + flex: 1 1 auto; + width: 100%; + max-width: 22rem; + margin: 1rem; + transform: translateY(0) scale(1); + transition: transform var(--duration) ease-out; +} + +.card a { + display: block; + box-shadow: 0 0 6.25rem -3.125rem rgba(0, 0, 0, 0.6); + opacity: 1; + transition: + transform var(--showing-duration) ease-out, + opacity var(--showing-duration), + box-shadow var(--showing-duration); +} + +.card.hidden a { + opacity: 0; + transform: translateY(-0.625rem) scale(1.05); + box-shadow: 0 0 3rem 3rem rgba(0, 0, 0, 0.4); +} + +.card picture { + display: block; + aspect-ratio: 1 / 1; +} + +.card picture img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.card_desc { + min-height: 7.75rem; + padding: 1.875rem 1.25rem; + color: #333; + background-color: #fff; +} + +.card_desc strong { + display: block; + font-size: 1.25rem; +} + +.card_desc span { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 0.875rem; + line-height: 1.4; +} + +@media (hover: hover) { + .card:hover { + transform: translateY(-0.625rem) scale(1.05); + } + .card:hover a { + box-shadow: 0 0.8rem 2rem -1rem rgba(0, 0, 0, 0.6); + } +} + +@media (max-width: 1280px) { + html { + font-size: 14px; + } + + .card { + max-width: 30rem; + margin-top: 2rem; + } +} + +@media (max-width: 1024px) { + .card_list { + flex-wrap: wrap; + height: auto; + } + + .card { + flex-basis: 22rem; + } +} + +@media (max-width: 768px) { + html { + font-size: 12px; + } + + .card_list { + flex-direction: column; + margin: 5rem auto; + } + + .card { + flex-basis: auto; + } + + .card ~ .card { + margin-top: 2rem; + } +} + +.spinner { + position: absolute; + left: 50%; + top: 50%; + width: var(--spinner); + height: var(--spinner); + margin-left: calc(var(--spinner) / 2 * -1); + margin-top: calc(var(--spinner) / 2 * -1); + border: var(--spinner-line-width) solid #f3f3f3; + border-left: var(--spinner-line-width) solid dodgerblue; + border-radius: 50%; + animation: spinner var(--showing-duration) infinite cubic-bezier(0.37, 0.65, 0.19, 0.1); +} + +@keyframes spinner { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/juyoung/week3/public/css/chapter_6/02_svg_ui.css b/juyoung/week3/public/css/chapter_6/02_svg_ui.css new file mode 100644 index 0000000..5253375 --- /dev/null +++ b/juyoung/week3/public/css/chapter_6/02_svg_ui.css @@ -0,0 +1,190 @@ +@charset "utf-8"; + +:root { + --duration: 0.3s; + --showing-duration: 1s; +} + +/* ๋ฃจํŠธ ์š”์†Œ ๊ธ€๊ผด ํฌ๊ธฐ ์„ค์ • */ +html { + font-size: 16px; +} + +body { + background-image: radial-gradient( + circle at center, + rgba(255, 255, 255, 0.9) 0%, + rgba(255, 230, 230, 0.8) 20%, + rgba(230, 255, 230, 0.8) 40%, + rgba(230, 230, 255, 0.8) 60%, + rgba(240, 240, 250, 0.7) 80%, + rgba(245, 245, 255, 0.6) 100% + ); +} + +.card_list { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100vh; + padding: 0 1rem; +} + +.card { + flex: 1 1 auto; + width: 100%; + max-width: 22rem; + margin: 1rem; + transform: translateY(0) scale(1); + transition: transform var(--duration) ease-out; +} + +.card a { + display: block; + box-shadow: 0 0 6.25rem -3.125rem rgba(0, 0, 0, 0.6); + opacity: 1; + transition: + transform var(--showing-duration) ease-out, + opacity var(--showing-duration), + box-shadow var(--showing-duration); +} + +.card.hidden a { + opacity: 0; + transform: translateY(-0.625rem) scale(1.05); + box-shadow: 0 0 3rem 3rem rgba(0, 0, 0, 0.4); +} + +.card picture { + display: block; + aspect-ratio: 1 / 1; +} + +.card picture img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.card_desc { + min-height: 7.75rem; + padding: 1.875rem 1.25rem; + color: #333; + background-color: #fff; +} + +.card_desc strong { + display: block; + font-size: 1.25rem; +} + +.card_desc span { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 0.875rem; + line-height: 1.4; +} + +@media (hover: hover) { + .card:hover { + transform: translateY(-0.625rem) scale(1.05); + } + .card:hover a { + box-shadow: 0 0.8rem 2rem -1rem rgba(0, 0, 0, 0.6); + } +} + +@media (max-width: 1280px) { + html { + font-size: 14px; + } + + .card { + max-width: 30rem; + margin-top: 2rem; + } +} + +@media (max-width: 1024px) { + .card_list { + flex-wrap: wrap; + height: auto; + } + + .card { + flex-basis: 22rem; + } +} + +@media (max-width: 768px) { + html { + font-size: 12px; + } + + .card_list { + flex-direction: column; + margin: 5rem auto; + } + + .card { + flex-basis: auto; + } + + .card ~ .card { + margin-top: 2rem; + } +} + +.svg_loader { + position: absolute; + left: 50%; + top: 50%; + width: 3rem; + height: 3rem; + transform: translate3d(-50%, -50%, 0); +} + +.svg_loader svg { + width: 100%; + height: 100%; + animation: rotate 1.8s linear infinite; +} + +.svg_loader circle { + fill: none; + stroke: #60a2e9; + stroke-width: 6; + stroke-linecap: round; + stroke-dasharray: 300; + stroke-dashoffset: 0; + animation: dash 1.56s ease-in-out infinite; +} + +@keyframes rotate { + 100% { + transform: rotate(360deg); + } +} + +@keyframes dash { + 0% { + stroke-dashoffset: 300; + } + + 100% { + stroke-dashoffset: 0; + } +} + +.svg_loader2 { + position: absolute; + left: 50%; + top: 50%; + width: 5rem; + height: 5rem; + transform: translate3d(-50%, -50%, 0); +} diff --git a/juyoung/week3/public/css/chapter_6/03_skeleton_ui.css b/juyoung/week3/public/css/chapter_6/03_skeleton_ui.css new file mode 100644 index 0000000..3c0fd00 --- /dev/null +++ b/juyoung/week3/public/css/chapter_6/03_skeleton_ui.css @@ -0,0 +1,179 @@ +@charset "utf-8"; + +:root { + --duration: 0.3s; + --showing-duration: 1s; +} + +/* ๋ฃจํŠธ ์š”์†Œ ๊ธ€๊ผด ํฌ๊ธฐ ์„ค์ • */ +html { + font-size: 16px; +} + +body { + background-image: linear-gradient(to bottom, #f0f8ff 0%, #e6f3ff 25%, #dcedff 50%, #d2e7ff 75%, #c8e1ff 100%); +} + +.card_list { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100vh; + padding: 0 1rem; +} + +.card { + flex: 1 1 auto; + width: 100%; + max-width: 22rem; + margin: 1rem; + transform: translateY(0) scale(1); + transition: transform var(--duration) ease-out; +} + +.card a { + display: block; + box-shadow: 0 0 6.25rem -3.125rem rgba(0, 0, 0, 0.6); + opacity: 1; +} + +.card.hidden a { + opacity: 0; +} + +.card picture { + display: block; + aspect-ratio: 1 / 1; +} + +.card picture img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.card_desc { + min-height: 7.75rem; + padding: 1.875rem 1.25rem; + color: #333; + background-color: #fff; +} + +.card_desc strong { + display: block; + font-size: 1.25rem; +} + +.card_desc span { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 0.875rem; + line-height: 1.4; +} + +@media (hover: hover) { + .card:hover { + transform: translateY(-0.625rem) scale(1.05); + } + .card:hover a { + box-shadow: 0 0.8rem 2rem -1rem rgba(0, 0, 0, 0.6); + } +} + +@media (max-width: 1280px) { + html { + font-size: 14px; + } + + .card { + max-width: 30rem; + margin-top: 2rem; + } +} + +@media (max-width: 1024px) { + .card_list { + flex-wrap: wrap; + height: auto; + } + + .card { + flex-basis: 22rem; + } +} + +@media (max-width: 768px) { + html { + font-size: 12px; + } + + .card_list { + flex-direction: column; + margin: 5rem auto; + } + + .card { + flex-basis: auto; + } + + .card ~ .card { + margin-top: 2rem; + } +} + +.skeleton { + position: absolute; + left: 0; + top: 0; + margin: 0; +} + +.skeleton .image { + aspect-ratio: 1 / 1; +} + +.skeleton .title { + width: 60%; + height: 1.8rem; +} + +.skeleton .description { + width: 100%; + height: 2.2rem; + margin-top: 0.5rem; +} + +.skeleton .image, +.skeleton .title, +.skeleton .description { + position: relative; + overflow: hidden; + background-color: #e3e3e3; +} + +.skeleton .image::before, +.skeleton .title::before, +.skeleton .description::before { + content: ''; + display: block; + position: absolute; + top: 0; + left: 0%; + width: 100%; + height: 100%; + background-image: linear-gradient(to right, transparent 0%, #f0f0f0 50%, transparent 100%); + animation: skeleton 1s infinite; +} + +@keyframes skeleton { + 0% { + transform: translateX(-100%); + } + 100% { + transform: translateX(100%); + } +} diff --git a/juyoung/week3/public/css/chapter_8/01_dashboard.css b/juyoung/week3/public/css/chapter_8/01_dashboard.css new file mode 100644 index 0000000..adcb4ee --- /dev/null +++ b/juyoung/week3/public/css/chapter_8/01_dashboard.css @@ -0,0 +1,520 @@ +@charset "utf-8"; + +:root { + --bg-color: #d3d2e7; + --main-color: #1f2f2f; + --second-color: #444444; + --section-color: #ffffff; + --card-color: #e3d8f6; + --progress-color: #8e6ccc; + --border-color: rgba(0, 0, 0, 0.1); + --icon-color: #000000; + --active-bg: #1f2f2f; + + --box-border: 1rem; +} + +.dark:root { + --bg-color: #0b181d; + --main-color: #ffffff; + --second-color: rgba(255, 255, 255, 0.7); + --section-color: #162f35; + --card-color: #4d6165; + --progress-color: #172f35; + --border-color: rgba(255, 255, 255, 0.1); + --icon-color: #ffffff; + --active-bg: #1f2f2f; +} + +html, +body { + width: 100%; + height: 100vh; +} + +body { + background: var(--bg-color); + font-family: 'Noto Sans KR', sans-serif; + color: var(--main-color); + visibility: hidden; +} + +button { + cursor: pointer; +} + +.svg_icon { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + width: 1.6rem; + height: 1.6rem; +} + +.svg_icon svg { + width: 100%; + height: 100%; +} + +.svg_icon svg path { + stroke: var(--icon-color); +} + +.svg_icon.hover { + border-radius: 50%; + padding: 0.5rem; + box-sizing: content-box; + transition: background-color 0.5s; +} + +.svg_icon.active { + background-color: var(--main-color); +} + +.svg_icon.active path { + stroke: var(--section-color); +} + +@media (hover: hover) { + .svg_icon.hover:hover { + background-color: var(--main-color); + } + + .svg_icon.hover:hover path { + stroke: var(--section-color); + } +} + +.svg_moon { + display: none; +} + +.svg_sun { + display: block; +} + +.dark .svg_moon { + display: block; +} + +.dark .svg_sun { + display: none; +} + +.profile { + display: flex; + align-items: center; + flex-shrink: 0; +} + +.profile img { + width: 2rem; + height: 2rem; + object-fit: cover; + border-radius: 50%; +} + +main { + display: grid; + grid-template-rows: auto 1fr; + width: 100%; + height: 100%; + max-width: 100rem; + margin: 0 auto; +} + +header { + display: flex; + justify-content: space-between; + align-items: center; + position: relative; + width: 100%; + padding: 1.75rem 2rem 1.75rem 0.8rem; +} + +.top_left, +.top_right { + display: flex; + align-items: center; +} + +h1 { + margin-left: 1.5rem; + font-size: 1.25rem; + font-weight: bold; + word-break: keep-all; +} + +.search { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + height: 2.5rem; + max-width: 28.75rem; + margin-left: 2rem; + padding-right: 1.25rem; + border-radius: 1.25rem; + background-color: var(--section-color); +} + +.search label { + width: 100%; +} + +.search input { + width: 100%; + padding-left: 2rem; + font-size: 0.9rem; + color: var(--main-color); +} + +.search .svg_icon { + width: 1.75rem; + height: 1.75rem; +} + +.top_right { + flex-grow: 1; + justify-content: flex-end; + gap: 0.5rem; +} + +.profile .name { + display: block; + margin-left: 0.5rem; + font-weight: bold; +} + +.svg_bubble { + display: none; + position: fixed; + z-index: 10; + bottom: 2.6rem; + right: 2.6rem; + width: 2rem; + height: 2rem; +} + +.container { + width: 100%; + height: 100%; + overflow: hidden; +} + +.main_content { + display: grid; + grid-template-columns: 2fr 3fr; + gap: 1.5rem; + height: 100%; + padding: 0 1.5rem 1.5rem; +} + +.article { + display: flex; + flex-direction: column; + height: 100%; + border-radius: var(--box-border); + background-color: var(--section-color); + color: var(--main-color); + overflow: hidden; +} + +.article h3 { + font-size: 1.5rem; + font-weight: 700; +} + +.community h3 { + padding: 2rem; +} + +.community .svg_close { + display: none; + position: absolute; + right: 2rem; + top: 2.2rem; + width: 2rem; + height: 2rem; +} + +.community .board { + display: flex; + flex-direction: column; + overflow-y: auto; +} + +.board .list { + display: flex; + align-items: flex-start; + padding: 2rem 1.5rem; + border-top: 1px solid var(--border-color); +} + +.board .list.active .svg_favorite path { + fill: var(--main-color); +} + +.board .preview { + margin-left: 1rem; + width: 100%; +} + +.board .title { + display: flex; + justify-content: space-between; +} + +.board .name { + font-weight: 700; +} + +.board .svg_favorite { + width: 1.3rem; + height: 1.3rem; +} + +.board .text { + display: block; + margin-top: 0.3rem; + font-size: 0.9rem; + color: var(--second-color); +} + +.board .date { + display: block; + margin-top: 0.8rem; + text-align: right; + font-size: 0.8rem; + color: var(--second-color); + font-weight: 300; +} + +.exercises { + padding: 2rem; +} + +.exercises .title { + display: flex; + justify-content: space-between; +} + +.exercises .date { + font-size: 1.2rem; + font-weight: 700; +} + +.exercises .util { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 1rem; +} + +.progress { + display: flex; +} + +.progress .list { + margin-right: 2rem; +} + +.progress .count { + display: block; + font-size: 1.2rem; + font-weight: 600; + line-height: 1; +} + +.progress .text { + font-size: 0.8rem; + font-weight: 300; +} + +.view_change { + display: flex; +} + +.view_change .svg_icon { + margin-left: 0.7rem; +} + +.view_change .svg_list svg { + transform: scale(1.3); +} + +.view_container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); + gap: 1rem; + margin-top: 2rem; + color: #1f2f2f; + overflow-y: auto; +} + +.view_container .list { + padding: 1.2rem; + border-radius: var(--box-border); + background: var(--card-color); + color: var(--main-color); +} + +.view_container .top { + display: flex; + justify-content: space-between; + align-items: center; +} + +.view_container .date { + font-size: 0.8rem; + font-weight: 300; +} + +.view_container .svg_more { + width: 1.3rem; + height: 1.3rem; +} + +.view_container .title { + display: block; + text-align: center; + margin-top: 1rem; + font-size: 1.1rem; + font-weight: 500; +} + +.view_container .sub_title { + display: block; + margin-top: 0.2rem; + text-align: center; + font-size: 0.8rem; + font-weight: 300; +} + +.graph { + display: flex; + justify-content: space-between; + align-items: center; + gap: 1rem; + width: 100%; + margin-top: 1rem; + margin-bottom: 0.5rem; +} + +.graph progress { + width: 100%; + height: 0.2rem; +} + +.graph progress::-webkit-progress-bar { + background-color: #fff; + border-radius: 0.5rem; +} + +.graph progress::-webkit-progress-value { + border-radius: 0.5rem; + background-color: var(--progress-color); +} + +.graph .percent { + font-size: 0.8rem; + font-weight: 300; +} + +[data-type='list'] .view_container { + grid-template-columns: 1fr; +} + +[data-type='list'] .view_container .list { + display: flex; + position: relative; + width: 100%; + border-radius: 1rem; +} + +[data-type='list'] .view_container .svg_more { + position: absolute; + right: 1.5rem; + top: 1.5rem; + width: 1rem; + height: 1rem; +} + +[data-type='list'] .view_container .info { + display: flex; + flex-direction: column; + flex-shrink: 0; + margin-right: 0.5rem; +} + +[data-type='list'] .view_container .top { + order: 1; + margin-top: 0.3rem; +} + +[data-type='list'] .view_container .title { + text-align: left; + margin-top: 0; +} + +[data-type='list'] .view_container .sub_title { + text-align: left; + margin-top: 0.3rem; +} + +@media (max-width: 1023px) { + .svg_bubble { + display: block; + } + + .main_content { + grid-template-columns: 1fr; + } + + /* community */ + .community { + position: fixed; + top: 0; + right: -100%; + z-index: 1; + width: 100%; + margin-right: 0; + border-radius: 0; + transition: transform 0.5s ease-in-out; + } + + .community .svg_close { + display: block; + } + + .community.active { + transform: translate3d(-100%, 0, 0); + } +} + +@media (max-width: 767px) { + h1 { + display: none; + } + + .search { + margin-left: 0.8rem; + } + + .profile .name { + display: none; + } +} + +@media (max-width: 639px) { + html { + font-size: 14px; + } +} + +@media (max-width: 480px) { + html { + font-size: 12px; + } +} diff --git a/juyoung/week3/public/css/common.css b/juyoung/week3/public/css/common.css new file mode 100644 index 0000000..8d965a3 --- /dev/null +++ b/juyoung/week3/public/css/common.css @@ -0,0 +1,24 @@ +@charset "utf-8"; + +@layer base { + .sr-only { + position: absolute; + overflow: hidden; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + border: 0; + clip: rect(0, 0, 0, 0); + } + + h1 { + font-size: 30px; + } + + .heading_1 { + margin-top: 50px; + text-align: center; + font-weight: bold; + } +} diff --git a/juyoung/week3/public/css/reset.css b/juyoung/week3/public/css/reset.css new file mode 100644 index 0000000..01c6ce5 --- /dev/null +++ b/juyoung/week3/public/css/reset.css @@ -0,0 +1,89 @@ +@charset "utf-8"; +@layer base { + + *:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) { + all: unset; + display: revert; + } + + *, + *::before, + *::after { + box-sizing: border-box; + } + + html { + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; + } + + a, + button { + cursor: revert; + } + + ol, + ul, + menu, + summary { + list-style: none; + } + + img { + max-inline-size: 100%; + max-block-size: 100%; + } + + table { + border-collapse: collapse; + } + + input, + textarea { + -webkit-user-select: auto; + } + + textarea { + white-space: revert; + } + + meter { + -webkit-appearance: revert; + appearance: revert; + } + + :where(pre) { + all: revert; + box-sizing: border-box; + } + + ::placeholder { + color: unset; + } + + :where([hidden]) { + display: none; + } + + :where([contenteditable]:not([contenteditable='false'])) { + -moz-user-modify: read-write; + -webkit-user-modify: read-write; + overflow-wrap: break-word; + -webkit-line-break: after-white-space; + -webkit-user-select: auto; + } + + :where([draggable='true']) { + -webkit-user-drag: element; + } + + :where(dialog:modal) { + all: revert; + box-sizing: border-box; + } + + ::-webkit-details-marker { + display: none; + } +} diff --git a/juyoung/week3/public/img/apple.jpeg b/juyoung/week3/public/img/apple.jpeg new file mode 100644 index 0000000..b7402fd Binary files /dev/null and b/juyoung/week3/public/img/apple.jpeg differ diff --git a/juyoung/week3/public/img/egg.jpeg b/juyoung/week3/public/img/egg.jpeg new file mode 100644 index 0000000..dd26a56 Binary files /dev/null and b/juyoung/week3/public/img/egg.jpeg differ diff --git a/juyoung/week3/public/img/english.jpeg b/juyoung/week3/public/img/english.jpeg new file mode 100644 index 0000000..69b20b3 Binary files /dev/null and b/juyoung/week3/public/img/english.jpeg differ diff --git a/juyoung/week3/public/img/grape.jpeg b/juyoung/week3/public/img/grape.jpeg new file mode 100644 index 0000000..8f6a3e5 Binary files /dev/null and b/juyoung/week3/public/img/grape.jpeg differ diff --git a/juyoung/week3/public/img/grapefruit.jpeg b/juyoung/week3/public/img/grapefruit.jpeg new file mode 100644 index 0000000..7a444b5 Binary files /dev/null and b/juyoung/week3/public/img/grapefruit.jpeg differ diff --git a/juyoung/week3/public/img/korea.jpeg b/juyoung/week3/public/img/korea.jpeg new file mode 100644 index 0000000..e1679ad Binary files /dev/null and b/juyoung/week3/public/img/korea.jpeg differ diff --git a/juyoung/week3/public/img/math.jpeg b/juyoung/week3/public/img/math.jpeg new file mode 100644 index 0000000..babc5b6 Binary files /dev/null and b/juyoung/week3/public/img/math.jpeg differ diff --git a/juyoung/week3/public/img/melon.jpeg b/juyoung/week3/public/img/melon.jpeg new file mode 100644 index 0000000..5d3b50a Binary files /dev/null and b/juyoung/week3/public/img/melon.jpeg differ diff --git a/juyoung/week3/public/img/milk.jpeg b/juyoung/week3/public/img/milk.jpeg new file mode 100644 index 0000000..6eb306a Binary files /dev/null and b/juyoung/week3/public/img/milk.jpeg differ diff --git a/juyoung/week3/public/img/orange.jpeg b/juyoung/week3/public/img/orange.jpeg new file mode 100644 index 0000000..361dde7 Binary files /dev/null and b/juyoung/week3/public/img/orange.jpeg differ diff --git a/juyoung/week3/public/img/potato.jpeg b/juyoung/week3/public/img/potato.jpeg new file mode 100644 index 0000000..43b64a1 Binary files /dev/null and b/juyoung/week3/public/img/potato.jpeg differ diff --git a/juyoung/week3/public/img/profile.jpeg b/juyoung/week3/public/img/profile.jpeg new file mode 100644 index 0000000..2eb54d9 Binary files /dev/null and b/juyoung/week3/public/img/profile.jpeg differ diff --git a/juyoung/week3/public/img/pumkin.jpeg b/juyoung/week3/public/img/pumkin.jpeg new file mode 100644 index 0000000..e1233a7 Binary files /dev/null and b/juyoung/week3/public/img/pumkin.jpeg differ diff --git a/juyoung/week3/public/img/science.jpeg b/juyoung/week3/public/img/science.jpeg new file mode 100644 index 0000000..07a2f42 Binary files /dev/null and b/juyoung/week3/public/img/science.jpeg differ diff --git a/juyoung/week3/public/img/society.jpeg b/juyoung/week3/public/img/society.jpeg new file mode 100644 index 0000000..0fc2cb3 Binary files /dev/null and b/juyoung/week3/public/img/society.jpeg differ diff --git a/juyoung/week3/public/img/watermelon.jpeg b/juyoung/week3/public/img/watermelon.jpeg new file mode 100644 index 0000000..330aca3 Binary files /dev/null and b/juyoung/week3/public/img/watermelon.jpeg differ diff --git a/juyoung/week3/public/js/chapter_6/01_spinner_ui.JS b/juyoung/week3/public/js/chapter_6/01_spinner_ui.JS new file mode 100644 index 0000000..9e0909e --- /dev/null +++ b/juyoung/week3/public/js/chapter_6/01_spinner_ui.JS @@ -0,0 +1,29 @@ +'use strict'; + +const DELAY = 1000 * 1; + +// ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜ +const show = ($elem) => ($elem.style.display = 'block'); +// ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜ +const hide = ($elem) => ($elem.style.display = 'none'); +// ์นด๋“œ UI ์•„์ดํ…œ๋“ค์„ DELAY์— ๋”ฐ๋ผ์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ํ•จ์ˆ˜ +const showItems = ($elem, $loader, idx) => { + setTimeout( + () => { + hide($loader); + $elem.classList.remove('hidden'); + }, + DELAY * (idx + 1), + ); +}; + +const initSpinner = ($elem, idx) => { + const $spinner = document.querySelector('.spinner').cloneNode(); + show($spinner); + $elem.appendChild($spinner); + showItems($elem, $spinner, idx); +}; + +document.addEventListener('DOMContentLoaded', () => { + [...document.querySelectorAll('.card_list .card')].forEach(($element, index) => initSpinner($element, index)); +}); diff --git a/juyoung/week3/public/js/chapter_6/02_svg_ui.js b/juyoung/week3/public/js/chapter_6/02_svg_ui.js new file mode 100644 index 0000000..94a35bb --- /dev/null +++ b/juyoung/week3/public/js/chapter_6/02_svg_ui.js @@ -0,0 +1,30 @@ +'use strict'; + +const DELAY = 1000 * 1.5; + +// ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜ +const show = ($elem) => ($elem.style.display = 'block'); +// ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜ +const hide = ($elem) => ($elem.style.display = 'none'); +// ์นด๋“œ UI ์•„์ดํ…œ๋“ค์„ DELAY์— ๋”ฐ๋ผ์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ํ•จ์ˆ˜ +const showItems = ($elem, $loader, idx) => { + setTimeout( + () => { + hide($loader); + $elem.classList.remove('hidden'); + }, + DELAY * (idx + 1), + ); +}; + +const initSVGLoader = ($elem, idx) => { + // const $svgLoader = document.querySelector('.svg_loader').cloneNode(true); + const $svgLoader = document.querySelector('.svg_loader2').cloneNode(true); + show($svgLoader); + $elem.appendChild($svgLoader); + showItems($elem, $svgLoader, idx); +}; + +document.addEventListener('DOMContentLoaded', () => { + [...document.querySelectorAll('.card_list .card')].forEach(($element, index) => initSVGLoader($element, index)); +}); diff --git a/juyoung/week3/public/js/chapter_6/03_skeleton_ui.js b/juyoung/week3/public/js/chapter_6/03_skeleton_ui.js new file mode 100644 index 0000000..c66fde3 --- /dev/null +++ b/juyoung/week3/public/js/chapter_6/03_skeleton_ui.js @@ -0,0 +1,29 @@ +'use strict'; + +const DELAY = 1000 * 1.5; + +// ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜ +const show = ($elem) => ($elem.style.display = 'block'); +// ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜ +const hide = ($elem) => ($elem.style.display = 'none'); +// ์นด๋“œ UI ์•„์ดํ…œ๋“ค์„ DELAY์— ๋”ฐ๋ผ์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ํ•จ์ˆ˜ +const showItems = ($elem, $loader, idx) => { + setTimeout( + () => { + hide($loader); + $elem.classList.remove('hidden'); + }, + DELAY * (idx + 1), + ); +}; + +const initSkeleton = ($elem, idx) => { + const $skeleton = document.querySelector('.skeleton').cloneNode(true); + show($skeleton); + $elem.appendChild($skeleton); + showItems($elem, $skeleton, idx); +}; + +document.addEventListener('DOMContentLoaded', () => { + [...document.querySelectorAll('.card_list .card')].forEach(($element, index) => initSkeleton($element, index)); +}); diff --git a/juyoung/week3/public/js/chapter_8/01_dashboard.js b/juyoung/week3/public/js/chapter_8/01_dashboard.js new file mode 100644 index 0000000..9ebc4cb --- /dev/null +++ b/juyoung/week3/public/js/chapter_8/01_dashboard.js @@ -0,0 +1,146 @@ +import { get$, getAll$ } from '../utils.js'; + +/** + * @function setTheme + * @description ํ…Œ๋งˆ ์„ค์ • + * @param {string} theme - ์„ค์ •ํ•  ํ…Œ๋งˆ (default : light) + */ +const setTheme = (theme = 'light') => { + document.documentElement.setAttribute('class', theme); +}; + +/** + * @function themeChangeHandler + * @description ํ…Œ๋งˆ ๋ณ€๊ฒฝ ํ•ธ๋“ค๋Ÿฌ + * @param {MouseEvent} event - ํด๋ฆญ ์ด๋ฒคํŠธ ๊ฐ์ฒด + */ +const themeChangeHandler = (event) => { + const theme = document.documentElement.classList.contains('dark') ? 'light' : 'dark'; + const $theme = event.target.closest('button').querySelector(`[data-theme="${theme}"]`); + if ($theme) { + setTheme($theme.dataset.theme); + } +}; + +/** + * @function setViewType + * @description ๋ทฐํƒ€์ž… ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ํ•จ์ˆ˜ + * @param {string} [viewType] - ๋ทฐ ํƒ€์ž…(default: thumbnail) + */ +const setViewType = (viewType = 'thumbnail') => { + get$('.js-viewChange .active')?.classList.remove('active'); + get$(`.js-viewChange [data-type="${viewType}"]`)?.classList.add('active'); + get$('.js-viewType').dataset.type = viewType; +}; + +/** + * @function viewChangeHandler + * @description ๋ทฐํƒ€์ž… ๋ณ€๊ฒฝ ํ•ธ๋“ค๋Ÿฌ + * @param {MouseEvent} event - ํด๋ฆญ ์ด๋ฒคํŠธ + */ +const viewChangeHandler = (event) => { + const $target = event.target.closest('button'); + if (!$target || $target.classList.contains('active')) { + return; + } + setViewType($target.dataset.type); +}; + +/** + * @function toggleFavorite + * @description ์ฆ๊ฒจ์ฐพ๊ธฐ ํ† ๊ธ€ + * @param {MouseEvent} event - ํด๋ฆญ ์ด๋ฒคํŠธ ๊ฐ์ฒด + */ +const toggleFavorite = (event) => { + if (!event.target.closest('button')) { + return; + } + event.target.closest('.list').classList.toggle('active'); +}; + +/** + * @function getActiveFavorite + * @description ์ฆ๊ฒจ์ฐพ๊ธฐ ์ƒํƒœ + * @param {Element[]} $favorites - ์ฆ๊ฒจ์ฐพ๊ธฐ ์ƒํƒœ์ธ ์š”์†Œ๋“ค + */ +const getActiveFavorite = ([...$favorites]) => { + const result = $favorites.map(($element) => $element.classList.contains('active')); + return JSON.stringify(result); +}; + +/** + * @function setActiveFavorite + * @description ์ฆ๊ฒจ์ฐพ๊ธฐ ์ƒํƒœ ์„ค์ • + * @param {boolean[]} favorites - ์ฆ๊ฒจ์ฐพ๊ธฐ ์ƒํƒœ ๋ฐฐ์—ด + */ +const setActiveFavorite = ([...favorites]) => { + if (favorites.length <= 0) { + return; + } + [...getAll$('.js-favorite .list')].forEach((list, index) => { + list.classList.toggle('active', favorites[index]); + }); +}; + +/** + * @function setSearch + * @description ๊ฒ€์ƒ‰ ์„ค์ • + * @param {string} search - URL ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ + */ +const setSearch = (search) => { + const searchKeyword = new URLSearchParams(search).get('searchWords'); + if (!searchKeyword) return; + get$('#search').value = searchKeyword; + [...getAll$('.js-viewContainer .list')].forEach(($element) => { + if ($element.querySelector('.title').textContent.includes(searchKeyword)) { + $element.style.display = 'block'; + } else { + $element.style.display = 'none'; + } + }); +}; + +/** + * @function openCommunity + * @description ์ปค๋ฎค๋‹ˆํ‹ฐ ์—ด๊ธฐ + */ +const openCommunity = () => { + get$('.js-community').classList.add('active'); +}; + +/** + * @function closeCommunity + * @description ์ปค๋ฎค๋‹ˆํ‹ฐ ๋‹ซ๊ธฐ + */ +const closeCommunity = () => { + get$('.js-community').classList.remove('active'); +}; + +/** + * @function notWorking + * @description ๋ฏธ๊ตฌํ˜„ ๊ธฐ๋Šฅ ์•Œ๋ฆผ + */ +const notWorking = () => { + alert('ํ•ด๋‹น ๋ถ€๋ถ„์„ ์ง์ ‘ ๊ตฌํ˜„ ํ•ด๋ณด์„ธ์š”.'); +}; + +document.addEventListener('DOMContentLoaded', () => { + setViewType(localStorage.getItem('viewType') ?? 'list'); + setTheme(localStorage.getItem('theme') ?? 'light'); + setActiveFavorite(JSON.parse(localStorage.getItem('favorites')) ?? []); + setSearch(window.location.search); + get$('body').style.visibility = 'visible'; + + get$('.js-theme').addEventListener('click', themeChangeHandler); + get$('.js-viewChange').addEventListener('click', viewChangeHandler); + get$('.js-openCommunity').addEventListener('click', openCommunity); + get$('.js-closeCommunity').addEventListener('click', closeCommunity); + get$('.js-favorite').addEventListener('click', toggleFavorite); + getAll$('.js-notWorking').forEach(($element) => $element.addEventListener('click', notWorking)); +}); + +window.addEventListener('beforeunload', () => { + localStorage.setItem('viewType', get$('.js-viewType').dataset.type); + localStorage.setItem('theme', document.documentElement.getAttribute('class')); + localStorage.setItem('favorites', getActiveFavorite([...getAll$('.js-favorite .list')])); +}); diff --git a/juyoung/week3/public/js/utils.js b/juyoung/week3/public/js/utils.js new file mode 100644 index 0000000..551d9e4 --- /dev/null +++ b/juyoung/week3/public/js/utils.js @@ -0,0 +1,4 @@ +const get$ = (selector) => document.querySelector(selector); +const getAll$ = (selector) => document.querySelectorAll(selector); + +export { get$, getAll$ };