<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>kimjiji_0.log</title>
        <link>https://velog.io/</link>
        <description>달리는 거북이</description>
        <lastBuildDate>Tue, 06 Jan 2026 19:02:19 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. kimjiji_0.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/kimjiji_0" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[리액트]]></title>
            <link>https://velog.io/@kimjiji_0/%EB%A6%AC%EC%95%A1%ED%8A%B8</link>
            <guid>https://velog.io/@kimjiji_0/%EB%A6%AC%EC%95%A1%ED%8A%B8</guid>
            <pubDate>Tue, 06 Jan 2026 19:02:19 GMT</pubDate>
            <description><![CDATA[<p>리액트 공부하면서 노션이 더 편해서 먼저 정리ㅠ
다시 복습하면서 벨로그로 정리하자ㅠ.ㅠ</p>
<p><a href="https://www.notion.so/2dcdf8931d14809984c2d7a3849db278?source=copy_link">https://www.notion.so/2dcdf8931d14809984c2d7a3849db278?source=copy_link</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Node.js]]></title>
            <link>https://velog.io/@kimjiji_0/Node.js</link>
            <guid>https://velog.io/@kimjiji_0/Node.js</guid>
            <pubDate>Tue, 06 Jan 2026 18:58:57 GMT</pubDate>
            <description><![CDATA[<p>리액트 들어가기전 간단한 node정리!
강의는 <code>한 입 크기로 잘라 먹는 리액트</code></p>
<h2 id="node는-자바스크립트-파일-실행기"><code>node</code>는 “자바스크립트 파일 실행기”</h2>
<p><code>node</code>는 <strong>파일을 직접 실행</strong>하는 명령어.</p>
<p>자바스크립트를 구동하는 구동기 역활, 코드를 브라우저 밖에서 실행할 수 있게 해주는 런타임 환경이다.
ctrl+` ⇒ 터미널</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/219accdd-0fff-488f-b24a-869ff8ff9f49/image.png" alt="">
-&gt;현재 경로</p>
<hr>
<p>새로운 node.js 패키지를 생성하기 위해 새로운 패키지를 초기화 or 새로 만들어 달라 ⇒ <code>npm init</code></p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/523d318a-e410-4bd7-924b-d4a2a4cec5a0/image.png" alt=""></p>
<p>패키지 이름이 뭐냐(자동값) ⇒바꾸고싶으면 바꾸기</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/95aa4f8e-13b8-4b01-bd72-f8cf3c2ce5f2/image.png" alt=""></p>
<p>일단 엔터만 클릭해서 정보 입력해주고 패키지 생성하기</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/62333140-030a-4f60-afb8-ef261e5dc55e/image.png" alt=""></p>
<p>그럼 기본적으로 넣어준게 파일 만들어줌</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/d5e0780f-d33c-4862-b56b-7d383180da37/image.png" alt=""></p>
<p>js파일 만들어서 node랑연결시켜주는방법</p>
<p><code>node index.js(파일이름,경로)</code>
“Node로 <code>src/index.js</code> 파일 실행해줘”라는 뜻.</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/d710d102-ced4-450c-aea8-b55ff27afc71/image.png" alt=""></p>
<p>잘 실행된걸 확인</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/185d8ec9-c2ee-4def-a9e8-9619418aedab/image.png" alt=""></p>
<p>인덱스파일이 src파일 안에 있었다면 node <code>src/index.js</code> 경로를 반드시 명시해줘야함 ‘src폴더 안에 인덱스 파일 실행하라~ 하는것’</p>
<h2 id="🔸파일이-여러개일때-scripts">🔸파일이 여러개일때 <code>scripts</code></h2>
<h3 id="🔹npm은-명령어를-저장해두고-실행하는-관리자">🔹<code>npm</code>은 “명령어를 저장해두고 실행하는 관리자”</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/b46de708-7160-4720-92b5-c2c5c68cf25d/image.png" alt=""></p>
<p>스크립트 안에 있는 매크로들!</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/ab0e1ef1-dff9-4b37-af35-2c36d5369241/image.png" alt=""></p>
<h3 id="🔹npm-run-start">🔹npm run <code>start</code></h3>
<blockquote>
<pre><code class="language-jsx">&quot;scripts&quot;: {
  &quot;start&quot;: &quot;node src/index.js&quot;
}
</code></pre>
</blockquote>
<pre><code>
그럼
&gt;
```bash
npm run start



= npm이 `start`라는 이름을 찾아서

= 그 안에 적힌 `&quot;node src/index.js&quot;`를 대신 실행해줘요.

일종의 매크로 역활을 하는것 경로를 지정!

![](https://velog.velcdn.com/images/kimjiji_0/post/8568957f-c674-4b47-9b3c-b76af300c488/image.png)


그래서 **start**에 경로를 지정해 놓고 npm run `start` 라고 하면 연결된걸 확인할수있음

- **node** = “파일 실행기” → `node 파일경로`
- **npm run** = “단축명령 실행기” → `npm run 별칭`

## 🔸모듈 시스템

![](https://velog.velcdn.com/images/kimjiji_0/post/28c09b67-fd82-4878-895b-46fe11fed674/image.png)


하나의 스크립트에 모든 기능을 넣으면 코드 줄이 너무 길어지니까 나눠쓰는

![](https://velog.velcdn.com/images/kimjiji_0/post/b294f908-a6c8-43f9-bb6b-3c41129dea80/image.png)


일단 이 2개만 배울것임

### 🔹 CJS(Common JS 모듈 시스템)

- 두개를 연동시켜볼꺼얌

![](https://velog.velcdn.com/images/kimjiji_0/post/1aeb2d71-d617-46f2-b42d-2f949df934a6/image.png)


![](https://velog.velcdn.com/images/kimjiji_0/post/11a68343-f9de-49fe-a36d-9d1e6ebd6579/image.png)


**`모듈(module)`**은 “파일 하나”라고 생각

**`module.exports`**는 이 파일에서 밖으로 내보낼 것 목록

![](https://velog.velcdn.com/images/kimjiji_0/post/b35c3f8e-857d-4d84-a009-ff79bc02965a/image.png)


![](https://velog.velcdn.com/images/kimjiji_0/post/9ac026bf-ac97-4495-ae9f-906b436a8158/image.png)


벨류값으로 사용되는 변수의 이름과 키값이 똑같을 경우 변수나 함수의 이름만 사용해도 됨

모듈이라는 내장객체에 export(내보내기)라는 프로퍼티에 객체를 저장해주는

각각 내보내고 싶은 값을 넣어주면 댐

⇒

- **객체(object)** = `{}` 처럼 생긴 “값 묶음”
- **프로퍼티(property)** = 객체 안의 “칸/이름표(키)”
- 

const obj = { key: value };

키(key): 왼쪽 이름표(속성 이름)

벨류(value): 오른쪽에 실제로 들어가는 값(데이터)

예시:

&gt;```jsx
const user = {name:&quot;지지&quot;,age:20 };</code></pre><ul>
<li>키: <code>name</code>, <code>age</code></li>
<li>벨류: <code>&quot;지지&quot;</code>, <code>20</code></li>
</ul>
<hr>
<p>예를 들어:</p>
<blockquote>
<pre><code class="language-jsx">const person = {name:&quot;지지&quot;,age:20 };</code></pre>
</blockquote>
<pre><code>
여기서

- `person` = 객체
- `name`, `age` = person 객체의 **프로퍼티**
- `&quot;지지&quot;`, `20` = 그 프로퍼티에 들어있는 값

---

### 그럼 강의 문장으로 돌아가서

Node에서는 `module`이라는 “내장 객체”가 있고,

그 안에 `exports`라는 **프로퍼티(칸)**가 있음.

즉 이런 구조:

- `module` (객체)
- `exports` (프로퍼티)

그리고 이 코드:

&gt;```jsx
module.exports = { add, sub };



이건 말 그대로

&gt; module 객체의 exports라는 칸에
&gt; 
&gt; 
&gt; `{ add, sub }` 라는 **객체를 넣어준다**
&gt; 

라는 뜻.

---

### “넣어준다”를 눈으로 보이게 하면

&gt;```jsx
module.exports// 처음엔 비어있거나 기본값
&gt;
module.exports = { add, sub };// 이제 exports 칸에 이 객체가 저장됨



![](https://velog.velcdn.com/images/kimjiji_0/post/ffae34c9-7e0e-4633-b3cf-e938d0063e69/image.png)


처음에 require()함수로 불러오는것

require(”./math”);로 하면 불러와짐. 이걸 변수로 담기

`const moudleDate = require(”./math”);`

![](https://velog.velcdn.com/images/kimjiji_0/post/a4db20cb-0472-462f-8733-4fe09554ec70/image.png)


add,sub가 잘 출력된걸 확인할수있음

그럼 `moudleDate` 함수안에는 {add: [Function: add], sub: [Function: sub]}가 담겨있는것임.

![](https://velog.velcdn.com/images/kimjiji_0/post/3308fe18-47b1-456b-9afa-b1ed50866962/image.png)


3과-1이 잘 출력되었음

const moudleDate = require(”./math”);을 그대로 쓸필요는 없음 const `{ add, sub }`= require(”./math”);로 해도 동일함

## 🔸필요한 것만 바로 꺼내 받기 (구조분해 할당)

&gt;```jsx
const { add, sub } =require(&quot;./math&quot;);
&gt;
add(1,2);
sub(1,2);



👉 “상자에서 필요한 물건(add, sub)만 바로 꺼내서 손에 쥐는 방식”

---

### 🤔왜 둘이 동일해?

사실 방법 B는 내부적으로 이런 뜻:

&gt;```jsx
const moduleData =require(&quot;./math&quot;);
const add = moduleData.add;
const sub = moduleData.sub;



이걸 한 줄로 줄인 게

&gt;```jsx
const { add, sub } =require(&quot;./math&quot;);



## 🔸ESM (ES 모듈 시스템)

좀 더 최신식

이걸 쓰려면 `package.json` 에서 es모듈 시스템을 쓰겟다고 해줘야함

![](https://velog.velcdn.com/images/kimjiji_0/post/ac13a864-5730-4910-b395-98efe03f2d94/image.png)


그래서 es를 쓴다고 해놓고 common꺼를 쓰면 오류가 남

⇒ 기본적으로 함께 쓸 수 없음

![](https://velog.velcdn.com/images/kimjiji_0/post/6251320d-9cc5-4df1-9759-831d379669fb/image.png)


math.js부분을

&gt;```jsx
module.exports = { add, sub };를
//

export { add, sub }; 로 바꿔줘야함


또한 index.js부분을

&gt;```jsx
const moduleData =require(&quot;./math&quot;);를
//

import mul, { add, sub } from &quot;./math.js&quot;; 로 바꿔야함.


여기서 주의할점은 확장자를 반드시 적어줘야함. (ㅇㅇ**.js**말하는거)

&gt;```jsx
// math 모듈
&gt;
export function add(a, b) {
  return a + b;
}
&gt;
export function sub(a, b) {
  return a - b;
}

//로 한번에 적어주면 더 간편하게 작성가능!


### 🔹default ⇒ 이름 내맘대로 정하기✨

⇒ 대표 1개만 내보낼때 이름 맘대로 가넝

&gt;```jsx
// math 모듈
export default function multiply(a, b) {
  return a * b;
}</code></pre><p>이 파일에서 <strong>multiply 함수 하나를 기본(default)으로 내보낼게 라는 뜻</strong></p>
<blockquote>
<pre><code class="language-jsx">//index.js
import multiply from &quot;./math.js&quot;;
import mul from &quot;./math.js&quot;;</code></pre>
</blockquote>
<pre><code>
mul이라고 적어도 알아먹음. 

#### ✅ 여러 개 내보낼 땐 `named export`를 쓰고, 이름이 기본적으로 고정

- `export const add = ...` 처럼 이름 붙여서 내보내면
- `import { add } from ...` 처럼 **그 이름으로** 가져와야 해.

&gt;```jsx
//동일한 경로로 부터 import문이 여러개라면 합쳐서 사용도 가넝
import mul, { add, sub } from &quot;./math.js&quot;;</code></pre><h4 id="🤔그럼-왜-default는-이름을-자유롭게-해놨을까">🤔그럼 왜 default는 이름을 자유롭게 해놨을까?</h4>
<p>“이 파일에서 대표로 하나만 내보내는 거니까”</p>
<p>가져오는 사람이 <strong>원하는 컨벤션에 맞게 이름을 맞출 수 있게</strong> 해준 거.</p>
<hr>
<h1 id="라이브러리-사용">라이브러리 사용</h1>
<h2 id="🔸dayjs">🔸Day.js</h2>
<p><a href="https://www.npmjs.com/">https://www.npmjs.com/</a></p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/4c503c6c-429f-4409-985d-9eafc8590e7a/image.png" alt=""></p>
<p>install에 적힌 명령어를 내 터미널에 적어주면 댐</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/af1ac161-f210-4d46-80bc-8f51469e7042/image.png" alt=""></p>
<p>그럼 라이브러리가 잘 설치 되었다고 알람이 뜨면서</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/d02ba247-4045-4b18-8b4f-c4819a06d394/image.png" alt=""></p>
<p>랜덤컬러라는 라이브러리의 버전이 표시댐</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/b3c793e1-baf3-4328-bad0-a3fc31da4a5e/image.png" alt=""></p>
<ul>
<li><p>node_modules</p>
<ul>
<li><p>라이브러리가 저장되는곳</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/f6227e8e-bb3a-4558-8911-c15e816d1c60/image.png" alt=""></p>
</li>
</ul>
</li>
</ul>
<ul>
<li>package-lock.json<ul>
<li>패키지가 사용하는 정확한 정보를 저장하고있음</li>
</ul>
</li>
</ul>
<p>package.js(기존) 과 package-lock.json(라이브러리생성후)의 차이는??</p>
<p>⇒package-lock.json는 정확한 버전이 올라감</p>
<blockquote>
<pre><code class="language-jsx">//package.js
&quot;dependencies&quot;: {
    &quot;randomcolor&quot;: &quot;^0.6.2&quot;
  }
</code></pre>
</blockquote>
<p>  //package-lock.json
&quot;node_modules/randomcolor&quot;: {
      &quot;version&quot;: &quot;0.6.2&quot;,
      &quot;resolved&quot;: &quot;<a href="https://registry.npmjs.org/randomcolor/-/randomcolor-0.6.2.tgz&quot;">https://registry.npmjs.org/randomcolor/-/randomcolor-0.6.2.tgz&quot;</a>,
      &quot;integrity&quot;: &quot;sha512-Mn6TbyYpFgwFuQ8KJKqf3bqqY9O1y37/0jgSK/61PUxV4QfIMv0+K2ioq8DfOjkBslcjwSzRfIDEXfzA9aCx7A==&quot;
    }</p>
<p><code>^</code> → Version Range(버전 범위) 대략적인 버전이라는 뜻</p>
<p>✅응용하기</p>
<p>라이브러리에서 가져올때는 from 뒤에 경로를 적는게 아니라 <code>라이브러리 이름</code>을 적어야함.</p>
<blockquote>
<pre><code class="language-jsx">//randomcolor 라이브러리에 있는 기본값 불러오기
import randomcolor from &quot;randomcolor&quot;;
</code></pre>
</blockquote>
<p>const color = randomcolor();
console.log(color);</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/ac24e251-67ce-4fdd-b1c2-0d588b0264b9/image.png" alt=""></p>
<p>그러면 랜덤컬러가 잘 나옴</p>
<h2 id="🔸npm-instal라이브러리-지워졌을때">🔸<code>npm instal</code>라이브러리 지워졌을때</h2>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/17159cfc-5249-4c04-a422-85929dde3ff4/image.png" alt=""></p>
<blockquote>
<pre><code class="language-jsx">//package.js
&quot;dependencies&quot;: {
    &quot;randomcolor&quot;: &quot;^0.6.2&quot;
  }</code></pre>
</blockquote>
<p>package.js에 정보만 가지고 있다면 원래 다시 설치 가넝</p>
<p> 터미널에 <code>npm instal</code>  혹은 <code>npm i</code> 입력하면</p>
<p>package.js에 설치된 버전을 기준으로 다시 등록해줌 → 파일 생성 완!</p>
<p>⇒ 다른사람과 공유하거나 업로드할때는 <code>node_modules</code> 파일을 공유하지 않음! 파일 크기도 크고 재설치가 가능하기때문에~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript 기초2]]></title>
            <link>https://velog.io/@kimjiji_0/Javascript-%EA%B8%B0%EC%B4%882</link>
            <guid>https://velog.io/@kimjiji_0/Javascript-%EA%B8%B0%EC%B4%882</guid>
            <pubDate>Tue, 06 Jan 2026 18:36:02 GMT</pubDate>
            <description><![CDATA[<h2 id="🔸연산자">🔸연산자</h2>
<h3 id="🔹대입-연산자">🔹대입 연산자</h3>
<p><code>=</code>는 <strong>오른쪽 값을 왼쪽 변수에 넣는 것</strong>.</p>
<blockquote>
<pre><code class="language-jsx">let var1 = 1;
var1 = 20;       // var에 20으로 다시 넣음(값 바뀜)</code></pre>
</blockquote>
<pre><code>
### 🔹산술 연산자

***  , / , %**  는 +, -보다 우선순위!

&gt;```jsx
let num1 = 3 + 2;
let num2 = 3 - 2;
let num3 = 3 * 2;
let num4 = 3 / 2;
let num5 = 3 % 2;
&gt;
let num6 = 1 + 2 * 10; // 21출력
let num6 = (1 + 2) * 10; //소괄호 먼저 계산 30출력</code></pre><h3 id="🔹복합-대입-연산자산술--대입">🔹복합 대입 연산자(산술 + 대입)</h3>
<p><code>x += 3</code>  는  <code>x = x + 3</code>  이랑 똑같다</p>
<blockquote>
<pre><code class="language-jsx">let x = 10;
</code></pre>
</blockquote>
<p>x += 3;  // x = x + 3  → 13
x -= 2;  // x = x - 2  → 11
x *= 5;  // x = x * 5  → 55
x /= 11; // x = x / 11 → 5
x %= 2;  // x = x % 2  → 1</p>
<pre><code>
### 🔹증감 연산자

(`++`, `--`)는 **“1씩 더하기/빼기”**를 짧게 쓰는 거

1. 기본 뜻
- `x++` : x를 **1 증가**
- `x--` : x를 **1 감소**
- `++x` : x를 **1 증가**
- `-x` : x를 **1 감소**

&gt;```jsx
let num8 = 10;
num++;
console.log(num8);
&gt;
//만약 바로 증감하고 싶다면
console.log((num8 += 1));
console.log(++num8);</code></pre><h4 id="1-전위-연산-x">1. 전위 연산 ++x</h4>
<p><strong>먼저</strong> 1 증가하고, 증가된 값 쓰기</p>
<blockquote>
<pre><code class="language-jsx">    let x = 5;
    console.log(++x); // 6 출력 (먼저 올리고)
    console.log(x);   // 6

    let a = 3;
    let b = ++a;
    console.log(a, b); // 4,4
    실행 순서
    a = a + 1; // a는 4가 됨
    그 다음 b = a; // b는 4
    ```</code></pre>
</blockquote>
<h4 id="2-후위-연산-x">2. 후위 연산 <strong><code>x++</code></strong></h4>
<p>일단 지금 값 쓰고, <strong>나중에</strong> 1 증가</p>
<blockquote>
<pre><code class="language-jsx">    let x = 5;
    console.log(x++); // 5 출력 (일단 5를 쓰고)
    console.log(x);   // 6 (그 다음 증가됨)
</code></pre>
</blockquote>
<pre><code>let a = 3;
let b = a++;      
console.log(a, b); // 4,3
&gt;
실행 순서
b = a 먼저 됨 → b는 3
그 다음 a가 1 증가 → a는 4
```</code></pre><h4 id="4-후위-감소-x--">4. 후위 감소 x--</h4>
<blockquote>
<pre><code class="language-jsx">let x =5;
console.log(x--);// 5
console.log(x);// 4</code></pre>
</blockquote>
<h4 id="5-전위-감소--x">5. 전위 감소 -x</h4>
<blockquote>
<pre><code class="language-jsx">let x =5;
console.log(--x);// 4
console.log(x);// 4</code></pre>
</blockquote>
<pre><code>
### 🔸논리 연산자

1. `||` (OR, 또는)

&gt;```jsx
// 하나만 참이여도 true
let or = true || false;</code></pre><ol start="2">
<li><code>&amp;&amp;</code> (AND, 그리고)</li>
</ol>
<blockquote>
<pre><code class="language-jsx">// 두개 값이 true여야지 true
let and = true &amp;&amp; false;</code></pre>
</blockquote>
<pre><code>
3. `!` (NOT, 반대)

&gt;```jsx
//!true → false
//!false → true
let not = !true;</code></pre><h3 id="🔸비교-연산자">🔸비교 연산자</h3>
<h4 id="1-크기-비교">1) 크기 비교</h4>
<ul>
<li><code>&gt;</code> : 크다</li>
<li><code>&lt;</code> : 작다</li>
<li><code>&gt;=</code> : 크거나 같다 (이상)</li>
<li><code>&lt;=</code> : 작거나 같다 (이하)</li>
</ul>
<blockquote>
<pre><code class="language-jsx">10 &gt;3 // true
10 &lt;3 // false
10 &gt;=10 // true
9 &lt;=10 // true</code></pre>
</blockquote>
<pre><code>

#### 2) 같은지 비교

✅ 가장 추천: `===` (엄격 비교)

**값도 같고, 타입도 같아야 true**

&gt;```jsx
10 ===10// true
10 ===&quot;10&quot;// false (숫자, 문자형이라 타입 다름)


⚠️ `==` (느슨 비교)

타입이 다르면 자바스크립트가 **자동으로 형변환**해서 비교. 그래서 헷갈릴 수 있음.

&gt;```jsx
10 ==&quot;10&quot;// true (자동 변환해서 같다고 봄)
0 ==false// true
&quot;&quot; ==0// true
null ==undefined// true



초반엔 **웬만하면 `===`만 쓰면 안전**.

---

#### ~~3) 같지 않다(다르다)~~

- `!==` : 엄격하게 다름(추천)
- `!=` : 느슨하게 다름(자동 변환 있음)

&gt;```jsx
10 !==&quot;10&quot;// true
10 !=&quot;10&quot;// false (자동변환 때문에 같다고 봄)</code></pre><hr>
<h4 id="4-문자열-비교도-가능사전-순서-느낌">4) 문자열 비교도 가능(사전 순서 느낌)</h4>
<blockquote>
<pre><code class="language-jsx">&quot;b&quot; &gt;&quot;a&quot;// true
&quot;10&quot; &gt;&quot;2&quot;// false  (문자열이라 글자 순서로 비교됨!)</code></pre>
</blockquote>
<pre><code>
그래서 숫자 비교는 문자열 말고 **숫자로 바꿔서** 하는 게 좋음:

`&quot;10&quot; &gt; &quot;2&quot;` 가 false인 이유 (여기서 헷갈림 포인트!)

이건 숫자 10과 2를 비교하는 게 아니라, 문자열 `&quot;10&quot;`과 `&quot;2&quot;`를 비교하는 거라서 **첫 글자부터 비교**하는것.

&gt;한 글자씩 비교 과정
&gt;
- `&quot;10&quot;`의 첫 글자: **&quot;1&quot;**
- `&quot;2&quot;`의 첫 글자: **&quot;2&quot;**
&gt;
사전/문자 순서로 보면 `&quot;1&quot;`은 `&quot;2&quot;`보다 앞이니까,
&gt;
- `&quot;1&quot; &lt; &quot;2&quot;`
&gt;
    그래서 전체도
&gt;
- `&quot;10&quot; &lt; &quot;2&quot;` 가 됨 → 즉 `&quot;10&quot; &gt; &quot;2&quot;`는 **false**
&gt;
여기서 `&quot;0&quot;`까지 볼 필요도 없음. **첫 글자에서 이미 끝**!

&gt;```jsx
Number(&quot;10&quot;) &gt;Number(&quot;2&quot;)// true</code></pre><h3 id="🔹null-병합-연산자-">🔹null 병합 연산자 <code>??</code></h3>
<p>null, undefined가 아닌 값을 찾아내는 연산자</p>
<blockquote>
<pre><code class="language-jsx">let var1;
let var2 = 10;
let var3 = 20;
</code></pre>
</blockquote>
<p>let var4 = var1 ?? var2; //10
let var5 = var1 ?? var3; //20
let var6 = var3 ?? var2; //20</p>
<p>//만약 둘다 undefined가 아니면 첫번째 값이 나옴</p>
<blockquote>
<pre><code>let var6 = var2 ?? var3; //10</code></pre></blockquote>
<pre><code>

만약 둘다 undefined가 아니면 첫번째 값이 나옴

### 🔑꿀팁! 회원관리

유저네임이 있으면 유저네임이 나오는거고 없으면 닉네임이 나오는것

&gt;```jsx
let userName;
let userNickName = &quot;Winterlood&quot;;
&gt;
let displayName = userName ?? userNickName; //Winterlood</code></pre><h3 id="🔹typeof-연산자">🔹typeof 연산자</h3>
<p>‘이 값의 타입이 뭐야?’하고 물어보는것 결과는 항상 문자열로 나옴</p>
<blockquote>
<pre><code class="language-jsx">typeof 10        // &quot;number&quot;
typeof &quot;hi&quot;      // &quot;string&quot;
typeof true      // &quot;boolean&quot;
</code></pre>
</blockquote>
<p>//예시
let x = &quot;hello&quot;;
console.log(typeof x); // &quot;string&quot;</p>
<blockquote>
</blockquote>
<p>x = 10;
console.log(typeof x); // &quot;number&quot;</p>
<blockquote>
</blockquote>
<p>x = true;
console.log(typeof x); // &quot;boolean&quot;</p>
<pre><code>
### 🔹 삼항 연산자

항을 3개 사용하는 연산자

#### 기본 형태

&gt;```jsx
조건 ? 참일때값 : 거짓일때값
&gt;
let age = 20;
&gt;
let msg = age &gt;= 19 ? &quot;성인&quot; : &quot;미성년&quot;;
console.log(msg); // &quot;성인&quot;
//age가 19이상이야?하고 물어보는것
&gt;
//if/else로 적었다면?
let msg;
if (age &gt;= 19) msg = &quot;성인&quot;;
else msg = &quot;미성년&quot;;</code></pre><ul>
<li>조건이 <strong>true</strong>면 → <code>?</code> 뒤의 값</li>
<li>조건이 <strong>false</strong>면 → <code>:</code> 뒤의 값</li>
</ul>
<p>예시</p>
<blockquote>
<pre><code class="language-jsx">let var8 = 10;
</code></pre>
</blockquote>
<p>// 요구사항 : 변수 res에 var8의 값이 짝수 -&gt; &quot;짝&quot;, 홀수 -&gt; &quot;홀&quot;
let res = var8 % 2 === 0 ? &quot;짝수&quot; : &quot;홀수&quot;;
console.log(res);</p>
<p>```</p>
<p>🤔여기서 헷갈린게 10 % 2면 5인데 왜 짝수 홀수이지? 하는 의문이 듬</p>
<p>-&gt; 근데 여기서 <code>%</code> 는 <strong>나머지</strong> 연산자.</p>
<blockquote>
<p><code>10 % 2</code> 는 “10을 2로 나눴을 때 나머지</p>
</blockquote>
<p>사탕 10개를 2명에게 <strong>똑같이</strong> 나눠주면:</p>
<blockquote>
</blockquote>
<ul>
<li>한 명당 <strong>5개(몫)</strong> 받고</li>
<li>남는 사탕은 <strong>0개(나머지)</strong><blockquote>
</blockquote>
그래서 <code>10 % 2</code>는 0.<blockquote>
</blockquote>
그래서 <code>11 % 2</code>는 1</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript 기초1]]></title>
            <link>https://velog.io/@kimjiji_0/Javascript-%EA%B8%B0%EC%B4%881</link>
            <guid>https://velog.io/@kimjiji_0/Javascript-%EA%B8%B0%EC%B4%881</guid>
            <pubDate>Tue, 06 Jan 2026 18:22:49 GMT</pubDate>
            <description><![CDATA[<p>이해하기 쉽게 정리하기</p>
<h2 id="🔸변수">🔸변수</h2>
<p><code>let</code>은 <strong>재할당 가능</strong>, 대신 <strong>재선언 불가</strong></p>
<blockquote>
<pre><code class="language-jsx">let age;
console.log(age); // undefined
age = 30;
console.log(age); // 30
age = 40;         // ✅ 재할당(값 변경)
console.log(age); // 40</code></pre>
</blockquote>
<p>let age는 선언한다 27은 초기화한다라는 뜻</p>
<p>그래서 27은 앞으로 age인것임</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/2f07d180-c024-4913-bb1e-d364403f9444/image.png" alt=""></p>
<blockquote>
<p>🤔Q. age = 30;이라고 선언한다면?
console.log(age); -&gt; 30!!</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/7f4e6438-6958-4435-8ab2-0d62946b6035/image.png" alt=""></p>
<pre><code class="language-jsx">{
let age = 30;
console.log(age); // 30 (안쪽 방 age)
}</code></pre>
<p>→ 이 경우는 { }안에 선언한다면 가능함</p>
<h2 id="🔸상수">🔸상수</h2>
<p>const은 <strong>재할당 불가능</strong></p>
<p>let은 내용없이 선언이 됐지만 const는 반드시 초기화값을 정해줘야함</p>
<blockquote>
<pre><code class="language-jsx">const age = 30;
age = 40; // ❌ 에러! (다른 값으로 갈아끼우기 불가)</code></pre>
</blockquote>
<pre><code>
- `let age = 30; age = 40;` ✅ (값 변경)
- `let age = 30; let age = 40;` ❌ (재선언)

- `const age = 30; age = 40;` ❌ (재할당)
- `const age = 30; const age = 40;` ❌ (재선언)

## 🔸명명규칙(이름 짓기)

### 1. $(달러),_(언더스코어)를 제외한 기호는 사용 할 수 없다.

&gt;```jsx
어디를 위치해도 절때 사용이 안됨.
let #name
let na#me
let name#</code></pre><h3 id="2-숫자로-시작-할-수-없다">2. 숫자로 시작 할 수 없다.</h3>
<blockquote>
<pre><code class="language-jsx">숫자로 사용하고 싶다면 이름의 중간이나 끝에만 사용가넝
let name1; &lt;가능
let 1name; &lt;불가능
정 숫자를 먼저 사용해야겠으면 `$,_`먼저쓰기
let _1name;
let $1name;</code></pre>
</blockquote>
<h3 id="3-예약어를-사용-할-수-없다">3. 예약어를 사용 할 수 없다.</h3>
<blockquote>
<pre><code class="language-jsx">let let = 3;       // ❌ let은 이미 &#39;변수 선언&#39; 의미
const if = 10;     // ❌ if는 조건문
let function = 1;  // ❌ function은 함수 선언
let class = &quot;a&quot;;   // ❌ class는 클래스</code></pre>
</blockquote>
<pre><code>
# 자료형(Type)집합
## 🔸원시타입

프로그래밍에 있어서 가장 기본적인 값들의 타입

### 1. Number Type

사칙연산이 가능함! = 모듈러 연산

자바스크립트는 신기하게도 **정수(10)랑 소수(3.14)를 따로 구분하지 않고** 다 `Number`로 담음.

&gt;```jsx
let a =10;// 정수
let b =3.14;// 소수
// 둘 다 Number 타입</code></pre><h3 id="2-계산도-가능">2) 계산도 가능</h3>
<blockquote>
<pre><code class="language-jsx">let x =5;
let y =2;
</code></pre>
</blockquote>
<p>x + y;// 7
x - y;// 3
x * y;// 10
x / y;// 2.5</p>
<pre><code>
### 3) 특이한 숫자 3총사도 Number에 포함돼요

자바스크립트엔 “이상한 숫자”가 있는데 이것들도 `Number`.

#### 🔹Infinity (무한대)

&gt;```jsx
let inf = Infinity</code></pre><h4 id="🔹-infinity-음의-무한대">🔹-Infinity (음의 무한대)</h4>
<blockquote>
<pre><code class="language-jsx">let mInf = -Infinity;</code></pre>
</blockquote>
<pre><code>
#### 🔹NaN (Not a Number인데 타입은 Number…)

“숫자가 나와야 하는데 숫자가 아닌 결과”가 나오면 `NaN`.

연산이 실패했을때 no 넘버라는 뜻

&gt;```jsx
&quot;abc&quot; *3;// NaN</code></pre><p>이름은 “숫자 아님”인데, 자바스크립트에서는 Number 타입으로 취급돼서 처음엔 많이 헷갈림.</p>
<h3 id="4-숫자인지-확인하는-방법자주-씀"><del>4) 숫자인지 확인하는 방법(자주 씀)</del></h3>
<p>지금 듣고있는 강의에서 넘기셔서 따로 공부해서 적기</p>
<blockquote>
<pre><code class="language-jsx">Number.isNaN(NaN);// true
Number.isFinite(10);// true
Number.isFinite(Infinity);// false</code></pre>
</blockquote>
<pre><code>
### 🔹String Type

덧셈 연산도 지원함

&gt;```jsx
let myName = &quot;지지&quot;;</code></pre><p>이름을 적을때는 반드시 “” 따옴표 안에 넣어야함! 안그러면 변수로 알아먹어버림</p>
<h3 id="1-string-만들기-따옴표로-감싸면-문자열">1) String 만들기: 따옴표로 감싸면 문자열!</h3>
<p>문자열은 <strong>작은따옴표(&#39; &#39;)</strong>, <strong>큰따옴표(&quot; &quot;)</strong>, <strong>백틱( ``)</strong> 으로 만들 수 있음.</p>
<blockquote>
<pre><code class="language-jsx">let a =&quot;안녕&quot;;
let b =&#39;지지&#39;;
let c =`반가워`;</code></pre>
</blockquote>
<pre><code>
### 2) 문자열 더하기(붙이기)

숫자처럼 더하는 게 아니라 **글자를 붙이는 것**.

&gt;```jsx
&quot;안녕&quot; +&quot;지지&quot;;// &quot;안녕지지&quot;
&quot;안녕&quot; +&quot; &quot; +&quot;지지&quot;;// &quot;안녕 지지&quot;</code></pre><h3 id="3-숫자랑-문자열을-더하면-→-문자열이-이김">3) 숫자랑 문자열을 더하면? → 문자열이 이김!</h3>
<blockquote>
<pre><code class="language-jsx">&quot;10&quot; +1;// &quot;101&quot;  (붙여버림)
10 +&quot;1&quot;;// &quot;101&quot;</code></pre>
</blockquote>
<p>그래서 계산하려면 숫자로 바꾸기:</p>
<blockquote>
<pre><code class="language-jsx">Number(&quot;10&quot;) +1;// 11</code></pre>
</blockquote>
<pre><code>
### 4) 백틱(``)은 문자열에 값을 넣기 편해요 (템플릿 리터럴 = 백틱)

&gt;```jsx
🔹기존은 + 로 붙여야해서 번거러움
let name = &quot;지지&quot;;
let age = 20;
&gt;
&quot;이름은 &quot; + name + &quot;, 나이는 &quot; + age;
&gt;
🔹백틱을 쓴다면 깔끔!
let name =&quot;지지&quot;;
let age =20;
&gt;
`이름은 ${name}, 나이는${age}`;
// &quot;이름은 지지, 나이는 20&quot;</code></pre><h3 id="5-문자열-길이글자-수">5) 문자열 길이(글자 수)</h3>
<blockquote>
<pre><code class="language-jsx">&quot;hello&quot;.length;// 5</code></pre>
</blockquote>
<pre><code>
### 🔸Boolean Type

상태표시

참/거짓만 담는 타입

&gt;```jsx
let a = true;   &lt;- //맞긴하지만 코드읽는사람이 바로 안읽힘
let b = false;  &lt;- //
let isSwitchOn = true; // 읽자마자 “스위치 켜져있어?” 느낌
let hasMoney = false;  // “돈 있어?”
let isEmpty = true;    // “비어 있어?”</code></pre><p>이 6개는 <strong>무조건 false 취급</strong>:</p>
<ul>
<li><code>false</code></li>
<li><code>0</code></li>
<li><code>&quot;&quot;</code> (빈 글자)</li>
<li><code>null</code></li>
<li><code>undefined</code></li>
<li><code>NaN</code></li>
</ul>
<blockquote>
<pre><code class="language-jsx">let pw = &quot;&quot;;
</code></pre>
</blockquote>
<p>if (pw) {
  console.log(&quot;통과&quot;);
}</p>
<p>출력이 안됨!</p>
<h3 id="🔸null-type-아무것도-없다">🔸Null Type (아무것도 없다)</h3>
<p><strong>null = 휴지심만 있는 상태</strong> ✅ (일부러 “없다”는 표시를 해둔 상태)</p>
<blockquote>
<pre><code class="language-jsx">let empty = null;</code></pre>
</blockquote>
<pre><code>
### 🔸Undefined Type 아직 안 정해짐(안 넣었음)

변수 상자를 만들어놨는데 **아직 아무것도 안 넣은 상태**

**undefined = 휴지조차 없는 상태** ✅ (아직 아무 설정/값이 없음)

&gt;```jsx
let none;
&gt;
let x;           // 상자만 만들고
console.log(x);  // undefined (비어있음)
&gt;
let x;           // 상자만 만들고
console.log(x);  // undefined (비어있음)</code></pre><h2 id="형-변환type-casting">형 변환(Type Casting)</h2>
<h3 id="🔸묵시적-형-변환">🔸묵시적 형 변환</h3>
<p>자바스크립트가 알아서 형변환하는거</p>
<ol>
<li><code>+</code>는 <strong>문자열이 한 명이라도 섞이면</strong> “붙이기 모드”</li>
</ol>
<blockquote>
<pre><code class="language-jsx">let num = 10;
let str = &quot;20&quot;;
</code></pre>
</blockquote>
<p>const result = num + str;</p>
<blockquote>
</blockquote>
<p>=&gt; 1020</p>
<pre><code>
2. `-`, `*`, `/`는 “붙이기”가 아니라 계산!

&gt;```jsx
&quot;10&quot; - 1   // 9
&quot;10&quot; * 2   // 20
&quot;10&quot; / 2   // 5</code></pre><ol start="3">
<li><code>==</code>는 “대충 같으면 같다” 모드라서 자동 변환 (조심해야함!)</li>
</ol>
<blockquote>
<pre><code class="language-jsx">&quot;1&quot; == 1   // true  (문자 &quot;1&quot;을 숫자 1처럼 봄)
0 == false // true
&quot;&quot; == 0    // true
null == undefined // true
</code></pre>
</blockquote>
<p>그래서 ===을 쓰는게 좋음
&quot;1&quot; === 1  // false (타입이 달라서)</p>
<h3 id="🔸명시적-형-변환">🔸명시적 형 변환</h3>
<p>개발자가 함수를 이용해서 변환함</p>
<p>문자열 -&gt; 숫자(String → Number)</p>
<p><strong>Number()</strong></p>
<p><code>parseInt()</code> 글자를 제외하고 숫자로 바꿀때</p>
<blockquote>
<pre><code class="language-jsx">//문자열을 숫자로 바꿀때
let str1 = &quot;10&quot;;
let strToNum1 = Number(str1);
console.log(strToNum1);     // 숫자 10이 출력돼요
</code></pre>
</blockquote>
<p>//글자를 제외하고 숫자로 바꿀때
let str2 = &quot;10개&quot;;
let strToNum2 = parseInt(str2);
console.log(strToNum2);     // 숫자 10이 출력돼요</p>
<pre><code>
숫자 -&gt; 문자열

**String()**

&gt;```jsx
let num1 = 20;
let numToStr1 = String(num1);
&gt;
console.log(numToStr1 + &quot;입니다&quot;);</code></pre><ul>
<li><p>내가 헷갈린거</p>
<h3 id="띄어쓰기를-원하면-띄어쓰기-문자도-직접-넣어야-해요">띄어쓰기를 원하면, 띄어쓰기 문자도 직접 넣어야 해요</h3>
<h4 id="방법-1-문자열에-공백-넣기">방법 1) 문자열에 공백 넣기</h4>
<blockquote>
<pre><code class="language-jsx">  console.log(numToStr1 +&quot; 입니다&quot;);// &quot;20 입니다&quot;</code></pre>
</blockquote>
<pre><code>
  #### 방법 2) 중간에 공백 문자열을 더하기

  &gt;```jsx
  console.log(numToStr1 +&quot; &quot; +&quot;입니다&quot;);// &quot;20 입니다&quot;</code></pre><h4 id="방법-3-백틱템플릿-리터럴로-쓰기추천">방법 3) 백틱(템플릿 리터럴)로 쓰기(추천)</h4>
<blockquote>
<pre><code class="language-jsx">  console.log(`${numToStr1} 입니다`);// &quot;20 입니다&quot;</code></pre>
</blockquote>
</li>
</ul>
<p>   “숫자랑 문자 같이 나오면 자동으로 띄어쓰기?”는 언제냐?</p>
<pre><code>-&gt; 그건 `console.log`에 **쉼표로 여러 개를 넣을 때**!!!

이 경우는 콘솔이 보기 좋게 띄어쓰기처럼 보여줌.

&gt;```jsx
console.log(numToStr1,&quot;입니다&quot;);// 보통 &quot;20 입니다&quot;처럼 보임
```

나는 `+`로 **문자열을 합친 하나의 값**을 만든 거라서 자동 공백이 없었던것.</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[마우스 이벤트]]></title>
            <link>https://velog.io/@kimjiji_0/%EB%A7%88%EC%9A%B0%EC%8A%A4-%EC%9D%B4%EB%B2%A4%ED%8A%B8</link>
            <guid>https://velog.io/@kimjiji_0/%EB%A7%88%EC%9A%B0%EC%8A%A4-%EC%9D%B4%EB%B2%A4%ED%8A%B8</guid>
            <pubDate>Wed, 15 Oct 2025 14:01:15 GMT</pubDate>
            <description><![CDATA[<p>hover이벤트 사용시 마우스가 영역을 벗어날 때 클래스가 빠르게 추가/제거되며 번쩍이는 현상이 발생</p>
<p><strong>🤔button의 영역은 충분한데 왜?</strong>
-&gt; 팝업/내용이 숨겨지면 마우스는 다시 버튼 위에 있거나 버튼과 팝업 사이의 빈 공간 위에 있게 되고, 이 과정이 매우 빠르게 반복되며 번쩍이는 현상이 발생!!</p>
<p>처음에는 <code>mouseover</code>를 이용해서 작업했지만 반복되는 오류</p>
<h2 id="📌-mouseenter-mouseleave">📌 mouseenter, mouseleave</h2>
<blockquote>
<p><code>mouseenter()</code> 이벤트 메서드 는 대상 요소의 경계 범위에 마우스 포인터가 들어오면 이벤트를 발생시킴.
<code>mouseleave()</code> 이벤트 메서드 는 대상 요소의 경계 범위에서 마우스 포인터가 완전히 벗어나면 이벤트를 발생시킴.</p>
</blockquote>
<h3 id="eventrelatedtarget">event.relatedTarget</h3>
<p>: 마우스가 떠난 직후 포커스 또는 호버 상태가 되는 요소를 나타냅니다.</p>
<h3 id="eventrelatedtargetclosest">$(event.relatedTarget).closest(&#39;...&#39;)</h3>
<p>: 마우스가 떠난 곳이 버튼 또는 감싸는 요소(footer-pop-wrap) 안인지 확인</p>
<h3 id="--length">! ... .length</h3>
<p>: 마우스가 떠난 곳이 지정된 영역(버튼 또는 팝업 영역)의 바깥인 경우에만 true가 됩니다.</p>
<table>
<thead>
<tr>
<th></th>
<th>mouseover</th>
<th>mouseenter</th>
</tr>
</thead>
<tbody><tr>
<td>자식 요소</td>
<td>자식 요소 진입 시에도 이벤트가 발생 (자식 요소에 포커스 이동 시)</td>
<td>자식 요소 진입 시에는 이벤트가 발생하지 않음</td>
</tr>
<tr>
<td>이벤트 전파</td>
<td>버블링(Bubbling) O (부모 요소로 전파됨)</td>
<td>버블링(Bubbling) X (부모 요소로 전파되지 않음)</td>
</tr>
</tbody></table>
<blockquote>
</blockquote>
<p>mouseleave 해당영역의 부모영역을 기준으로 작업함</p>
<blockquote>
<pre><code class="language-java">$(&#39;.footer-pop&#39;).mouseleave(function(e){
        if(!$(e.relatedTarget).closest(&#39;.footer-pop&#39;).length) {
        $(&#39;.footer-pop-cont&#39;).removeClass(&#39;on&#39;);
        }
    })</code></pre>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[깃허브 커밋오류]]></title>
            <link>https://velog.io/@kimjiji_0/%EA%B9%83%ED%97%88%EB%B8%8C-%EC%BB%A4%EB%B0%8B%EC%98%A4%EB%A5%98</link>
            <guid>https://velog.io/@kimjiji_0/%EA%B9%83%ED%97%88%EB%B8%8C-%EC%BB%A4%EB%B0%8B%EC%98%A4%EB%A5%98</guid>
            <pubDate>Tue, 29 Jul 2025 12:27:14 GMT</pubDate>
            <description><![CDATA[<p>랜딩페이지의 고화질 동영상때문에 인코딩이 너무 느려 오류처럼 보이는 현상을 수정하다보니 커밋오류ㅠ</p>
<blockquote>
<p>&#39;참조를 원격에 푸시할 수 없습니다. 먼저 &#39;풀 을 실행하여 변경 내용을 통합하세요&#39;
라는 오류 발생</p>
</blockquote>
<p>🤔검색했을때 해결방법</p>
<ol>
<li>동영상 파일 크기 50MB로 낮추기
<del>2. 새로 깃허브 파일 올리기</del></li>
</ol>
<p>파일 크기를 낮춰도 똑같은 오류 발견!
로컬 저장소의 <strong>변경 내용</strong>이 원격 저장소의 내용과 <strong>충돌</strong>해서 발생한 문제!</p>
<h2 id="✔-해결방안">✔ 해결방안</h2>
<h4 id="1-vs-code-터미널에서-명령어git-status로컬-변경-사항-확인">1. VS Code 터미널에서 명령어<code>git status</code>로컬 변경 사항 확인</h4>
<p>&#39;On branch main Your branch is ahead of &#39;origin/main&#39; by 2 commits.(use &quot;git push&quot; to publish your local commits) nothing to commit, working tree clean&#39;
<img src="https://velog.velcdn.com/images/kimjiji_0/post/9ce0916c-1b6e-4178-b5ab-b50b1a828a10/image.png" alt=""></p>
<p>)
<code>main 브랜치</code>와 <code>origin/main 브랜치</code>가 분리된것!
로컬 main 브랜치에 아직 원격 저장소에 푸시되지 않은 커밋(동영상크기조절)이 존재한다는 뜻
-&gt; 오류 때문에 푸시가 되지 않아 생긴 결과</p>
<h4 id="2-불필요한-파일-삭제-되었는지-확인">2. 불필요한 파일 삭제 되었는지 확인</h4>
<h4 id="3-명령어-git-push-origin-main">3. 명령어 <code>git push origin main</code></h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[[💻] 실습 - 엔터프라이즈블록체인]]></title>
            <link>https://velog.io/@kimjiji_0/%EC%97%94%ED%84%B0%ED%94%84%EB%9D%BC%EC%9D%B4%EC%A6%88%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8</link>
            <guid>https://velog.io/@kimjiji_0/%EC%97%94%ED%84%B0%ED%94%84%EB%9D%BC%EC%9D%B4%EC%A6%88%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8</guid>
            <pubDate>Wed, 09 Apr 2025 14:04:15 GMT</pubDate>
            <description><![CDATA[<h2 id="📖-overview">📖 Overview</h2>
<p>사이트명: 엔터프라이즈블록체인
작업 기간: 5일 소요
라이브러리: swiper, jQuery, gsap
유형: PC적응형, 클론 코딩
참여도: 100%</p>
<h3 id="👀-check-point">👀 Check-point</h3>
<p>GSAP + ScrollTrigger를 활용한 애니메이션 구현
ScrollTrigger의 pin 속성
유연한 가로세로 스크롤, 콜백이벤트</p>
<hr>
<h3 id="📌-width값-고정">📌 width값 고정</h3>
<p>PC만 지원하도록 만들었기 때문에, 최소너비를 1300픽셀로 잡아주었다. 이때, 컨텐츠의 수평 스크롤영역 때문에 가로스크롤이 생길 위험을 낮추기 위해 overflow-x:hidden을 사용했다.</p>
<blockquote>
<pre><code class="language-css">.wrap {
    position: relative;
    min-width: 1440px;
    overflow-x: hidden;
}</code></pre>
</blockquote>
<pre><code>
### 📌 pin 속성
스크롤 도중 특정 요소를 화면에 **고정**시키는 기능
#### ✏ pin: true
&gt;```java
gsap.to(&quot;.sc-box&quot;, {
  scrollTrigger: {
    trigger: &quot;.box&quot;, // 고정할 타겟
    start: &quot;top top&quot;, 
    end: &quot;bottom top&quot;,
    pin: true, // 고정
    markers: true
  }
});</code></pre><p><strong>✅ pinSpacing</strong></p>
<blockquote>
<p><strong>true</strong> → 기본값, 고정된 요소만큼 공간 확보
<strong>false</strong> → 고정이 될때 다른 요소들이 겹쳐 올라가거나 여백이 생길 수 있음, 없애고 싶을때 사용</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/f327e974-aa8f-4367-a17d-8742d76ed1f3/image.gif" alt=""></p>
<blockquote>
<pre><code class="language-java">// 가로스크롤 sc-possibility
    ScrollTrigger.create({
      animation:economyTl,
      // markers:true,
      trigger:&#39;.sc-economy&#39;,
      start:&#39;0 0&#39;,
      end:&#39;+=1500&#39;,
      pin:true,
      scrub:0,
      invalidateOnRefresh:true,
      onEnter:function(){
        $(&#39;.sc-economy .card-item&#39;).addClass(&#39;blur&#39;)
        $(&#39;.sc-economy .arrow-area&#39;).addClass(&#39;on&#39;)
        },
        onEnterBack:function(){
        $(&#39;.sc-economy .arrow-area&#39;).addClass(&#39;on&#39;)
        },
        onLeave:function(){
        $(&#39;.sc-economy .arrow-area&#39;).removeClass(&#39;on&#39;)
        },
        onLeaveBack:function(){
        $(&#39;.sc-economy .arrow-area&#39;).removeClass(&#39;on&#39;)
        }
    })</code></pre>
</blockquote>
<pre><code>
영역에 들어갔을때 진행되도록 &#39;onEnter&#39;이벤트 사용


### 📌 이벤트 콜백 함수(Event Callback Functions)
특정 요소가 뷰포트(Viewport)에 진입하거나 벗어날 때 실행되는 이벤트이다.

&gt;```java
ScrollTrigger.create({
  trigger: &quot;.section&quot;,
  start: &quot;top 80%&quot;,
  end: &quot;bottom top&quot;,
  onEnter: () =&gt; console.log(&quot;들어옴&quot;),
  onLeave: () =&gt; console.log(&quot;나감&quot;),
  onEnterBack: () =&gt; console.log(&quot;뒤로 들어옴&quot;),
  onLeaveBack: () =&gt; console.log(&quot;뒤로 나감&quot;),
});</code></pre><p><strong>✅ onEnter</strong>: 요소가 처음 스크롤 다운하여 트리거 범위에 들어올 때 실행된다.
<strong>✅ onLeave</strong>: 요소가 스크롤 다운하여 트리거 범위에서 벗어날 때 실행된다.
<strong>✅ onEnterBack</strong>: 요소가 스크롤 업하여 다시 트리거 범위에 들어올 때 실행된다.
<strong>✅ onLeaveBack</strong>: 요소가 스크롤 업하여 트리거 범위를 벗어날 때 실행된다.</p>
<h3 id="📌-공통요소">📌 공통요소</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/84ed5920-307a-498e-9c6c-e3e76afe24c1/image.png" alt="">
<img src="https://velog.velcdn.com/images/kimjiji_0/post/43f0c207-c1c9-4221-a0b6-e29fe1d56120/image.png" alt=""></p>
<p>반복되는 카드형태의 UI에 공통 스타일을 적용</p>
<pre><code class="language-html">&lt;section class=&quot;sc-economy&quot;&gt;
  &lt;div class=&quot;split-area&quot;&gt;
     &lt;h3 class=&quot;title&quot;&gt;전통 금융에서&lt;br&gt;미래 금융으로.&lt;/h3&gt;
        &lt;ul class=&quot;card-list&quot;&gt;
          &lt;li class=&quot;card-item&quot;&gt;
             &lt;div class=&quot;title-box&quot;&gt;
               &lt;em class=&quot;title&quot;&gt;전통자산&lt;/em&gt;
               &lt;div class=&quot;right&quot;&gt;
               ...
             &lt;/div&gt;
          &lt;/li&gt;
          ...
&lt;/section&gt;</code></pre>
<h3 id="📌-border-image">📌 border-image</h3>
<p><code>###border-image</code> 속성을 사용하여 요소의 테두리에 그라데이션 이미지를 적용하는 코드입니다.
border-image-slice: 1;</p>
<p><code>border-image-slice</code>는 <code>border-image</code>로 지정된 원본 이미지를 어떻게 자르고 테두리에 적용할지 제어하는 속성입니다.</p>
<h3 id="📌-한-방향으로-계속-흘러가는-배너">📌 한 방향으로 계속 흘러가는 배너</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/8a5ac2f4-01d9-4984-ba05-64ba4517d457/image.png" alt="">
한 방향으로 끝없이 흘러가는 배너는 keyframe을 활용해서 구현해주었다.</p>
<blockquote>
<pre><code></code></pre></blockquote>
<ul class="banner-rolling">
  <li><span>JOIN <i>us</i></span></li>
  <li><span>JOIN <i>us</i></span></li>
  <li><span>JOIN <i>us</i></span></li>
  <li><span>JOIN <i>us</i></span></li>
  <li><span>JOIN <i>us</i></span></li>
  <li><span>JOIN <i>us</i></span></li>
  ...
</ul>
```
>```css
.sc-banner02 .banner-rolling {
  position: relative;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: end;
      -ms-flex-pack: end;
          justify-content: flex-end;
  -webkit-animation: banner2 30s linear infinite;
          animation: banner2 30s linear infinite;
}
@-webkit-keyframes banner2 {
  0% {
    -webkit-transform: translateX(0);
            transform: translateX(0);
  }
  100% {
    -webkit-transform: translateX(100%);
            transform: translateX(100%);
  }
}
```

<p>이번 프로젝트는 가로를 잡는 오류가 많이 나서 따로 벨로그에 정리해 두었다!
<del>정말..잊지 못할 ScrollTrigger였다..</del>
-&gt; pin으로만 모든걸 해결하려고 해서 오류가 많이 났던것! 해결방안 다시 정리!!</p>
<hr>
<p><strong>사이즈를 축소해보니 오류 발견🤔</strong>
<img src="https://velog.velcdn.com/images/kimjiji_0/post/c19e3540-5cbd-405b-9e2a-c8880b123982/image.png" alt="">
100%일땐 높이가 100vh로 잘 잡혔는데 줄이니 자동으로 잡아주지 않는다.
-&gt; 적응형으로 작업했기 때문에 ScrollTrigger에게 자동 높이 계산 코드를 넣어주지 않았기 때문!</p>
<blockquote>
<p><strong>3가지 해결방안</strong></p>
</blockquote>
<ol>
<li>invalidateOnRefresh: true</li>
<li>pinSpacing: true</li>
<li>sticky사용하기</li>
</ol>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/b5fe128e-522a-439b-8c6c-0b14dd719f35/image.png" alt="">
before을 이용해서 흰배경을 주었더니 확대시 오류발생
<code>border-image</code>를 이용하기!
<img src="https://velog.velcdn.com/images/kimjiji_0/post/c2b7a740-ba2b-46cd-8dd3-272bf61eecb7/image.png" alt=""></p>
<ol>
<li><strong>border-left: 0;</strong>
왼쪽을 없애주면 해결!
<img src="https://velog.velcdn.com/images/kimjiji_0/post/359a2934-67dc-4b18-b095-1df96af03471/image.png" alt=""></li>
</ol>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/eb7aa771-0fd1-4aa6-bf86-f534fa637ebe/image.png" alt="">
<strong>적응형이지만 화면이 줄어들시 여백 발생🤔</strong>
문제1 가로스크롤이 width값 못잡음
-&gt; width: max-content; or width: 100%
문제2 마지막 스크롤 뒤에 여백생김</p>
<blockquote>
<p>기존코드</p>
</blockquote>
<pre><code class="language-js"> .to(&#39;.sc-economy .split-area&#39;,{
        x: function() {
            return -economyWidth;
          },
          ease: &quot;none&quot;,
          duration:4
    },&#39;z&#39;)</code></pre>
<p>.split-area를 (전체 카드 너비 - 뷰포트 너비) 만큼만 이동시켜야 하는데,
-economyWidth는 한 화면 더 많이 이동해버리는 셈</p>
<blockquote>
<p>수정코드</p>
</blockquote>
<pre><code class="language-js">economyTl
    .to(&quot;.sc-economy .split-area&quot;,{
        xPercent:-100,
        x:&quot;100vw&quot;,
        duration:4
    },&#39;z&#39;)</code></pre>
<p><strong>xPercent: -100</strong>
=&gt; .split-area 전체 너비의 100%만큼 왼쪽으로 이동
하지만 상대이동이라 자기 너비만큼 움직이기 때문에 화면에 딱 맞지 않을수있다.
<strong>x: &quot;100vw&quot;</strong>
여기에 추가로 화면 너비만큼 오른쪽으로 이동
즉, 위에서 너무 많이 밀린 걸 한 화면 만큼 다시 앞으로 당긴 효과
ex) -300vw + 100vw = -200vw</p>
<p>✍ gsap pin은 만능이 아니다!
<code>sticky</code>를 사용했다면 더 빠르고 쉽게 사용할 수 있었다!
gsap 사용전 더 쉬운 방법 생각해보고 들어가기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[timeline관련]]></title>
            <link>https://velog.io/@kimjiji_0/timeline</link>
            <guid>https://velog.io/@kimjiji_0/timeline</guid>
            <pubDate>Wed, 26 Mar 2025 07:12:30 GMT</pubDate>
            <description><![CDATA[<p>타임라인을 사용하는데 첫번째 코드는 안돼고 두번째 코드는 될까?</p>
<h3 id="1-scrolltrigger를-timeline-내부에-설정했다">1. scrollTrigger를 timeline 내부에 설정했다.</h3>
<blockquote>
<pre><code class="language-java">    let economyTl = gsap.timeline({
        scrollTrigger:{
        trigger:&quot;.sc-economy&quot;,
        start:&#39;0 0&#39;,
        end:&#39;+=1500&#39;,
        pin:true,
        scrub:true,
        invalidateOnRefresh: true,
        // markers: true,
        },
        onEnter:function(){
            $(&#39;.sc-economy .card-item&#39;).addClass(&#39;blur&#39;)
            $(&#39;.sc-economy .arrow-area&#39;).addClass(&#39;on&#39;)
          },
          onEnterBack:function(){
            $(&#39;.sc-economy .arrow-area&#39;).addClass(&#39;on&#39;)
          },
          onLeave:function(){
            $(&#39;.sc-economy .arrow-area&#39;).removeClass(&#39;on&#39;)
          },
          onLeaveBack:function(){
            $(&#39;.sc-economy .arrow-area&#39;).removeClass(&#39;on&#39;)
          }

    })
    economyTl
    .to(&#39;.sc-economy .split-area&#39;,{
        x:()=&gt;{
        return -economyWidth / 3;
        },
        ease: &quot;none&quot;
    })</code></pre>
</blockquote>
<pre><code>
`onEnter`, `onLeave` 같은 이벤트는 `ScrollTrigger` 객체에서 직접 설정해야만 동작한다.

하지만 이렇게 타임라인 내부에서 `scrollTrigger`를 선언하면 타임라인과 애니메이션만 연결되고, `ScrollTrigger` 인스턴스 자체를 분리해서 제어할 수 없음.

결과적으로 이벤트가 제대로 바인딩되지 않거나 **무시될 수 있음**.

&gt;특히 `scrub: true`를 사용하는 경우 타임라인의 진행 방식이 바뀌는데, 여기에 **onEnter 같은 이벤트 트리거 방식과 충돌이 생기기 쉬움.**


### 2. ScrollTrigger.create()로 따로 생성
&gt;```java
const economyTl = gsap.timeline()
    economyTl
    .to(&#39;.sc-economy .split-area&#39;,{
        x: function() {
            return -economyWidth / 3;
          },
          ease: &quot;none&quot;,
          duration:4
    },&#39;z&#39;)
    .to(&quot;.sc-economy .arrow-area .fade&quot;,{opacity:1,delay:1,duration:1},&#39;z&#39;)
    &gt;
    ScrollTrigger.create({
      animation:economyTl,
      // markers:true,
      trigger:&#39;.sc-economy&#39;,
      start:&#39;0 0&#39;,
      end:&#39;+=1500&#39;,
      pin:true,
    //   scrub:1,
      invalidateOnRefresh:true,
      onEnter:function(){
        $(&#39;.sc-economy .card-item&#39;).addClass(&#39;blur&#39;)
        $(&#39;.sc-economy .arrow-area&#39;).addClass(&#39;on&#39;)
        },
        onEnterBack:function(){
        $(&#39;.sc-economy .arrow-area&#39;).addClass(&#39;on&#39;)
        },
        onLeave:function(){
        $(&#39;.sc-economy .arrow-area&#39;).removeClass(&#39;on&#39;)
        },
        onLeaveBack:function(){
        $(&#39;.sc-economy .arrow-area&#39;).removeClass(&#39;on&#39;)
        }
    })</code></pre><p>타임라인과 <strong><code>ScrollTrigger</code>를 명확히 분리</strong>하고,</p>
<p><code>ScrollTrigger.create()</code> 안에서 이벤트, 애니메이션, 스크롤 구간을 정밀하게 제어.</p>
<p>특히 이 구조는 <code>scrub, pin, invalidateOnRefresh</code> 같은 기능과 충돌 없이 안정적으로 작동함.</p>
<p>1번 코드는 구조는 맞지만 동작 보장이 약한 축약형,
2번 코드는 명시적이고 안전한 방식입니다.</p>
<blockquote>
<p>✅ 정리: 언제 어떤 방식 쓰면 되나?
<strong>단순한 스크롤 애니메이션</strong>
-&gt; gsap.timeline({ scrollTrigger: {...} })도 OK</p>
</blockquote>
<p><strong>이벤트 (onEnter, onLeave)를 쓰고 싶을 때</strong>
-&gt; 무조건 ScrollTrigger.create()로 분리</p>
<blockquote>
</blockquote>
<p><strong>scrub, pin, 애니메이션 동기화 필요</strong>
-&gt; ScrollTrigger.create({ animation: ... }) 구조 권장</p>
<table>
<thead>
<tr>
<th>코드 형태</th>
<th>의미</th>
<th>언제 사용?</th>
</tr>
</thead>
<tbody><tr>
<td><code>x: -economyWidth</code></td>
<td>처음에 계산된 값만 사용</td>
<td>값이 변하지 않을 때</td>
</tr>
<tr>
<td><code>x: function() { return -economyWidth; }</code></td>
<td>매번 새로 계산하도록 설정</td>
<td>창 크기 변경 등 반응형 처리 필요할 때</td>
</tr>
</tbody></table>
<pre><code>x: function() {
return -economyWidth;
}

x: () =&gt; -economyWidth; (함수사용시)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[defer와 async의 차이]]></title>
            <link>https://velog.io/@kimjiji_0/deferasync</link>
            <guid>https://velog.io/@kimjiji_0/deferasync</guid>
            <pubDate>Wed, 15 Jan 2025 07:26:05 GMT</pubDate>
            <description><![CDATA[<p><code>&lt;script&gt;</code> 태그에서 외부 JavaScript 파일을 불러올 때 로딩 방식을 제어하는 속성</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/802f2045-f02a-41c3-b491-c9b1fd701289/image.png" alt=""></p>
<h3 id="✅-1-defer란">✅ 1. defer란?</h3>
<blockquote>
<pre><code></code></pre></blockquote>
<script src="script.js" defer></script>
<p>```</p>
<p><strong>📌 동작 방식</strong>
HTML 파싱이 끝난 뒤 (DOMContentLoaded 직전) 스크립트를 실행</p>
<p>여러 개의 defer 스크립트는 순서대로 실행됨</p>
<p><strong>✅ 장점</strong>
DOM이 준비된 상태에서 실행 → DOM 조작에 안전</p>
<p>스크립트 간 실행 순서 보장</p>
<p>페이지 렌더링 지연 없음</p>
<p><strong>❌ 단점</strong>
반드시 external script만 가능 (inline script는 defer 못 씀)</p>
<p>🟢 사용 시점
DOM이 먼저 구성된 후에 실행되어야 하는 스크립트</p>
<p>여러 개의 스크립트를 순서대로 실행해야 할 때</p>
<h3 id="✅-2-async란">✅ 2. async란?</h3>
<script src="script.js" async></script>
<p>📌 동작 방식
다운로드가 완료되는 즉시 실행
→ HTML 파싱 중단 가능</p>
<p><strong>✅ 장점</strong>
가장 빠르게 실행됨 → 성능 최적화 가능</p>
<p>렌더링 블로킹 없이 실행됨</p>
<p><strong>❌ 단점</strong>
DOM 준비 전에 실행될 수 있음 → DOM 조작 시 에러 가능</p>
<p>여러 async 스크립트는 실행 순서 보장 안 됨</p>
<p><strong>💡 실무 팁</strong>
일반 웹 앱/사이트: defer 기본 사용</p>
<p>외부 SDK, 광고, 트래킹: async 사용</p>
<p><code>&lt;script&gt;</code>를 body 맨 아래 두는 방식보다 defer가 더 안정적이고 관리 편함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스크롤 이벤트 오류(namespace)]]></title>
            <link>https://velog.io/@kimjiji_0/namespace</link>
            <guid>https://velog.io/@kimjiji_0/namespace</guid>
            <pubDate>Fri, 03 Jan 2025 08:22:57 GMT</pubDate>
            <description><![CDATA[<p>특정영역일때 헤더가 사라졌다가 나타나게하기
열심히 검색해서 겨우 구현했는데 반응형시에 위치를 엉뚱하게 잡아 맨위로 올라갈때 헤더가 아예 안나옴...</p>
<p>그래서 비활성화했더니 화면 줄어들고 늘어날때 다른 스크롤 이벤트인 btn이 아예 안먹음...하...</p>
<blockquote>
<pre><code class="language-java">ScrollTrigger.matchMedia({
    &quot;(max-width:1023px)&quot;:function(){
      // 비활성화
      $(window).off(&quot;scroll&quot;);
    },
    &quot;(min-width:1024px)&quot;: function(){

      let lastScroll = 0;
      let isInProjectArea = false; // project-area에 들어갔는지 여부를 추적

      $(window).scroll(function () {
        const curr = $(this).scrollTop(); // 현재 스크롤 위치
        const projectAreaOffset = $(&quot;.project-area&quot;).offset().top; // .project-area의 상단 위치
        const projectAreaHeight = $(&quot;.project-area&quot;).outerHeight(); // .project-area의 높이
        const projectAreaEnd = projectAreaOffset + projectAreaHeight; // .project-area의 하단 위치

        // .project-area에 진입하면 헤더를 항상 숨김
        if (curr &gt;= projectAreaOffset &amp;&amp; curr &lt;= projectAreaEnd) {
          if (!isInProjectArea) {
            // .project-area에 처음 진입한 경우
            $(&quot;.header&quot;).fadeOut();
            isInProjectArea = true; // .project-area 내부로 상태 갱신
          }
        } else {
          // .project-area를 벗어나면 헤더를 다시 표시
          if (isInProjectArea) {
            $(&quot;.header&quot;).fadeIn();
            isInProjectArea = false; // .project-area 외부로 상태 갱신
          }
        }

        // 마지막 스크롤 위치 업데이트
        lastScroll = curr;
      });
    }
  })</code></pre>
</blockquote>
<pre><code>
✅ 네임스페이스(namespace)를 이용해서 헤더만 콕 찝어서 스크롤 안주면 된다!

&gt;```java
ScrollTrigger.matchMedia({
  &quot;(max-width:1023px)&quot;: function () {
    // 헤더 관련 스크롤 이벤트 제거
    $(window).off(&quot;scroll.headerFade&quot;);
  },
  &quot;(min-width:1024px)&quot;: function () {
    let isInProjectArea = false;
&gt;
    // 헤더 페이드 처리 이벤트 등록
    $(window).on(&quot;scroll.headerFade&quot;, function () {
      const curr = $(this).scrollTop();
      const projectAreaOffset = $(&quot;.project-area&quot;).offset().top;
      const projectAreaHeight = $(&quot;.project-area&quot;).outerHeight();
      const projectAreaEnd = projectAreaOffset + projectAreaHeight;
&gt;
      if (curr &gt;= projectAreaOffset &amp;&amp; curr &lt;= projectAreaEnd) {
        if (!isInProjectArea) {
          $(&quot;.header&quot;).fadeOut();
          isInProjectArea = true;
        }
      } else {
        if (isInProjectArea) {
          $(&quot;.header&quot;).fadeIn();
          isInProjectArea = false;
        }
      }
    });
  }
})</code></pre><p><strong>네임스페이스(namespace)</strong>는 고유한 이름 공간을 제공해 충돌을 막준다. 쉽게말해, 나중에 이 이벤트만 골라서 삭제하거나 관리하기 위해서입니다.</p>
<p><strong><code>.headerFade</code></strong>는 이벤트의 <strong><code>네임스페이스(namespace)</code></strong>를 의미
네임스페이스는 특정 이벤트를 그룹화하거나, 해당 그룹의 이벤트만 선택적으로 <strong>제거(off)하거나 추가(on)</strong>할 수 있도록 해주는 기능</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[gsap.set 반응형]]></title>
            <link>https://velog.io/@kimjiji_0/%EB%B0%98%EC%9D%91%ED%98%95%EC%8B%9C-gsap</link>
            <guid>https://velog.io/@kimjiji_0/%EB%B0%98%EC%9D%91%ED%98%95%EC%8B%9C-gsap</guid>
            <pubDate>Fri, 27 Dec 2024 05:12:58 GMT</pubDate>
            <description><![CDATA[<p><code>gsap.set()</code>은 초기 상태를 명확히 설정하여</p>
<p>애니메이션이 항상 <strong>예상한 위치와 스타일에서 시작</strong>되도록 보장해줍니다.</p>
<h4 id="✅-1-즉시-설정-no-animation">✅ 1. 즉시 설정 (No animation)</h4>
<p>gsap.set()은 애니메이션 없이 즉시 값을 적용합니다.</p>
<p>예: 초기 상태 설정 시 매우 유용.</p>
<blockquote>
<pre><code>gsap.set(&quot;.box&quot;, { opacity: 0, y: 50 });</code></pre></blockquote>
<pre><code>
#### ✅ 2. 퍼포먼스 최적화
element.style이나 jQuery보다 빠르게 동작하는 경우도 많음.


#### ✅ 3. GSAP 생태계와 연계 쉬움
나중에 gsap.to()로 애니메이션을 만들 때, 초기값을 일관되게 설정 가능.

ScrollTrigger와 같이 연동할 때도 좋음.

&gt;```
gsap.set(&quot;.box&quot;, { scale: 0 });
gsap.to(&quot;.box&quot;, { scale: 1, duration: 1 });</code></pre><h4 id="✅-4-css뿐-아니라-transform-등-복잡한-속성도-쉽게-설정">✅ 4. CSS뿐 아니라 transform 등 복잡한 속성도 쉽게 설정</h4>
<p>transform 관련 속성 (x, y, scale, rotate) 등은 CSS에서 설정하면 문자열 파싱이 필요하지만,
gsap.set()은 숫자 기반으로 깔끔하게 다룸.</p>
<blockquote>
<pre><code>gsap.set(&quot;.box&quot;, { x: 100, rotate: 45 });</code></pre></blockquote>
<pre><code>
#### ✅ 5. 배열, 반복 요소 설정도 간편
&gt;```
gsap.set(&quot;.items&quot;, { opacity: 0 });  // 여러 요소 한 번에 설정 가능</code></pre><h4 id="✅-6-단독으로도-사용-타임라인-안에서도-사용-가능">✅ 6. 단독으로도 사용, 타임라인 안에서도 사용 가능</h4>
<blockquote>
<pre><code>let tl = gsap.timeline();
tl.set(&quot;.box&quot;, { x: 0 })     // 초기 설정
  .to(&quot;.box&quot;, { x: 300 });   // 애니메이션</code></pre></blockquote>
<p>```</p>
<p>이처럼 반응형 환경에서 초기 상태를 화면 크기별로 분리에 용의.
불필요한 시각적 깜빡임이나 스타일 오류를 방지.
사용자 경험을 부드럽고 일관되게 유지.</p>
<p>이 코드는 반응형 애니메이션에서 초기 상태를 관리하기 위한 <strong>가장 좋은 방법</strong> 중 하나로 사용되었습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[지정영역에서 이벤트 발생 후 재실행]]></title>
            <link>https://velog.io/@kimjiji_0/%EC%A7%80%EC%A0%95%EC%98%81%EC%97%AD%EC%97%90%EC%84%9C-%EC%97%86%EC%96%B4%EC%A7%80%EA%B8%B0</link>
            <guid>https://velog.io/@kimjiji_0/%EC%A7%80%EC%A0%95%EC%98%81%EC%97%AD%EC%97%90%EC%84%9C-%EC%97%86%EC%96%B4%EC%A7%80%EA%B8%B0</guid>
            <pubDate>Tue, 17 Dec 2024 06:20:48 GMT</pubDate>
            <description><![CDATA[<p>gsap를 이용해서 스크롤시 내가 원하는 영역에서 이벤트가 발생하고 해당영역을 벗어나면 다시 이벤트가 나타나는걸 작성했는데 원하는대로 안됨ㅠ</p>
<p>내가 처음 작성한것</p>
<p><strong>1. gsap를 이용</strong></p>
<blockquote>
<pre><code class="language-java">ScrollTrigger.create({
  trigger: &quot;.project-area&quot;, // .project-area에 트리거 설정
  start: &quot;top top&quot;, // .project-area의 상단이 뷰포트 상단에 닿으면 시작
  end: &quot;bottom top&quot;, // .project-area의 하단이 뷰포트 상단에 닿으면 종료
  toggleActions: &quot;play none none reverse&quot;, // 실행: play, 복귀: reverse
  onEnter: () =&gt; {
    gsap.to(&quot;#header&quot;, { opacity: 0, y: -20, duration: 0.2 }); // 헤더 숨김
  },
  onLeaveBack: () =&gt; {
    gsap.to(&quot;#header&quot;, { opacity: 1, y: 0, duration: 0.2 }); // 헤더 복귀
  }
});</code></pre>
</blockquote>
<pre><code>

#### 🤔 문제점project-area를 못잡는다

&gt; 내가 생각한 해결법
1. 부모한데 300vh를 줘서 스크롤할 높이값을 준다. -&gt; 실패
2. end를 100%를 줘서 전체 높이값을 잡도록한다 -&gt; 여전히 못잡음</code></pre><h4 id="👀-3-서치를-통해-찾은-다른-해결법">👀 3. 서치를 통해 찾은 다른 해결법</h4>
<blockquote>
<pre><code class="language-java">onEnter: () =&gt; {
    gsap.to(&quot;#header&quot;, { opacity: 0, y: -20, duration: 0.2 }); // 헤더 숨김
  },
  onLeave: () =&gt; {
    gsap.to(&quot;#header&quot;, { opacity: 1, y: 0, duration: 0.2 }); // 헤더 복귀 (project-area 벗어날 때)
  },
  onEnterBack: () =&gt; {
    gsap.to(&quot;#header&quot;, { opacity: 0, y: -20, duration: 0.2 }); // 다시 project-area로 진입 시 숨김
  },
  onLeaveBack: () =&gt; {
    gsap.to(&quot;#header&quot;, { opacity: 1, y: 0, duration: 0.2 }); // 위로 벗어나면 복귀
  }</code></pre>
</blockquote>
<pre><code>
-&gt; 여전히 못잡음

**👀 4. invalidateOnRefresh 트리거 재계산 -&gt; 안먹음x**


#### ✅ **5. scroll이벤트를 이용해서 잡기**
&gt;```java
let lastScroll = 0;
&gt;
$(window).scroll(function () {
  const currScroll = $(this).scrollTop(); // 현재 스크롤 위치
  const projectAreaOffset = $(&quot;.project-area&quot;).offset().top; // .project-area의 상단 위치
  const projectAreaHeight = $(&quot;.project-area&quot;).outerHeight(); // .project-area의 높이
  const projectAreaEnd = projectAreaOffset + projectAreaHeight; // .project-area의 하단 위치
&gt;
  // 스크롤이 .project-area에 있을 때만 동작
  if (currScroll &gt;= projectAreaOffset &amp;&amp; currScroll &lt;= projectAreaEnd) {
    if (currScroll &gt; lastScroll) {
      // 아래로 스크롤
      gsap.to(&quot;.header&quot;, { opacity: 0, duration: 0.1 });
    } else {
      // 위로 스크롤
      gsap.to(&quot;.header&quot;, { opacity: 1, duration: 0.1 });
    }
  } else {
    // .project-area를 벗어나면 헤더를 항상 보이게 설정
    gsap.to(&quot;.header&quot;, { opacity: 1, duration: 0.1 });
  }
&gt;
  lastScroll = currScroll; // 마지막 스크롤 위치 갱신
});</code></pre><p><strong>해결!</strong>
하지만 새로운 문제 project-area를 벗어나고 다시 스크롤을 위로 올려서 영역에 들어가면
그대로 존재😢</p>
<h3 id="⭕찐해결법">⭕찐해결법</h3>
<p><strong>let isInProjectArea = false;를 이요해서 영역에 들어갔는지 여부를 추적하면 된다!!!</strong></p>
<blockquote>
<pre><code class="language-java">  if (curr &gt;= projectAreaOffset &amp;&amp; curr &lt;= projectAreaEnd) {
    if (!isInProjectArea) {
      // .project-area에 처음 진입한 경우
      $(&quot;.header&quot;).fadeOut();
      isInProjectArea = true; // .project-area 내부로 상태 갱신
    }
  } else {
    // .project-area를 벗어나면 헤더를 다시 표시
    if (isInProjectArea) {
      $(&quot;.header&quot;).fadeIn();
      isInProjectArea = false; // .project-area 외부로 상태 갱신
    }
  }</code></pre>
</blockquote>
<p>```</p>
<p>두 번 선언하는 이유는 퍼포먼스 최적화와 정확한 동작 보장 때문</p>
<p><strong>1. <code>$(window).scroll</code> 내부에서 선언</strong>
스크롤 이벤트 내부에서 위치와 크기를 다시 계산하는 이유는 <code>$(&quot;.project-area&quot;)</code>의 위치나 크기가 <strong>스크롤 중에 동적으로 변경될 가능성이 있기 때문</strong>입니다.</p>
<p><strong>2. 전역 변수 및 resize 이벤트</strong>
<code>.project-area</code>의 위치와 크기가 고정된 경우. 반복적으로 계산하지 않고 성능을 최적화.</p>
<h4 id="🤔언제-두-방식을-동시에-사용하는가">🤔언제 두 방식을 동시에 사용하는가?</h4>
<p><strong>1. 전역 변수 + resize 이벤트</strong>
상황: .project-area의 위치와 크기가 대부분 고정되어 있고, 브라우저 창 크기 변경 시만 업데이트가 필요할 때.
장점: 스크롤 이벤트를 가볍게 만들고, 성능을 최적화.</p>
<p><strong>2. 스크롤 이벤트 내부에서 계산</strong>
상황: .project-area의 위치나 크기가 스크롤 도중 동적으로 변경될 가능성이 있을 때.
장점: 위치와 크기의 정확성을 보장.</p>
<p><strong>3. 둘을 함께 사용하는 이유</strong>
기본적으로 전역 변수와 resize 이벤트를 사용해 성능을 최적화.
<strong>하지만 특정 상황에서는 스크롤 이벤트 내에서도 실시간으로 값을 재계산해야 동작의 정확성을 보장.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[반응형시 gsap 초기화가 나을까]]></title>
            <link>https://velog.io/@kimjiji_0/gsap%EC%B4%88%EA%B8%B0%ED%99%94</link>
            <guid>https://velog.io/@kimjiji_0/gsap%EC%B4%88%EA%B8%B0%ED%99%94</guid>
            <pubDate>Tue, 29 Oct 2024 04:56:19 GMT</pubDate>
            <description><![CDATA[<p>프로젝트 진행시 모바일 마크업을 따로하지 않고 초기화로 작업하려 했는데 너무 오류가 발생...</p>
<pre><code class="language-css">(min-width: 767px) and (max-width: 1023px)</code></pre>
<h3 id="1-애니메이션-초기화-방식"><strong>1. 애니메이션 초기화 방식</strong></h3>
<h4 id="✅-장점">✅ 장점</h4>
<p><strong>유지보수 용이성:</strong> 동일한 마크업을 사용하므로 수정할 때 코드 중복을 피할 수 있어 유지 보수가 쉬워집니다.
<strong>파일 크기 절감</strong>: 마크업을 하나로 통일하면 불필요한 HTML이 추가되지 않아 전체 파일 크기가 줄어듭니다.
<strong>변경 관리 간소화</strong>: 한 개의 마크업에 반응형 CSS와 애니메이션 초기화 설정을 추가하면, 특정 디바이스에서 동작 방식을 쉽게 수정할 수 있습니다.</p>
<h4 id="✅-단점">✅ 단점</h4>
<p><strong>복잡한 조건 설정</strong>: 특정 해상도별로 애니메이션 초기화를 세밀하게 설정해야 하므로 코드가 복잡해질 수 있습니다.
<strong>성능 이슈</strong>: 반응형에서 매번 애니메이션을 초기화하거나 다시 설정하는 과정에서 성능에 영향을 줄 수 있습니다.</p>
<p>-&gt; 초기화 방식을 사용하면, 불필요한 애니메이션 코드가 항상 포함되기 때문에, <strong>모바일 디바이스에서 실행하지 않는 코드를 계속 로드하게 되는 부담</strong>이 있습니다.</p>
<p><strong>👀이 방식이 적합한 경우</strong></p>
<ul>
<li>간단한 애니메이션을 포함하거나, 애니메이션의 복잡도가 낮아 디바이스별 초기화가 쉬운 경우</li>
<li>HTML 구조를 동일하게 유지해야 할 필요가 있는 경우</li>
</ul>
<h3 id="2-모바일용-마크업-별도-제작">2. 모바일용 마크업 별도 제작</h3>
<h4 id="✅-장점-1">✅ 장점</h4>
<p><strong>유연한 디자인 적용</strong>: 모바일에 최적화된 구조를 별도로 만들 수 있어, 디바이스에 맞는 애니메이션과 레이아웃을 쉽게 구현할 수 있습니다.
<strong>더 나은 성능</strong>: 디바이스에 맞게 마크업을 최적화하여 불필요한 요소를 로드하지 않게 할 수 있습니다.</p>
<h4 id="✅-단점-1">✅ 단점</h4>
<p><strong>유지 보수 어려움</strong>: 동일한 콘텐츠를 여러 개의 마크업에 구현하게 되어 수정할 때 두 곳 이상을 모두 수정해야 하는 번거로움이 있습니다.
<strong>코드 중복</strong>: 모바일용과 데스크탑용으로 분리된 HTML 코드가 추가되어 코드가 복잡해질 수 있습니다.</p>
<p><strong>👀이 방식이 적합한 경우</strong></p>
<ul>
<li>데스크탑과 모바일 <strong>레이아웃이 많이 다르거나</strong>, <strong>애니메이션이 복잡</strong>하여 해상도에 따른 조건을 따로 설정하는 것이 더 효율적인 경우</li>
<li>마크업 자체가 해상도별로 크게 달라질 필요가 있는 경우</li>
</ul>
<h3 id="결론">결론</h3>
<blockquote>
<p><strong>초기화</strong>
-&gt; 간단한 애니메이션과 비슷한 레이아웃을 유지하는 경우, 유지보수
<strong>별도의 마크업(모바일)</strong>
-&gt; 디바이스별로 전혀 다른 애니메이션 효과나 레이아웃을 적용해야 하는 경우, 최적화</p>
</blockquote>
<p>🤔 일단 시안을 보고 마크업을 pc,모바일로 따로 마크업을 따로할지 보고 결정해야할것 같다!
이번 시안은 pc에서는 고정 모바일에서는 세로스크롤이라 따로 마크업이 좋다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[제이쿼리 클래스 구분자]]></title>
            <link>https://velog.io/@kimjiji_0/%EC%A0%9C%EC%9D%B4%EC%BF%BC%EB%A6%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B5%AC%EB%B6%84%EC%9E%90</link>
            <guid>https://velog.io/@kimjiji_0/%EC%A0%9C%EC%9D%B4%EC%BF%BC%EB%A6%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B5%AC%EB%B6%84%EC%9E%90</guid>
            <pubDate>Mon, 21 Oct 2024 02:29:34 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p><strong>올바른 방식</strong>: 클래스 이름을 <strong>공백</strong>으로 구분
$rolltextWrap.removeClass(&quot;a1 a2 a3 a4&quot;);</p>
</li>
<li><p><strong>잘못된 방식</strong>: <strong>콤마</strong>로 구분 (하나의 문자열로 인식됨)
$rolltextWrap.removeClass(&quot;a1, a2, a3, a4&quot;); </p>
</li>
<li><blockquote>
<p>작동하지 않음</p>
</blockquote>
</li>
</ul>
<p>클론코딩하는데 헷갈렷던...</p>
<blockquote>
<p>onUpdate: (self) =&gt; { const bar = self.progress.toFixed(3) * 100; }
에 대한 풀이</p>
</blockquote>
<h3 id="1-onupdate-self----"><strong>1. onUpdate: (self) =&gt; { ... }</strong></h3>
<p>onUpdate는 ScrollTrigger가 스크롤할 때마다 실행되는 <strong>콜백 함수</strong>입니다. 즉, 스크롤이 진행될 때마다 특정 작업을 실행하고 싶을 때 사용됩니다.
이 함수는 매번 스크롤 위치가 변할 때마다 실행되며, <strong>self라는 매개변수</strong>로 현재 ScrollTrigger 객체의 상태를 전달받습니다.</p>
<h3 id="2-selfprogress">2. self.progress</h3>
<p>self.progress는 <strong>현재 스크롤 진행 상황을 0에서 1 사이의 숫자</strong>로 나타내는 값입니다.
예를 들어:
0은 트리거가 시작 위치에 있는 상태를 의미합니다.
1은 트리거가 끝 위치에 도달한 상태를 의미합니다.
0.5는 트리거가 절반 정도 진행된 상태를 의미합니다.
따라서, self.progress는 현재 스크롤 상태를 비율로 나타내는 값입니다.</p>
<h3 id="3-tofixed3">3. .toFixed(3)</h3>
<p><strong>toFixed(3)는 숫자를 소수점 셋째 자리까지 나타내는 메서드</strong>입니다.
예를 들어 self.progress가 0.87654321이라면, toFixed(3)를 사용하면 0.877로 만들어줍니다.
이는 스크롤 진행 값을 <strong>3자리 소수점까지 반올림해서 간결하게 보여주기 위한 방법</strong>입니다.</p>
<h3 id="4--100">4. * 100</h3>
<p>스크롤 진행 상황을 퍼센트(%)로 표현하기 위해 self.progress에 <strong>100을 곱하는 것</strong>입니다. 즉, 0.5라면 50% 진행된 것이고, 0.8이라면 80% 진행된 것을 의미합니다.
self.progress는 0에서 1 사이의 값이므로, <strong>이를 100으로 바꾸면 직관적</strong>으로 스크롤이 얼마나 진행되었는지를 퍼센트로 나타낼 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스크롤 기반 반복문]]></title>
            <link>https://velog.io/@kimjiji_0/Scroll</link>
            <guid>https://velog.io/@kimjiji_0/Scroll</guid>
            <pubDate>Thu, 10 Oct 2024 07:18:56 GMT</pubDate>
            <description><![CDATA[<h3 id="1-scrolltriggerbatch의-목적"><strong>1. ScrollTrigger.batch의 목적</strong>:</h3>
<p>ScrollTrigger.batch는 여러 요소가 스크롤에 반응할 때 성능을 최적화하며 일괄적으로(배치) 애니메이션을 적용하는 방식이다. 즉, 화면에 여러 요소가 있을 때 스크롤 이벤트에 따라 특정 구간에 들어오면 해당 요소들에 애니메이션을 일괄 적용하는 것.</p>
<ul>
<li><p>특징:
스크롤 이벤트에 맞춰 동작: 스크롤하면서 화면에 요소가 나타나거나 사라질 때만 애니메이션이 실행된다.
성능 최적화: 요소가 많이 있을 때 각각 독립적으로 처리하지 않고, 여러 개의 요소를 모아서 한꺼번에 처리하므로 성능에 좋음!</p>
<h3 id="2-foreach의-목적"><strong>2. forEach의 목적:</strong></h3>
<p>forEach는 배열이나 HTML 요소 리스트에 대해 순차적으로 하나씩 작업을 수행하는 방법이다. 스크롤과는 관계없이 반복문 역할만함.</p>
</li>
<li><p>특징:
순차적으로 요소 하나씩 처리: 스크롤 이벤트 없이 요소 리스트를 순차적으로 반복하여 각 요소에 대해 작업을 한다.
스크롤과 관련 없음: 스크롤을 기반으로 작동하는 애니메이션과는 무관하며 단순히 반복 작업에 사용된다.</p>
</li>
</ul>
<p>비교</p>
<blockquote>
<p><strong>ScrollTrigger.batch</strong>:</p>
</blockquote>
<pre><code>ScrollTrigger.batch(&quot;.item&quot;, {
  onEnter: (batch) =&gt; {
    gsap.to(batch, { opacity: 1, y: 0 }); // 스크롤을 통해 여러 요소가 한 번에 나타남
  }
});</code></pre><p><strong>forEach</strong>:</p>
<pre><code>document.querySelectorAll(&#39;.item&#39;).forEach(item =&gt; {
  gsap.to(item, { opacity: 1, y: 0 }); // 각 요소가 순차적으로 애니메이션 실행
});</code></pre><p>요약:
<strong>ScrollTrigger.batch</strong>: 스크롤 이벤트에 반응하는 여러 요소에 애니메이션을 일괄적으로 적용하여 성능을 최적화함. 스크롤과 관련된 이벤트에 최적화!!
<strong>forEach</strong>: 배열이나 HTML 요소 리스트의 각 항목에 대해 반복 작업을 수행하는 일반적. 스크롤과는 무관하며 <strong>단순한 반복 작업</strong>을 처리할 때 사용됩니다.</p>
<h4 id="실수">실수</h4>
<p>두 코드의 차이는 ScrollTrigger가 한 번만 작동하느냐 아니면 각 요소별로 따로 작동하느냐입니다.</p>
<blockquote>
<pre><code class="language-javascript">수정전
gsap.from(&quot;.sc-title .line&quot;, {
    height: &quot;0&quot;,
    ease: &quot;none&quot;,
    duration: 5,
    stagger: 1,
</code></pre>
</blockquote>
<pre><code>scrollTrigger: {
    trigger: &quot;.sc-title&quot;,
    start: &quot;0% 70%&quot;,
    end: &quot;0% 70%&quot;,
    scrub: 1,
    markers: true,
},</code></pre><p>});</p>
<pre><code>
&gt;```
수정후
gsap.utils.toArray(&quot;.sc-title .line&quot;).forEach((item) =&gt; {
  gsap.from(item, {
    height: &quot;0&quot;,
    ease: &quot;none&quot;,
    duration: 5,
    scrollTrigger: {
      trigger: item, // 각 개별 아이템을 기준으로 트리거 설정
      start: &quot;0% 70%&quot;,
      end: &quot;0% 70%&quot;,
      scrub: 1,
      markers: true,
    },
  });
});</code></pre><h2 id="📌data-속성">📌data-속성</h2>
<p><strong>data-</strong> 속성은 개발자가 특정한 기능이나 데이터와 관련된 요소를 쉽게 찾고 조작할 수 있도록 도와줍니다. 코드의 가독성과 유지보수성 향상된다!!!!
예를 들어
<strong>data-scroll-opacity</strong>와 같은 사용자 정의 속성을 사용하는 이유는 특정 요소에 스크롤 관련 애니메이션을 적용할 때, 요소를 쉽게 타겟팅하기 위해.
이 클론파일에서 <strong>data-scroll-opacity</strong>는 스크롤에 따라 불투명도(opacity)와 위치(y)를 제어하기위해 사용됨!</p>
<blockquote>
<pre><code>gsap.set(&quot;[data-scroll-opacity]&quot;, {
  opacity: 0,
  y: 30,
});
</code></pre></blockquote>
<p>ScrollTrigger.batch(&quot;[data-scroll-opacity]&quot;, {
  start: &quot;0% 85%&quot;,
  end: &quot;100% 0%&quot;,
  onEnter: (batch) =&gt; {
    gsap.to(batch, {
      opacity: 1,
      y: 0,
    });
  },
  onLeaveBack: (batch) =&gt; {
    gsap.to(batch, {
      opacity: 0,
      y: 30,
    });
  },
});</p>
<p>```</p>
<p>data-scroll-opacity 속성을 가진 모든 요소에 대해 스크롤을 통해 애니메이션이 적용됩니다. 스크롤이 특정 위치에 도달하면 해당 요소의 불투명도와 위치가 변경되며 애니메이션 효과가 발생!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[💻] 실습 - earth]]></title>
            <link>https://velog.io/@kimjiji_0/earth</link>
            <guid>https://velog.io/@kimjiji_0/earth</guid>
            <pubDate>Wed, 15 Mar 2023 11:33:16 GMT</pubDate>
            <description><![CDATA[<h2 id="📖-overview">📖 Overview</h2>
<p><strong>사이트명</strong>: earth
<strong>작업 기간</strong>: 3.5일 소요
<strong>라이브러리</strong>: swiper, jQuery
<strong>유형</strong>: 반응형, 클론 코딩
<strong>참여도</strong>: 100%</p>
<h2 id="📌-svg-마스킹">📌 svg 마스킹</h2>
<p><code>mask-image</code>를 이용해야한다.
<code>background-image</code>처럼 <code>url</code>을 이용해야한다.</p>
<p>id연결</p>
<pre><code>&lt;mask id=&quot;mask&quot;&gt;
      &lt;rect fill=&quot;#000000&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;/rect&gt;
      &lt;circle fill=&quot;#FFFFFF&quot; cx=&quot;150&quot; cy=&quot;150&quot; r=&quot;100&quot; /&gt;
      &lt;circle fill=&quot;#FFFFFF&quot; cx=&quot;50&quot; cy=&quot;50&quot; r=&quot;150&quot; /&gt;
&lt;/mask&gt;</code></pre><pre><code class="language-css">  -webkit-mask-image: url(#mask);
  mask-image: url(#mask);</code></pre>
<p>먼저 필요한건 <strong><code>&lt;defs&gt;&lt;/defs&gt;</code></strong>이다
defs란??</p>
<blockquote>
<p><strong>definitions</strong> 정의
그래픽 오브젝트들은 어디서든 참조될 수 있지만, <defs>엘리먼트 안의 이러한 오브젝트들을 정의하는 것은 그 svg 컨텐츠의 이해를 높이고, 문서의 전반적인 접근에 유익하다.</p>
</blockquote>
<p><strong>쉽게말해</strong>
 <span style="color: red"><strong>나중에 참조할 그래픽 요소 같은 것들을 담아놓는 공간.</strong> </span></p>
<p><a href="https://nyjchoi.tistory.com/15">https://nyjchoi.tistory.com/15</a></p>
<h3 id="✏-사용법">✏ 사용법</h3>
<ol>
<li><code>&lt;mask&gt; &lt;mask/&gt;</code>에 <strong>id</strong>를 지정하자.<ul>
<li><code>&lt;mask id=&quot;mask_a&quot;&gt;</code>   </li>
</ul>
</li>
</ol>
<p>2.<code>&lt;g&gt;&lt;/g&gt;</code> 안 스타일에 <code>mask: url(#mask_a);</code> <strong>id</strong>값을 연결하자.</p>
<h2 id="📌-columns">📌 columns</h2>
<p>다단(multi-column) 레이아웃</p>
<blockquote>
<pre><code>columns: 2;
column-gap: 48px;</code></pre></blockquote>
<pre><code>
  그리드 영역 설정
  https://sorto.me/docs/Web/CSS/grid-template-areas
  https://velog.io/@forest0501/CSS-Grid-Grid-Template-Areas%EC%99%80-Grid-Row-Grid-Column

  grid-area로 이름설정
  grid-template-areas로 순서


  &lt;br&gt;

![](https://velog.velcdn.com/images/kimjiji_0/post/7c5b1f6c-fe4c-4b26-905a-90bdd71663f7/image.png)

처음 알고있는대로 columns을 줬지만 전혀 원하는 칸만큼 나오지 않았다.
검색 결과 `grid-column-end`가 필요함!!

`grid-column-end: span 9;`란 숫자만큼 라인을 확장하는(+) 개념 9칸을 한칸으로 친다는뜻

[grid 참고](https://studiomeal.com/archives/533)






  ---
## 오답
1. ![](https://velog.velcdn.com/images/kimjiji_0/post/d92ed8f2-349b-4bc1-9e40-c83486f3af1e/image.png)

애니메이션 시작시 저부분이 제일 마지막에 실행되어야하는데 시작부터 나와있음
  -&gt; animation-fill-mode를 이용해서 해결

- **animation-fill-mode**란
  애니메이션이 끝난 후의 상태를 설정합니다.
- 속성 -&gt; **both**
  애니메이션이의 앞 뒤 결과를 조합하여 설정합니다.

  &lt;br&gt;

2. ![](https://velog.velcdn.com/images/kimjiji_0/post/fda148eb-d2cf-4e04-8b58-cb5b95592a1f/image.png)


호버시 자꾸 다음꺼가 바뀌고 덜컹거리는 문제가 생김

&gt;```css
$(&#39;.swiper-pagination-bullet&#39;).hover(function() {
        $( this ).trigger( &quot;click&quot; );
     });</code></pre><p>  스와이퍼 루프기능이 들어간다면 <code>$( this ).trigger( &quot;click&quot; );</code>이 기능을 사용 할 수 없다.
  <br></p>
<p>✍ <strong><code>slide2.slideToLoop()</code></strong>를 사용해야한다.</p>
<p>호버했을때 루프되라는 뜻
내가 숫자 2를 넣으면 어디를 호버해도 2번째로 간다.</p>
<blockquote>
<pre><code class="language-css">slide2.slideToLoop($(this).index())</code></pre>
</blockquote>
<p>```</p>
<p>그렇기 때문에 호버하려는 this의 길이(index)로 가라 하면 된다.</p>
  <br>


<ol start="3">
<li><img src="https://velog.velcdn.com/images/kimjiji_0/post/caa9a4a2-d077-473f-a343-e5fb286426f0/image.png" alt=""></li>
</ol>
<p>호버햇을때 나온 자식들에게 마우스 호버를 할 수 없는 일 이 발생;;</p>
<p>→ 부모에 호버를 한다고 써줘야하고 부모가로 길이를 주면 안됐다</p>
<p>왜냐 저 부분에 가지도 않았는데 나타났다 사라졌다 하기때문에</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/4ea819f4-594d-49f5-b14b-3262bae4dcbf/image.png" alt=""></p>
<p>위치를 오른쪽에서 시작하게 하고 <code>width: 0;</code>를 이용해서 해결!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[💻] 실습 - 맥북]]></title>
            <link>https://velog.io/@kimjiji_0/jj</link>
            <guid>https://velog.io/@kimjiji_0/jj</guid>
            <pubDate>Wed, 26 Oct 2022 10:31:23 GMT</pubDate>
            <description><![CDATA[<h2 id="📖-overview">📖 Overview</h2>
<p><strong>사이트명</strong>: 맥북
<strong>작업 기간</strong>: 6.5일 소요
<strong>라이브러리</strong>: swiper, jQuery
<strong>유형</strong>: 반응형, 클론 코딩
<strong>참여도</strong>: 100%</p>
<h3 id="👀-check-point">👀 Check-point</h3>
<ul>
<li>반응형시 오류가 없는가</li>
<li>공통 클래스명으로 컨트롤하기 쉽게 작업했는가</li>
<li>스크롤에 대한 이벤트처리</li>
</ul>
<hr>
<h3 id="공통-클래스를-주로-쓰는-mac">공통 클래스를 주로 쓰는 mac</h3>
<p>공통으로 꾸밀때는 영역에 가서 좌표를 잡는게 좋다. </p>
<h2 id="📌-favicon-추출법"><strong>📌 favicon 추출법</strong></h2>
<ol>
<li><p>페이지 소스에서 <code>favicon</code>검색 후 추출
<img src="https://velog.velcdn.com/images/kimjiji_0/post/2d867610-080f-4912-a027-1111266273ef/image.png" alt=""></p>
</li>
<li><p>절대주소 추출</p>
</li>
</ol>
<ul>
<li>가끔 페이지 소스에서 나오지 않는 경우가 있다.
<code>https://주소/favicon.ico</code>를 사용해주면 된다.</li>
</ul>
<br>


<h2 id="📌-비디오-태그-쓰는법"><strong>📌 비디오 태그 쓰는법</strong></h2>
<p><a href="https://m.blog.naver.com/skydoor2014/221667330746">[ video 태그 ] HTML5로 동영상 넣는 방법. 이 글 하나면 모든 고민 끝!</a></p>
<blockquote>
</blockquote>
<pre><code class="language-html">&lt;video autoplay muted class=&quot;video&quot;&gt;
    &lt;source src=&quot;https://www.apple.com/105/media/us/macbook-air-m1/2022/648bb92f-0bb4-452c-bfbc-2898641b22f5/anim/hero/large.mp4&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;</code></pre>
<ul>
<li><strong>muted</strong> - 음소거</li>
<li><strong>autoplay</strong> - 자동재생</li>
<li><strong>type</strong> - video</li>
</ul>
<ul>
<li>비디오는 <span style="color: red"><strong>현재 내 화면에서만 재생</strong> </span>되니까 제이쿼리 안걸어줘도 된다!</li>
<li>현재 내가 보고있는 <strong>화면에 도달해야지만 플레이</strong> 되는 성질인 애다!</li>
</ul>
<br>

<p><strong>반응형시 <code>br</code>이 필요할때 <code>display:none</code> , <code>block</code>처리해주면된다.</strong></p>
<p><br><br></p>
<h2 id="📌-animation">📌 Animation</h2>
<h3 id="✏-순서">✏ 순서</h3>
<blockquote>
<pre><code class="language-css">div {
    animation: rgy 5s ease-in 1s infinite alternate forwards paused;
}</code></pre>
</blockquote>
<pre><code>
&gt;**순서헷갈리지 말기**
&gt; name &gt; duration &gt; timing-function &gt; delay &gt; count &gt; direction &gt; fill-mode &gt; play-state
&gt;
애니메이션 이름 &gt; 재생 시간(실행 속도) &gt; 속도 곡선 타입 &gt; 딜레이 시간 &gt; 반복 횟수 &gt;  진행 방향 &gt; 종료 후 위치 &gt; 실행or정지

&lt;br&gt;

### ✏ background-clip
&lt;span style=&quot;color: red&quot;&gt; **제이쿼리를 사용하지 않고 글자가 채워질수 있다!**&lt;/span&gt;

![](https://velog.velcdn.com/images/kimjiji_0/post/0bbe4886-1f4c-42fd-ad74-ac90db0e5865/image.png)


내가 주려는 글자에 **`animation`**,**`text-fill-color`**,**`background-clip`** 필수!

**text-fill-color** - 기존 텍스트 색

**background-clip** - 사용하려는 요소의 색을 어디에 두려는지


&gt;```css
.content.battery .headline{
    animation: battery 1.5s linear forwards;
&gt;
    background: linear-gradient(to top, #4cd265 50%, #fff 50%);
    background-size: auto 200%;
    -webkit-background-clip: text;
    background-clip: text;
    /* text-fill-color: transparent; */
    -webkit-text-fill-color: transparent; /*투명*/
}</code></pre><h2 id="📌-공통-클래스">📌 공통 클래스</h2>
<p>안다르에서도 공통 클래스를 이용하여 쉽게 컨트롤을 연습했지만 내가 사용을 잘 안함 + 너무 많은 공통 클래스로 인해 헷갈리게 되었다.</p>
<blockquote>
<pre><code class="language-css">80* headline-super
56* headline-medium
</code></pre>
</blockquote>
<p>32* desc-super
28* desc-large
19* desc-medium</p>
<blockquote>
</blockquote>
<p>21* title-normal </p>
<pre><code>
-어렵게 생각하지 않기-

1. 자주 쓰이는 폰트 사이즈를 적어보고 자주쓰이는 애들한테 클래스 이름을 추가해 준다.
2. 중복되는 font-weight, line-height도 같이 적어준다

``` css
.headline-super{
    font-size: 80px;
    line-height: 1.15;
    font-weight: 700;
}</code></pre><p>🤔 → 왜 변수 (var)로 안쓰고 클래스로 주나요??</p>
<blockquote>
<p>클래스가 좀 더 간편하고 각각 계속 줘야하는게 많은데 var는 css까지 가서 줘야한다.(가내 수공업)</p>
</blockquote>
<p><br><br></p>
<h2 id="📌-공통-css---gap을-안주고-쓰는방법">📌 공통 css - gap을 안주고 쓰는방법</h2>
<h3 id="✏-선택자">✏ 선택자</h3>
<blockquote>
<pre><code class="language-css">.section .content-wrapper &gt; * + *{margin-top: 24px;}</code></pre>
</blockquote>
<pre><code>
→ `.section` `.content-wrapper`의 직계자식중 전체애들중에 첫번째 요소빼고 전체애들한테 `{margin-top: 24px;}` 을 준다.

근데 왜 `.content-wrapper`안에  `.content`로 잡지 않고 `*`선택자를 썼을까?

→ .content-wrapper안에는 .content가 아닌 다른요소도 있기때문에

- 선택자 설명이 이해안된다면?

[꼭 알아야하는 선택자](https://code.tutsplus.com/ko/tutorials/the-30-css-selectors-you-must-memorize--net-16048)

#### &lt;span style=&quot;background-color: rgba(242,179,188,0.5)&quot;&gt; :not(선택자)&lt;/span&gt;
&gt;```css
.content.gpu &gt; *:not(.video-area){z-index: 1;}</code></pre><p>내가 선택하려는 .content.gpu에 인접한 전체 애들중에 .video-area빼고(아닌애들은) 다 z-index: 1 줘라</p>
<p><br><br></p>
<h2 id="📌-flex만이-가능한-비율계산">📌 flex만이 가능한 비율계산!</h2>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/c8f232e6-e1c7-4e14-aabc-0db1b638db83/image.png" alt=""></p>
<p>컨텐츠들의 등분을 묶어줄때 col-2,col-3등으로 나눠준다.</p>
<blockquote>
<pre><code class="language-css">.grid-box .col-8{width: 80%;} 절반보다 살짝 큰 비율은 80% 
.grid-box .col-6{width: 60%;} 절반은 60%
.grid-box .col-4{width: 40%;} 절반보다 살짝 큰작은 비율은 40%</code></pre>
</blockquote>
<pre><code>
🤔 **왜 이런 퍼센트가 나왔을까?**

→ 기존 애플 mac에선 그리드로 12등분을 해놨다.
    난 flex로 사용했음으로 그 비율을 맞추기 위해 &lt;span style=&quot;color: red&quot;&gt;**전체가 120%라고 생각** &lt;/span&gt;하고 알아서 계산해준다!

&gt; #### 💡 주의할점 - 120%는 실질적으로 사용할 수 없는 %이다. 80%+40%가 120%여도 flex는 총 합이 100%라고 생각한다.
**flex: 1은 반으로 나눠 준다는게 아니라 &lt;span style=&quot;color: red&quot;&gt;1대1 &lt;/span&gt;로 만들어준다.**

&lt;br&gt;

## 📌 애니메이션 시작,멈춤

`animation-play-state: paused;` → 멈춤

`animation-play-state: running;` → 시작


&lt;br&gt;

### ✏ animation steps(1)
![](https://velog.velcdn.com/images/kimjiji_0/post/8de7691b-fe02-41f2-90c4-2e02e2bf4cad/image.png)

스크롤시 이미지가 부드럽게 바뀌게 해야함

처음에는 gsap를 써서 작업했으나 스크롤시 순식간에 사라지는 오류 발생
![](https://velog.velcdn.com/images/kimjiji_0/post/4d46fcbc-984e-43b6-9dd9-939c7ab1c831/image.png)
이런식 X

&gt;```css
.to(&#39;.content.security .img-area&#39;,{
        &#39;animation-delay&#39;: -72
    },&#39;a&#39;)</code></pre><p>각 이미지의 좌표를 애니메이션으로 만들어두고 스크롤을 끝냈을때의 애니메이션 딜레이를 gsap에 넣어준다.</p>
<p>gsap 트리거에 scrub(부드럽게) 필수</p>
<blockquote>
<pre><code class="language-css">animation: unlock 6s steps(1) forwards; 
animation-duration: 72s; 
animation-iteration-count: initial; /*무한반복 */
animation-play-state: paused;
animation-delay: 0s; /*처음 시작잉니까*/</code></pre>
</blockquote>
<pre><code>

여기서 가장 중요한 포인트는 `steps(1)` 각 하나씩 이동하는 것 같음 이걸 사용하면 부드럽게 연결된다.  
애니메이션을 연속적인 전환이 아니라 **끊을 수 있는애**다.




&lt;br&gt;&lt;br&gt;&lt;br&gt;

____

## 오답✍(◔◡◔)✧

### ✏ `backdrop-filter`
요소 뒤 영역에 흐림이나 색상 시프트 등 그래픽 효과를 적용할 수 있는 속성

![](https://velog.velcdn.com/images/kimjiji_0/post/b619b4ca-4954-47d0-9069-4232a83c53d1/image.png)



### ✏ **반응형일때**

모바일에서만 보이는애들은 따로 클래스를 주는게 좋다.

ex) mobile-visible, mobile-show….

&lt;br&gt;

### ✏ alt에 설명이 없다면, 제공되는 이미지가 아니라 그냥 디자인이다

![](https://velog.velcdn.com/images/kimjiji_0/post/c1bb3330-f36a-40ad-b99e-045727908057/image.png)


- 난 의미있는 이미지라 생각하여 ‘런닝하는 사람이미지’등등으로 표현하였으나
→ 그럴필요없었음!
- 설명이 필요없으면 alt에 쓰지 않아도 된다.
→ 왜냐! 리더기에 읽히지 말아야하니까
- background-img로 해도 무관하다!

&lt;br&gt;

### ✏ background로만 이미지를 꾸미고 싶을때 마크업

&gt;```html
&lt;figure class=&quot;img-area&quot;&gt;&lt;/figure&gt;</code></pre><ul>
<li>😎 figure가 뭔지 혹시나 기억안난다면???
의미없는애!!!</li>
</ul>
<p><strong>장점 → 모바일영역, 반응형할때 이미지 교체가 쉽다!</strong></p>
<blockquote>
<p>🤔 mac background이미지 사이즈가  반응형마다 다 달라요</p>
</blockquote>
<p>→ 그 사이즈마다 최적의 화질에 맞게 제작되어있기 때문에!!!
    반응형에 따른 이미지 변경하기</p>
<br>

<h3 id="✏-레이아웃">✏ 레이아웃</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/c1a5690d-d667-48dd-893e-db6ffc605dc5/image.png" alt=""></p>
<p><code>grid</code>를 사용했다면 쉽게 레이아웃을 맞출수 있지만 <code>flex</code>를 이용했다면 높이를 맞춰주고 빈칸을 만들어 주면 된다.</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/a4854e0e-47e4-406d-920f-8d51d54fd2dd/image.png" alt=""></p>
<p>마찬가지로 <code>flex</code>를 이용했을시 한줄마다 하나씩 묶어버리자!</p>
<ul>
<li>총5개의 영역으로 만들어 줘야한다</li>
<li>5개로 잡아야 맞는거임 → 반응형일때는 disply-block이면 되는거임</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[💻] Json]]></title>
            <link>https://velog.io/@kimjiji_0/json</link>
            <guid>https://velog.io/@kimjiji_0/json</guid>
            <pubDate>Wed, 05 Oct 2022 09:51:41 GMT</pubDate>
            <description><![CDATA[<p><span style="color: red"> <strong>JSON</span>( javascript Object Notation )</strong>라는 의미의 축약어로 데이터를 저장하거나 전송할 때 많이 사용 되는 경량의 <span style="background-color: rgba(242,179,188,0.5)"> DATA <strong>교환 형식</strong></span>을 의미한다.</p>
<ul>
<li><code>Javascript</code>에서 <span style="color: red"><strong>객체를 만들 때</strong></span> 사용하는 표현식.</li>
<li><span style="background-color: rgba(242,179,188,0.5)"><strong>사람과 기계 모두 이해하기 쉬우며 용량이 작아서</strong></span>, 최근에는 <code>XML</code>을 대체해서 데이터 전송에 사용한다.</li>
<li>데이터 포맷일 뿐이며 어떠한 통신 방법도, 프로그래밍 문법도 아닌 <span style="background-color: rgba(242,179,188,0.5)"><strong>단순히 데이터를 표시하는 표현 방법.</strong></span></li>
<li><span style="background-color: rgba(242,179,188,0.5)"><strong>비동기통신</strong></span>에 사용하는 대표적인 데이터 교환 형식</li>
</ul>
<p>프론트엔드가 준 데이터를 뿌리는거임!! <strong>api통신</strong></p>
<br>


<h2 id="📌-비동기통신">📌 <strong>비동기통신</strong></h2>
<p>웹페이지 <strong>사용자의 요청에 빠르고 효율적으로 응답하기 위해 동기화 하지 않는 통신 방법</strong></p>
<p>Javascript의 object(객체)와 같이 <span style="color: red"> <strong>key(속성)-value(값)</span>가 묶여진 표기법</strong>을 사용</p>
<blockquote>
<ul>
<li><strong>배열(array)</strong>는 리스트 형식 <span style="background-color: rgba(242,179,188,0.5)"> <strong>[ 대괄호 ]</strong></span></li>
</ul>
</blockquote>
<ul>
<li><strong>객체(object)</strong>는 속성 값 쌍의 집합 <span style="background-color: rgba(242,179,188,0.5)"> <strong>{ 중괄호 }</strong></span></li>
<li><strong>복수의 data</strong>는 <span style="background-color: rgba(242,179,188,0.5)"> ** , **</span>로 구분</li>
</ul>
<p>중괄호로 시작<code>{ }</code>해서 안에 쓸 데이터들을 담는다.</p>
<blockquote>
<pre><code class="language-jsx">//sample.json파일
{
    &quot;items&quot;:[
        {
            &quot;name&quot;:&quot;윤미&quot;,
            &quot;age&quot;:18
        },
        {
            &quot;name&quot;:&quot;소미&quot;,
            &quot;age&quot;:28
        },
        {
            &quot;name&quot;:&quot;미미&quot;,
            &quot;age&quot;:38
        }
    ]
}</code></pre>
</blockquote>
<pre><code>
문자열은 항상 **`&quot; &quot;`**를 이용하여 표기 해야 한다.

데이터 작성후 제이쿼리에 연결시켜준다.

![](https://velog.velcdn.com/images/kimjiji_0/post/02a75fea-dd5f-4ce4-9094-9cf36626dd82/image.png)


## 📌 fetch문법

옛날에는 `@ajax` `@getJson` 을 이용해서 json을 불러왔지만 요즘에는 &lt;span style=&quot;color: red&quot;&gt; **fetch문법**&lt;/span&gt;를 이용한다.

&gt;```jsx
fetch(&quot;./sample.json&quot;) // 가지고오고 싶은 데이터,주소도 가능
.then((response) =&gt; response.json()) //response → 받다
.then((json) =&gt; {
    // console.log(json);
    // alert(json);
    const items = json.items; //json데이터의 items에 접근
    let html = &#39;&#39;; //변수가 반복해서 계속들어갈꺼라 한번 생성
    items.forEach(item =&gt; { //개수만큼 반복해야함
        html += `&lt;li&gt;${item.name}&lt;/li&gt;`; //변수에 담음
   });
    //list(변수)
   list = document.querySelector(&#39;.list&#39;); ///.list 선택해줬음 (자바스크립스 선택법)
   list.innerHTML = html; //.list에다가 넣었음
});//</code></pre><br>

<h3 id="✏-thenresponse--responsejson">✏ .then((response) =&gt; response.json())</h3>
<p><code>response</code>를 <code>json</code>으로 받아오겠다</p>
<p>꼭  <code>response.json</code>로 받는건 아니지만 대부분이 <code>json</code>이다.</p>
<br>


<h3 id="✏-span-stylecolor-blue-span-에로우펑션">✏ <span style="color: blue">=&gt; </span> (에로우펑션)</h3>
<p>실행이라는 뜻 (새로나온 문)
쓰는법</p>
<blockquote>
<p>( ) =&gt; { }</p>
</blockquote>
<br>

<h3 id="✏-const-변수명-json변수명">✏ const 변수명= json.변수명;</h3>
<p>json안에 있는 변수명을 가져오겠다!</p>
<p><strong>const</strong>란 절대 변하지 않는 변수, 재할당 불가능한 변수(var는 가넝)</p>
<p>items 에 대한 복수선택자 <strong>forEach</strong>문을 사용</p>
<p><br><br></p>
<h2 id="📌-자바스크립트-선택법">📌 자바스크립트 선택법</h2>
<p><code>list = document.querySelector(&#39;.list&#39;);</code></p>
<blockquote>
<ul>
<li><code>querySelector</code> - 단일영역 , 여기다가 p태그를 넣으면 제일 앞에 있는 p태그 하나만 선택됨</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code>querySelectorAll</code> - 모든 영역 ex) 모든 p태그</li>
</ul>
</blockquote>
<br>

<h2 id="📌-반복문">📌 반복문</h2>
<blockquote>
<p><code>for</code> → 내가 돌릴 갯수를 설정해야함, 귀찮
<code>forEach</code>(각각) → 배열만 적어주면 갯수만큼 알아서 돌아감</p>
</blockquote>
<ul>
<li><strong><code>element</code></strong> → json정보에 들어갈 수있게 해주는애, 아무이름이든 상관없음</li>
</ul>
<blockquote>
<pre><code class="language-jsx">배열이름.forEach(element =&gt; {

});</code></pre>
</blockquote>
<pre><code>&lt;br&gt;

무조건 객체로 이루워져있다



- 객체 - 오브젝트

&gt;```jsx
    사과 = {
         당도(변수)
         당도:10,
         색:&quot;빨강&quot;,
         금액:1000
     }
    ```


### ✏ 내가 만든 html(body)에 넣고싶을때

&gt;```jsx
let html = &#39;&#39;; //html이란 변수임
&gt;
human.forEach(element =&gt; {
    html += `&lt;li&gt;${element.name}&lt;/li&gt;` //${데이터}
    // console.log(html); // 하나씩 순차적으로 실행 (과정을 볼수있음)
});
console.log(html); // 최종값</code></pre><h4 id="span-stylecolor-redlet-span-→-재할당-가능함-바뀔꺼같은-데이터면-span-stylebackground-color-rgba24217918805-letspan"><span style="color: red"><strong>let</strong> </span> → 재할당 가능함, 바뀔꺼같은 데이터면 <span style="background-color: rgba(242,179,188,0.5)"> <strong>let</strong></span></h4>
<blockquote>
<pre><code class="language-jsx">html += `&lt;li&gt;aaaa&lt;/li&gt;`
html = html + `&lt;li&gt;aaaa&lt;/li&gt;`</code></pre>
</blockquote>
<pre><code>
- **`+=`** → `html변수`에 태그를 합쳐서 `HTML`에 담는다.
그걸 배열 개수만큼 돌린다. (난 3번)

- 문자열에 변수를 보관하고 바꿀때 쓰면됨

- **` 백틱`** 을 사용하지 않고 **‘ ’** 따옴표를 쓴다면 변수를 못쓴다. 끊어써야함 → 번거로움
→ `백틱`을 사용하면 한번에 사용가능

&gt;```jsx
adult = &#39;성인&#39;
&gt;
if (element.age &lt; 20) {
    adult = &#39;미성년자&#39;
}else{
    adult = &#39;성인&#39;
}</code></pre><blockquote>
<pre><code class="language-jsx">adult = (element.age &lt; 20) ? &#39;미성년자&#39;:&#39;성인&#39;;
</code></pre>
</blockquote>
<p>pet = (element.pet) ? &#39;있다&#39;:&#39;없다&#39;;</p>
<blockquote>
</blockquote>
<p>html += <code>&lt;li&gt;이름 : ${element.name}&lt;br&gt; 성인: ${adult}&lt;br&gt; 펫: ${pet}&lt;/li&gt;</code></p>
<p>```</p>
<ul>
<li><strong><code>?</code> = <code>참</code></strong>이면</li>
<li><strong><code>:</code> = 거짓</strong>이면 (없다면)</li>
</ul>
<p><code>element.pet</code>이 조건문이 없는이유는
→ <span style="background-color: rgba(242,179,188,0.5)"> <strong>if문 자체가 참</strong></span>일때 실행되는 애임으로 <span style="background-color: rgba(242,179,188,0.5)"> <strong>자체가 조건문</strong></span>이 될수있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[💻] 실습 - 카카오페이지(데이터 바인딩)]]></title>
            <link>https://velog.io/@kimjiji_0/%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%8E%98%EC%9D%B4%EC%A7%80</link>
            <guid>https://velog.io/@kimjiji_0/%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%8E%98%EC%9D%B4%EC%A7%80</guid>
            <pubDate>Fri, 30 Sep 2022 13:35:31 GMT</pubDate>
            <description><![CDATA[<h2 id="📖-overview">📖 Overview</h2>
<p><strong>사이트명</strong>: 카카오페이지
<strong>작업 기간</strong>: 4.5일 소요
<strong>라이브러리</strong>: swiper, jQuery
<strong>유형</strong>: PC,mobile 적응형, 클론 코딩
<strong>참여도</strong>: 100%</p>
<h3 id="👀-check-point">👀 Check-point</h3>
<ul>
<li>sass로 처리할수있는가</li>
<li>Json이용하여 데이터 연동이 가능한가</li>
<li>detail페이지와 index페이지의 연동이 자유로운가</li>
</ul>
<hr>
<h3 id="sass셋팅-정리"><a href="https://fish-menu-0dd.notion.site/sass-1261718543534d6cbacac81bac0c1bfe">sass셋팅 정리</a></h3>
<p><br><br></p>
<h2 id="📌-datajson">📌 data.Json</h2>
<h3 id="✏-swiper-데이터-연동">✏ swiper 데이터 연동</h3>
<ol>
<li>html swiper 마크업 작성</li>
<li>json의 데이터를 넣을 부분은 삭제</li>
</ol>
<blockquote>
<pre><code class="language-html"></code></pre>
</blockquote>
<div class="main-slide">
                <ul class="swiper-wrapper">
             <!-- <li class="swiper-slide">
                        <a href="./detailpage.html">
                            <div class="img-box">
                                <figure>
                                    <img src="./asset/images/mb/mb1.png" alt="로맨스웹툰">
                                    <figcaption class="blind">
                                        여제화원,기다무 런칭기념, 캐시+경품 이벤트!
                                    </figcaption>
                                </figure>
                            </div>
                        </a>
                    </li> -->
                        <!-- <li class="swiper-slide">
                        <a href="./detailpage.html">
                            <div class="img-box">
                                <figure>
                                    <img src="./asset/images/mb/mb1.png" alt="로맨스웹툰">
                                    <figcaption class="blind">
                                        여제화원,기다무 런칭기념, 캐시+경품 이벤트!
                                    </figcaption>
                                </figure>
                            </div>
                        </a>
                    </li> -->
                </ul>
```

<ol start="3">
<li><p>json파일에 필요한 데이터를 생성한다.
<code>mainBanner</code> 라는 변수명을 지정한다.</p>
<br>
</li>
<li><p>대괄호 안에 해당하는 속성 및 값을 지정한다.</p>
</li>
</ol>
<blockquote>
<pre><code class="language-jsx">{
    &quot;mainBanner&quot;: [
        {
            &quot;link&quot;: &quot;./detail.html&quot;,
            &quot;imgSrc&quot;: &quot;./asset/images/mb/mb1.png&quot;,
            &quot;caption&quot;: &quot;여제화원,기다무 런칭기념, 캐시+경품 이벤트!&quot;
        },
        {
            &quot;link&quot;: &quot;./detail.html&quot;,
            &quot;imgSrc&quot;: &quot;./asset/images/mb/mb6.png&quot;,
            &quot;caption&quot;: &quot;웹툰, 그 바보짓은 바로 이녀석의 소행!&quot;
        }
    ],</code></pre>
</blockquote>
<pre><code>
5. 기존 스와이퍼 제이쿼리 위에  중괄호안 `mainBanner`라는 변수를 지정하고 json데이터의 `mainBanner`에 접근한다.
  &lt;br&gt;
6. html에 적은 마크업(주석된)을 그대로 가져와 `백틱`에 넣어 
  `${banner.데이터}`를 적는다.
&lt;br&gt;
7. `document.querySelector`으로 html에 삽입해준다.
&lt;br&gt;
8. json속성 밑에 swiper 속성을 적어준다.


&gt;```jsx
//메인슬라이드
    fetch(&quot;./asset/data/banner.json&quot;)
    .then((response) =&gt; response.json())
    .then((json) =&gt; {
  // alert(json);
        const mainBanner = json.mainBanner; //mainBanner 데이터 접근
&gt;    
        let html = &#39;&#39;;
        mainBanner.forEach(banner =&gt; {
&gt;    
            html += `&lt;li class=&quot;swiper-slide&quot;&gt;
                        &lt;a href=&quot;${banner.link}&quot;&gt;
                            &lt;div class=&quot;img-box&quot;&gt;
                                &lt;figure&gt;
                                    &lt;img src=${banner.imgSrc} alt=&quot;로맨스웹툰&quot;&gt;
                                    &lt;figcaption class=&quot;blind&quot;&gt;${banner.caption}&lt;/figcaption&gt;
                                &lt;/figure&gt;
                            &lt;/div&gt;
                        &lt;/a&gt;
                    &lt;/li&gt;`;
&gt;    
        });
        // console.log(html);
        const list = document.querySelector(&#39;.sc-visual .swiper-wrapper&#39;);
&gt;    
        list.innerHTML = html; //변수</code></pre><br>

<h3 id="✏-값이-존재할때-나오기">✏ 값이 존재할때 나오기</h3>
<blockquote>
</blockquote>
<pre><code class="language-cs"> &quot;freeToon&quot;:[
        {
            &quot;imgSrc&quot;: &quot;./asset/images/contents/free1.png&quot;,
            &quot;waitFree&quot;: true,
            &quot;new&quot;: true,
            &quot;up&quot;: true,
            &quot;view&quot;: 500000,
            &quot;title&quot;: &quot;여제화원&quot;,
            &quot;readIcon&quot;: &quot;./asset/images/icon/icon_read_count.png&quot;,
            &quot;viewPeople&quot;: &quot;10.3만명&quot;,
            &quot;link&quot;: &quot;./detail.html&quot;,
            &quot;viewWriter&quot;: &quot;PAMBA,윤점례&quot;
        },</code></pre>
<p>카카오페이지의 <code>product json</code> 데이터 생성
중괄호 안에 <strong>변수명</strong> 지정
대괄호 안에 해당하는** 속성 및 값** 지정
<strong>true로 데이터에 해당하는 값</strong>만 넣었다 뺐다 할 수 있게 셋팅한다.</p>
  <br>

<p>조건문을 만들기전 필요한 링크등을 <strong>변수</strong>로 지정한다.
거의 모든곳에 사용함으로 어디에 놓든 상관없다.</p>
<blockquote>
<pre><code>const ic_free = `&lt;img src=&quot;./asset/images/icon/badge_time.png&quot; alt=&quot;기다리면 무료&quot;&gt;`;
const ic_mili = `&lt;img src=&quot;./asset/images/icon/badge_right_million.png&quot; alt=&quot;밀리언페이지&quot; class=&quot;mp-icon&quot;&gt;&lt;/img&gt;`;
const ic_new = `&lt;img src=&quot;./asset/images/icon/icon_new.svg&quot; alt=&quot;신규&quot; /&gt;`;
const ic_up = `&lt;img src=&quot;./asset/images/icon/icon_up.svg&quot; alt=&quot;up&quot; /&gt;`;</code></pre></blockquote>
<pre><code>`const`를 쓴 이유 -&gt; 누구든 사용하고 변하지 않게 하기위해


&gt;조건문
```jsx
freeEl = (freeToon.waitFree)?ic_free:&#39;&#39;;
    //→ freeToon데이터안에 waitFree가 있다면 const ic_free가 나와라 그렇지 않다면 **빈칸**
miliEl = (freeToon.view &gt;= 1000000)?ic_mili:&#39;&#39;;
    //→ freeToon데이터안에 view가 있고 100만보다 크다면 const ic_mili가 나와라 그렇지 않다면 **빈칸**
newEl = (freeToon.new)?ic_new:&#39;&#39;;
upEl = (freeToon.up)?ic_up:&#39;&#39;;</code></pre><p><img src="https://velog.velcdn.com/images/kimjiji_0/post/4fffce06-39e4-472a-b4c7-f51bbd14485a/image.png" alt=""></p>
<p>필요한곳에 비교문을 넣어주기만 하면 끝
<strong><code>${freeEl} ${miliEl}</code></strong></p>
<br>

<h3 id="✍주의할점">✍주의할점</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/97100e96-eddb-49a4-8167-782b51357446/image.png" alt=""></p>
<p><code>json</code>을 쓸때 난 편하게 보기 위해 각 이름을 주었지만 원래는 <code>item</code>으로 통일해줘야한다.</p>
<p><br><br></p>
<h2 id="📌-클릭시-데이터-변경">📌 클릭시 데이터 변경</h2>
<p><a href="https://inpa.tistory.com/entry/HTML-%F0%9F%93%9A-%EC%86%8D%EC%84%B1-id-class-name-%EC%B0%A8%EC%9D%B4-%EC%82%AC%EC%9A%A9%EC%B2%98">id,class,name 차이</a></p>
<blockquote>
<ul>
<li><strong>id</strong> 속성 - <strong>고유한 식별</strong>을 목적으로 하는 경우 사용
-&gt; <code>input</code>과 <code>label</code>속성</li>
</ul>
</blockquote>
<ul>
<li><strong>name</strong> 속성 - form 컨트롤 요소의 값(value)을 <strong>서버로 전송</strong>하기 위해 필요한 속성
-&gt; <code>name</code> 속성은 <code>자바스크립트</code>에서 요소를 참조할 수 있게 합니다.</li>
</ul>
<p><del>### ✏ 요일-데이터 연결 : name-id로 연결</del></p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/0f107db6-7782-489c-94cb-1644b49210b9/image.png" alt=""></p>
<blockquote>
<pre><code class="language-html">  &lt;ul class=&quot;arrayDay-list&quot;&gt;
                &lt;li class=&quot;arrayDay-item active&quot; name = &quot;#monday&quot;&gt;
                    &lt;a class=&quot;today&quot;&gt;월&lt;/a&gt;
                &lt;/li&gt;
                &lt;li class=&quot;arrayDay-item&quot; name = &quot;#tuesday&quot;&gt;
                    &lt;a class=&quot;today&quot;&gt;화&lt;/a&gt;
                &lt;/li&gt;
                &lt;li class=&quot;arrayDay-item&quot; name = &quot;#wednesday&quot;&gt;
                    &lt;a class=&quot;today&quot;&gt;수&lt;/a&gt;
                &lt;/li&gt;
    ...
 &lt;/ul&gt;</code></pre>
</blockquote>
<pre><code>


&gt;```html
&lt;!-- 월요일 --&gt;
            &lt;div class=&quot;day-wrap active mon&quot; id=&quot;monday&quot;&gt;
                &lt;ul class=&quot;product-list column-3&quot;&gt;
            &lt;!-- &lt;li class=&quot;product-item&quot;&gt;
                        &lt;a href=&quot;&quot;&gt;
                            &lt;div class=&quot;img-box&quot;&gt;
&gt;                
                                &lt;div class=&quot;badge&quot;&gt;
                                    &lt;p class=&quot;img-rank&quot;&gt;1위&lt;/p&gt;
                                    &lt;img src=&quot;./asset/images/icon/bmbadge_waitfree.svg&quot; alt=&quot;&quot;&gt;
                                &lt;/div&gt;
                                &lt;img src=&quot;./asset/images/contents/webtoon2.png&quot; alt=&quot;도굴왕&quot;&gt;
                            &lt;/div&gt;
                            &lt;div class=&quot;txt-wrap&quot;&gt;
                                &lt;div class=&quot;title-box&quot;&gt;
                                    &lt;em class=&quot;title&quot;&gt;도굴왕&lt;/em&gt;
                                &lt;/div&gt;
                                &lt;div class=&quot;view-info&quot;&gt;
                                    &lt;img src=&quot;./asset/images/icon/icon_up.svg&quot; alt=&quot;업데이트&quot; class=&quot;icon-up&quot;&gt;
                                    &lt;img src=&quot;./asset/images/icon/icon_read_count.png&quot; alt=&quot;사람 아이콘&quot;&gt;
                                    &lt;span class=&quot;view-people&quot;&gt;331.9만명&lt;/span&gt;
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/a&gt;
                    &lt;/li&gt;
                &lt;/ul&gt;
&gt;                
                &lt;a href=&quot;&quot; class=&quot;dayMore-box&quot;&gt;월요 연재 더보기&lt;/a&gt;
            &lt;/div&gt;</code></pre><p>name으로 이름(요일), 데이터항목에 id 부여하여 연결한다.</p>
<blockquote>
<pre><code class="language-jsx">    // 요일별 클릭
</code></pre>
</blockquote>
<pre><code>$(&#39;.sc-array .arrayDay-item&#39;).click(function(e){
    e.preventDefault();
    day = $(this).attr(&#39;name&#39;); /*name 속성의 값 */ 
   $(this).addClass(&#39;active&#39;).siblings().removeClass(&#39;active&#39;);
   $(day).addClass(&#39;active&#39;).siblings().removeClass(&#39;active&#39;); 
    /* 나를 제외한 클래스 없애기 */
})</code></pre><pre><code>`arrayDay-item`요일이 `active`되었을 때, 다른 요일들은 `active`뺀다.
💡 json으로 다 연결시켜준 이후 그 밑에 적어준다.

-----------------잘못된 연결법

---
### ✏ 데이터교체
tab이 아닌 데이터교체로 만들어야한다

&gt;```
&lt;!-- 월요일 --&gt;
&lt;div class=&quot;day-wrap active mon&quot; &gt;
     &lt;ul class=&quot;product-list column-3&quot;&gt;
       &lt;/ul&gt;
     &lt;a href=&quot;&quot; class=&quot;dayMore-box&quot;&gt;월요 연재 더보기&lt;/a&gt;
 &lt;/div&gt;</code></pre><p>월요일 틀 하나만 준비하여 ul안에 데이터만 바꿔준다.
id값으로 <code>~~result</code> 혹은 <code>dayResult</code>란 이름이 더 좋다</p>
<p>✍ 이부분에선 <code>name = &quot;#monday&quot;</code>인 ❌name값을 쓰면 안된다.❌
굳이 쓴다면 <strong><code>data-name=&quot;monday&quot;</code></strong>으로 사용</p>
<blockquote>
<pre><code></code></pre></blockquote>
<li class="arrayDay-item active" data-name="monday">
  <a class="today">월</a>
</li>
<li class="arrayDay-item" data-name="tuesday">
  <a class="today">화</a>
</li>
...
```

<p>json데이터도 수정해야한다.
<img src="https://velog.velcdn.com/images/kimjiji_0/post/1aa7c30b-3304-4e9b-a26c-1df166f2b4d9/image.png" alt=""></p>
<p>기존 날짜별로 분류한걸 큰 틀인 <code>dayItems</code>안에 넣는다</p>
<blockquote>
<pre><code>    &quot;dayItems&quot;:[
        {
            &quot;rankNumber&quot;: &quot;1위&quot;,
            &quot;waitIcon&quot;: &quot;./asset/images/icon/bmbadge_waitfree.svg&quot;,
            &quot;imgSrc&quot;: &quot;./asset/images/contents/webtoon2.png&quot;,
            &quot;updateIcon&quot;: &quot;./asset/images/icon/icon_up.svg&quot;,
            &quot;title&quot;: &quot;도굴왕&quot;,
            &quot;readIcon&quot;: &quot;./asset/images/icon/icon_read_count.png&quot;,
            &quot;viewPeople&quot;: &quot;331.9만명&quot;,
            &quot;sort&quot;:&quot;monday&quot;
        },
        {
            &quot;rankNumber&quot;: &quot;2위&quot;,
            &quot;waitIcon&quot;: &quot;./asset/images/icon/bmbadge_waitfree.svg&quot;,
            &quot;imgSrc&quot;: &quot;./asset/images/contents/webtoon1.png&quot;,
            &quot;updateIcon&quot;: &quot;./asset/images/icon/icon_up.svg&quot;,
            &quot;title&quot;: &quot;소설 속 엑스트라&quot;,
            &quot;readIcon&quot;: &quot;./asset/images/icon/icon_read_count.png&quot;,
            &quot;viewPeople&quot;: &quot;21.6만명&quot;,
            &quot;sort&quot;:&quot;monday&quot;
        },</code></pre></blockquote>
<pre><code>**&quot;sort&quot;:&quot;데이터네임&quot;**로 요일별로 분류를 해준다.
내가 정한 `data-name=&quot;monday&quot;`을 적어주는거임
&gt;
월요일이라면 `&quot;sort&quot;:&quot;monday&quot;`
화요일이라면 `&quot;sort&quot;:&quot;tuesday&quot;`
실무에선 요일대신 숫자로 쓴다 ex)&quot;sort&quot;: 1,&quot;sort&quot;: 2,,,

### 원하는 데이터만 뽑기

자바스크립트의 **`filter`**가 필요하다.

주어진 함수의 필터를 통과하는 모든 요소를 모아 새로운 배열로 반환하는 것</code></pre><p>filter 함수
const result = data.filter(function (a) {return a.sort == val});</p>
<pre><code>
&gt;```jsx
val = $(this).data(&#39;name&#39;);
const data = json.dayItems;
//json에 담겨있는 json.dayItems를 변수명에 저장
const result = data.filter(function (a) {return a.sort == &#39;monday&#39;});
// function (a)의 a는 임의로 지정, 의미없는것
//내가 지정한 **sort**값이 **monday**면 monday만 나와라</code></pre><p>이렇게 지정한다면 강제로 monday값이 들어감으로 어디를 눌러도 monday값만 나온다</p>
<blockquote>
</blockquote>
<p><strong>function (a)의 a는 임의로 지정, 의미없는것</strong></p>
<blockquote>
<br>

</blockquote>
<pre><code class="language-jsx">const result = data.filter(function (a) {return a.sort == val});    
&gt;</code></pre>
<p>분류되는 <code>sort</code>값이 <strong><code>val = $(this).data(&#39;name&#39;);</code></strong>이 되게 해준다</p>
<br>

<h3 id="요일클릭시-연재더보기-글씨-변경">요일클릭시 연재더보기 글씨 변경</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/d0d0b6ae-9a7b-4f22-adcc-c5e2ff7e2abc/image.png" alt=""></p>
<p>바꾸려는 dotay의 이름을 가져와야한다.</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/60498167-178b-4182-a3bf-5ba1f6e40433/image.png" alt=""></p>
<ol>
<li>변수로 만들어주기</li>
</ol>
<blockquote>
<pre><code class="language-jsx">dateName = $(this).find(&#39;.today&#39;).text();</code></pre>
</blockquote>
<pre><code>this의 클래스 today의 텍스트를 찾아라를 변수로 만드는것


2. 내가 바꾸려는 클래스

&gt;```jsx
$(&#39;.dayMore-box&#39;).text(${dateName} 연재 더보기)</code></pre><p>text부분은 html도 상관없음</p>
<br>

<h2 id="📌-강제로-시작-trigger">📌 강제로 시작 trigger</h2>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/4f48827b-93d1-49f9-b2a7-f08c02ab3e92/image.png" alt=""></p>
<blockquote>
<pre><code class="language-jsx">$(&#39;.arrayDay-item&#39;).eq(0).trigger(&#39;click&#39;);</code></pre>
</blockquote>
<pre><code>시작시 강제로 0번째 즉 월요일이 클릭되어 나타나있게하기
eq - 태그에서 몇번째



&lt;br&gt;

## 📌 마크업
### ✏ width 사이즈
`w 400`을 주면 안됨, 모바일에 있을수 없는 사이즈
### ✏ 공통 css

![](https://velog.velcdn.com/images/kimjiji_0/post/f74294af-fe78-45f8-91c5-7245b1cdbbe5/image.png)

카카오페이지는 공통된 레이아웃이 많다
→ 공통으로 마크업하는게 좋다!

&gt; ``` css
&amp;.column-2{
        padding: 17px 20.7px 5px;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        gap: 5px;
        .product-item{
            width: calc(50% - 5px);
        }
    }</code></pre><p>column-2,column-3,row-1,row-2와 같이 공통 레이아웃을 만들어 통제해주는게 쉽고 빠르다.</p>
<h2 id="📌-grid">📌 grid</h2>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/e4422aff-2123-421c-87d2-1cfd3aefe251/image.png" alt=""></p>
<p>이런식의 레이아웃 반복에는 flex보다 grid를 추천한다</p>
<p> -&gt;중간에 데이터가 하나 없을시 <code>flex</code>의 <code>justify-content: space-between;</code>보다 편하기 때문</p>
<h3 id="✏-사용법">✏ 사용법</h3>
<blockquote>
<pre><code class="language-css">display: grid;
gap: 10px;
grid-template-columns: repeat(3, minmax(0, 1fr));</code></pre>
</blockquote>
<pre><code>열 - **grid-template-columns**
행 - **grid-template-rows**


1fr - 1대1, 여기서는 3분의1쓰겠다
grid-template-columns: 1fr 1fr 1fr;
이렇게 쓰는것보다
grid-template-columns: repeat(3,1fr);
3번쓸꺼다, 즉 3분의 1대1대1 3분의1이 나와라
px도 가능하다

왜 줬냐 -&gt; 글자가 너무 길어서 말줄임이 안먹어서 강제로 준것

minmax함수
사용법
minmax(0, 1fr)
minmax(최솟값, 최댓값)
최솟값과 최댓값 범위내에서 값을 유연하게 처리한다.



&lt;br&gt;

## 📌 swiper
### ✏ 부드럽게 움직이기
![](https://velog.velcdn.com/images/kimjiji_0/post/aba2fc87-7767-4bd4-ae66-a643c98c3370/image.png)

&gt;```jsx
var lastSlide = new Swiper(&quot;.sc-event .swiper&quot;, {
        spaceBetween: 10,
        freeMode: true,
        slidesPerView: &#39;auto&#39;,
      });</code></pre><p><code>swiper</code>시 <strong><code>freeMode: true</code></strong>를 주면 부드럽게 넘어감</p>
<br>

<h2 id="📌-페이지-링크이동">📌 페이지 링크이동</h2>
<h3 id="✏-a태그-href">✏ a태그 href</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/563fa146-d224-4671-b48f-ad7068d1619b/image.png" alt=""></p>
<p>a태그 안 주소를 쓸때 <code>/</code>(상단페이지로 이동)만 써도 된다.</p>
<p>다만 <code>/</code>만 쓸시 깃헙에서 사용할시에
<strong><code>ㅇㅇㅇ.깃헙.io/폴더경로/index</code></strong>로 폴더경로가 겹쳐서<br>(❌)<strong>절대경로</strong>인<strong><code>ㅇㅇㅇ.깃헙.io/</code></strong>로 나온다. </p>
<p>(⭕)그렇기에 <span style="background-color: rgba(242,179,188,0.5)"><strong>./</strong> </span> 혹은 <span style="background-color: rgba(242,179,188,0.5)"> <strong>./index</strong></span>라고 작성해야한다.</p>
<p><br><br></p>
<hr>
<h3 id="오답✍◔◡◔✧">오답✍(◔◡◔)✧</h3>
<ol>
<li><img src="https://velog.velcdn.com/images/kimjiji_0/post/9296168c-5ad5-4988-aa8d-43983ddc7bdb/image.png" alt=""></li>
</ol>
<blockquote>
<p>⛔ img-box 클래스 이름 주의할점!!! 광범위한 img-box이름은 에러</p>
</blockquote>
<ul>
<li><p>img-box는 너무 광범위하고 당돌한  클래스이름이다.</p>
</li>
<li><p>다른 sc에서 img-box가 엄청나게 나올수있고 사용하지 않을 수도 있다.</p>
</li>
<li><p>협업에 있어서 불가능한 소스다.</p>
</li>
<li><p>섹션 img-box 마다 다른 이름을 주는게 좋다.</p>
</li>
</ul>
<br>

<ol start="2">
<li><img src="https://velog.velcdn.com/images/kimjiji_0/post/68981de0-6d32-4d96-93cb-93bb4620b117/image.png" alt=""></li>
</ol>
<p>아이콘인 <code>시계표시,up, 15</code>는 꾸미는 용도가 아니라 각 필요한 정보가 있는 애다.</p>
<p><strong>정보전달이 필요한 애임으로 img태그로 들어가야한다.</strong></p>
<p>⭐ 이미지가 <code>before</code>가 아니라 <strong>자식태그</strong>여야한다</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/b38f06b6-2806-4cd7-90c7-d90774de9dc2/image.png" alt=""></p>
<blockquote>
<pre><code></code></pre></blockquote>
<div class="img-box">
    <div class="badge">
         <img src="./asset/images/icon/badge_time.png" alt="">
    </div>
    <img src="./asset/images/contents/challenge1.png" alt="로열 메리지">
</div>
```
`img-box`안에 `badge`라는 태그를 하나 만들어 반복되는 `img`를 꾸며준다.


<ul>
<li>제목 옆 N이미지는 vertical-align:top을 줄 수있지만 margin-top:-2px로 맞춰줄수있다</li>
</ul>
<blockquote>
<h4 id="🤔-왜-vertical-alignmiddle로-안줄까">🤔 왜 vertical-align:middle로 안줄까??</h4>
<p>-&gt; 글씨도 내려가면서 작아지니까</p>
</blockquote>
<p>서로서로 기준이기 때문에 top을 기준으로 두고 이미지만 내리는게 맞음</p>
<br>

<p>3.<img src="https://velog.velcdn.com/images/kimjiji_0/post/6db64687-85ad-4666-9a18-aee8380f3408/image.png" alt=""></p>
<p>부모에 flex를 주고 자식인 p태그에 with를 주지 않고 말줄임 코드를 사용하는것은 오류!</p>
<p>-&gt; <code>flex:1;</code>이라고 셋팅해야함</p>
<p>4.⭐⭐⭐ 바보같은 실수금지!!!
<img src="https://velog.velcdn.com/images/kimjiji_0/post/0d67759e-2034-4068-8192-0a3ac31cadea/image.png" alt=""></p>
<p>뒤로가기 이미지 안나옴</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/fc0d6017-e462-489b-b4e4-81fcb6ba5f13/image.png" alt=""></p>
<p>scss에서 보면 경로를 잘못적어놨다. 😢</p>
<blockquote>
<p>../../는 있을수 없는 경로</p>
</blockquote>
<p>수정하면 <code>detail.scss</code>에 줬던 css를 지워도 나오게 된다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[💻] 실습 - barcelona (gsap)]]></title>
            <link>https://velog.io/@kimjiji_0/barcelona-gsap</link>
            <guid>https://velog.io/@kimjiji_0/barcelona-gsap</guid>
            <pubDate>Fri, 30 Sep 2022 13:35:23 GMT</pubDate>
            <description><![CDATA[<h2 id="📖-overview">📖 Overview</h2>
<p><strong>사이트명</strong>: barcelona
<strong>작업 기간</strong>: 3일 소요
<strong>라이브러리</strong>: swiper, jQuery, gsap
<strong>유형</strong>: PC 적응형, 클론 코딩
<strong>참여도</strong>: 100%</p>
<h3 id="👀-check-point">👀 Check-point</h3>
<ul>
<li>화살표에 따른 좌표 구하기</li>
<li>스크롤이벤트 <code>scrollTrigger</code>에 대한 이해</li>
<li>root 변수에 대한 응용</li>
</ul>
<hr>
<h2 id="📌-root">📌 root</h2>
<p>전역 CSS 변수 선언을 함으로써 아주 유용하게 사용할 수 있다!!
sass처럼 변수를 써주는거다.</p>
<blockquote>
<pre><code class="language-css">:root{
    --font-en1:&#39;hatton&#39;,Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, &#39;Helvetica Neue&#39;, &#39;Segoe UI&#39;, &#39;Apple SD Gothic Neo&#39;, &#39;Noto Sans KR&#39;, &#39;Malgun Gothic&#39;, sans-serif;
    --font-en2:&#39;Montserrat&#39;,Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, &#39;Helvetica Neue&#39;, &#39;Segoe UI&#39;, &#39;Apple SD Gothic Neo&#39;, &#39;Noto Sans KR&#39;, &#39;Malgun Gothic&#39;, sans-serif;
    --color-green:#81d8d0;
}</code></pre>
</blockquote>
<pre><code>


- 공통으로 들어갈 폰트와 색을 넣어준다.
-&gt;`--color-green:#81d8d0;` 여기서 green은 내가 정한 변수
=&gt; --변수-명: 값;
css에서 적용 시 =&gt; :var(--해당변수명-)

- `font family`로 폰트들을 다 설정해놓은 다음 변수 지정해주는것

&gt;```css
.sc-visual .txt-title{
    font-family: var(--font-en1);
}</code></pre><ul>
<li>이런식으로 내가 쓰려는 클래스에 var를 써서 폰트를 불러오면 된다.
-&gt; 위에 설정해놓은 값처럼 폰트가 지정됨</li>
</ul>
<br>

<ul>
<li>이미 변수로 값을 설정해두었기에 상단에서 값을 한 번에 제어가 가능하다.</li>
<li>후에 값을 선택자마다 하나씩 바꾸지 않고 변수 값에서의 스타일만 수정하면 아주 간편하게 유지보수가 가능하다!</li>
</ul>
<br>

<h2 id="📌-기본-폰트">📌 기본 폰트</h2>
<blockquote>
<p>sans-serif → 고딕체 /  serif→ 명조체</p>
</blockquote>
<br>


<h2 id="📌-swiper-slide-active">📌 swiper-slide-active</h2>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/b11b2652-9f23-44a5-baf0-6251dded6336/image.png" alt=""></p>
<h3 id="✏-이미지-자연스럽게-확대되면서-넘어가기">✏ 이미지 자연스럽게 확대되면서 넘어가기</h3>
<p><code>swiper</code>에 특정 이벤트를 넣어주고 싶다면 <code>swiper-slide-active</code>에 css 넣어주기</p>
<blockquote>
<pre><code class="language-css">.sc-visual img{
    width: 100%;
    height: 100vh;
    object-fit: cover;
    transform: scale(1.2);
    transition: transform 5s linear; //linear - 일정하게
}
.sc-visual .swiper-slide-active img{
    transform: scale(1);
}</code></pre>
</blockquote>
<pre><code>
- 항상 `transition` 뒤에는 누가한테 효과를 줄건지 써둘것, 안그러면 다른애들까지 효과가 다 적용된다.


&lt;br&gt;


### ✏ swiper시 글자가 밑에서 위로 올라오기

&gt;``` html
&lt;h3 class=&quot;txt-box&quot;&gt;
    &lt;span class=&quot;txt-title&quot;&gt;&lt;b&gt;we are different&lt;/b&gt;&lt;/span&gt;
    &lt;span class=&quot;txt-info&quot;&gt;&lt;b&gt;get to know us&lt;/b&gt;&lt;/span&gt;
&lt;/h3&gt;</code></pre><p>글자가 슬라이드시 밑에서 올라와야하니 b태그로 감싸준다
(꾸며주기 위한것 의미없음)</p>
<br>

<p><span style="background-color: rgba(242,179,188,0.5)"> <strong>⭐ transform은 display가 없으면 사용할수가 없음</strong></span></p>
<p>그렇기 때문에 <code>부모</code>(txt-title)에도 <code>display</code>, 주려는 <code>자신</code>(b)에도 display를 줘야한다.</p>
<blockquote>
<pre><code class="language-jsx">$(window).scroll(function(){
        curr = $(this).scrollTop();
        visualHeight = $(&#39;.sc-visual&#39;).outerHeight();
        // scvisual = $(&#39;.sc-visual&#39;).outerHeight();
        if (curr &gt; visualHeight) {
            $(&#39;.header&#39;).addClass(&#39;active&#39;);
        } else {
            $(&#39;.header&#39;).removeClass(&#39;active&#39;);
        }
});</code></pre>
</blockquote>
<pre><code>


### ✍ 오류사항
#### 글씨가 잘릴때는??

![](https://velog.velcdn.com/images/kimjiji_0/post/cd76839d-11e2-40ab-8467-e78ce2119d7d/image.png)

### **✍ 해결사항**

1. `padding`을 준다.
2. `line-height`를 늘려준다.



&lt;br&gt;

### ✏ 헤더 active, 특정 지역에서 수행하기

![](https://velog.velcdn.com/images/kimjiji_0/post/4a6c1793-ed1f-4272-83fd-ef8c81316a2c/image.png)

![](https://velog.velcdn.com/images/kimjiji_0/post/e377e7d2-dd03-476c-9ce0-997869b19917/image.png)



&gt;```jsx
$(window).scroll(function(){
        curr = $(this).scrollTop();
        scvisual = $(&#39;.sc-visual&#39;).outerHeight(); -&gt; 비주얼영역 높이
    // visualHeight = $(&#39;.sc-visual&#39;).outerHeight();
        if (curr &gt; scvisual) {
            $(&#39;.header&#39;).addClass(&#39;active&#39;);
        } else {
            $(&#39;.header&#39;).removeClass(&#39;active&#39;);
        }
    });</code></pre><p>◼ 2가지 방법이 있다</p>
<ol>
<li>기준잡기</li>
<li>헤더의 높이만큼을 계산하기</li>
</ol>
<p>🤔 curr, scvisual등등 왜 변수로 써주는거에요??
→ 재활용 하려고!!</p>
<br>

<h2 id="📌-swiper터치-이벤트">📌 Swiper터치 이벤트</h2>
<p><a href="https://swiperjs.com/swiper-api">Swiper API</a>
Swiper API에서 터치 검색 touch-end</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/6d1484ec-6368-42c3-81c5-eef00b26ffd6/image.png" alt=""></p>
<p><strong><code>touchstart</code></strong>  →  손가락 닿을 때 발생</p>
<p>*<em><code>touchmove</code> *</em> →  손가락이 닿은 채 움직일 때 발생</p>
<p><strong><code>touchend</code></strong>  →   손가락을 뗄 때 발생</p>
<blockquote>
<pre><code class="language-jsx">featuredSlide.on(&#39;touchStart&#39;,function(){
        $(&#39;.sc-featured .mid-slide&#39;).addClass(&#39;grab&#39;)
        console.log(1);
      })
featuredSlide.on(&#39;touchEnd&#39;,function(){
        $(&#39;.sc-featured .mid-slide&#39;).removeClass(&#39;grab&#39;)
        console.log(2);
      })</code></pre>
</blockquote>
<pre><code>```css
.sc-featured .mid-slide.grab .img-box{
    transform: scale(0.95);
}
.sc-featured .mid-slide.grab img{
    transform: scale(1.2);
}</code></pre><ul>
<li><p>featureSlide는 내가 지정했던 변수(Swiper)이름임</p>
</li>
<li><p>터치 될때 grab클래스 추가해라, 손을 땔떼 grab클래스를 빼라</p>
</li>
<li><p>잡히는게 더 극적으로 보이게하기 위해 이미지감싸고있는 박스에 작아지는 스케일줌</p>
</li>
</ul>
<br>


<h2 id="📌-다른영역-클릭시-닫기">📌 다른영역 클릭시 닫기</h2>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/6337a571-b453-4dd6-8d32-af85c9599b7c/image.png" alt=""></p>
<blockquote>
<pre><code class="language-jsx">$(&#39;header&#39;).click(function(e){
        if( !$(&#39;.header .util-area .link-wrap&#39;).has(e.target).length )
          $(&#39;.header .util-area .link-wrap&#39;).removeClass(&#39;open&#39;);
    });</code></pre>
</blockquote>
<pre><code>
header안에는 body나 wrap등 내가 클릭하려는 요소의 외의 요소를 넣어준다.


&lt;br&gt;


## 📌 메뉴클릭시 하나씩 나타나기
![](https://velog.velcdn.com/images/kimjiji_0/post/e07ca304-5cdb-44a4-bf61-1e601cebdf2a/image.png)

&gt;```css
.header .menu-area .menu-body .menu-item{
    width: 30%;
    transform: translateY(20%);
    transition:  transform 1.2s, opacity 1.2s;
    opacity: 0;
}</code></pre><p>이벤트를 주려는 클래스에 속도와 투명도를 주고</p>
<blockquote>
<pre><code class="language-css">.header .menu-area.active .menu-body .menu-item:nth-child(1){
        transition-delay: 0.3s;
}
.header .menu-area.active .menu-body .menu-item:nth-child(2){
        transition-delay: 0.4s;
}
.header .menu-area.active .menu-body .menu-item:nth-child(3){
        transition-delay: 0.5s;
}
.header .menu-area.active .menu-body .menu-item:nth-child(4){
        transition-delay: 0.6s;
}
.header .menu-area.active .menu-body .menu-item:nth-child(5){
        transition-delay: 0.7s;
}
.header .menu-area.active .menu-body .menu-item:nth-child(6){
        transition-delay: 0.8s;
}</code></pre>
</blockquote>
<pre><code>
제이쿼리를 실행했을때 하나하나에 `delay`를 준다.

➕


`nth-child`로 했을시 새로운 영역이 추가됐을때 css에서 계속 추가해줘야하는 번거로움이 있다.

&gt;```jsx
const menu = gsap.from(&#39;.menu-area .menu-item&#39;,{
        // delay:1,
        opacity:0,
        yPercent:20,
        stagger:0.1, //시간차
        paused:true, //정지 (미리실행되면 안되니까_)
    })</code></pre><p><code>gsap.from</code>으로 이벤트가 실행되기 전을 셋팅해준다.
만들어준 제이쿼리에 재생할때마다 실행되게하기</p>
<blockquote>
<pre><code class="language-jsx">$(&#39;.header .util-area .btn-menu&#39;).click(function(e){
        e.preventDefault();
</code></pre>
</blockquote>
<pre><code>    menu.restart()</code></pre><blockquote>
</blockquote>
<pre><code>    $(&#39;.menu-area&#39;).addClass(&#39;active&#39;);
    $(&#39;body&#39;).addClass(&#39;active&#39;);        
});</code></pre><pre><code>
 지정한 변수`menu`를 누를때마다 실행하게 하기
 -&gt; &lt;span style=&quot;color: red&quot;&gt; **`menu.restart()`**&lt;/span&gt;


#### 🤔 왜 `gsap`를 변수 `const`로 줬나요??
변수로 지정하지 않으면 새로고침했을때 바로 실행된다.

&lt;br&gt;&lt;br&gt;




## 📌 scroll-down 클릭시 해당영역으로 내려가기

![](https://velog.velcdn.com/images/kimjiji_0/post/979b9b65-b3dc-4174-a25c-f49aeefc0326/image.png)


&gt;```jsx
$(&#39;.sc-visual .scroll-down&#39;).click(function(){
        target = $(&#39;.sc-featured&#39;).offset().top+1
$(&#39;html,body&#39;).animate({scrollTop:target},300)
    })</code></pre><pre><code class="language-jsx">$(&#39;html,body&#39;).animate({scrollTop:target},300) </code></pre>
<p>$(&#39;여길기준으로&#39;).animate({scrollTop:이위치로},300) 0.3초동안 스르르ㅡ이동</p>
<br>


<h2 id="📌-스크롤바-변경">📌 스크롤바 변경</h2>
<blockquote>
</blockquote>
<pre><code class="language-css">body::-webkit-scrollbar {
    width: 7px;  /* 스크롤바의 너비 */
}
&gt;
body::-webkit-scrollbar-thumb {
    height: 10%; /* 스크롤바의 길이 */
    background: rgba(31, 31, 31, 0.5); /* 스크롤바의 색상 */    
    border-radius: 10px;
}
&gt;
body::-webkit-scrollbar-track {
    background: transparent;
    opacity: 1;  /*스크롤바 뒷 배경 색상*/
}</code></pre>
<br>



<h2 id="📌-html-특수문자">📌 html 특수문자</h2>
<blockquote>
<p><strong>‹</strong>    <code>&amp;lsaquo;</code>    왼쪽 홑꺽쇠표
<strong>›</strong>    <code>&amp;rsaquo;</code>    오른쪽 홑꺽쇠표</p>
</blockquote>
<br>

<h2 id="📌-gsap">📌 Gsap</h2>
<h3 id="✏-마우스를-따라다니는애-좌표구하기">✏ 마우스를 따라다니는애, 좌표구하기</h3>
<p>이벤트를 먼저 구해야한다.
<strong>좌표먼저 구하기</strong></p>
<blockquote>
<ol>
<li>문서의 시작지점부터 끝까지 좌표</li>
<li>보고있는 현재화면의 좌표</li>
<li>영역에서의 좌표</li>
</ol>
</blockquote>
<p>마우스를 따라다니는애를 구하려면 <strong>2. 보고있는 현재화면의 좌표가 필요하다</strong></p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/424eff0e-138d-4eee-b0ad-8f6cc85a5cf6/image.png" alt=""></p>
<p><strong>자식요소까지 인식하는가 차이</strong>
<code>mouseover</code>, <code>mouseout</code>는 자식 요소에 접근해도 동작을 하지만,</p>
<p><code>mouseenter</code>, <code>mouseleave</code>는 자식 요소에는 동작하지 않는다.</p>
<br>


<p><strong><code>mousemove</code></strong> : 마우스를 움직일 때 발생</p>
<p><strong><code>mouseover</code></strong> : 마우스를 요소 안에 들어올 때 발생</p>
<p><strong><code>mouseleave</code></strong> : 마우스가 요소의 경계 내부에서 외부로 이동할 때 발생</p>
<br>

<p>현재화면의 <code>x</code>의 좌표,<code>y</code>의 좌표값</p>
<blockquote>
<pre><code class="language-jsx">xVal = e.clientX;
yVal = e.clientY;</code></pre>
</blockquote>
<pre><code>
&gt;```jsx
$(&#39;body&#39;).mousemove(function(e){
        xVal = e.clientX;
        yVal = e.clientY;
        // console.log(xVal+&#39;//&#39;+yVal);
        gsap.to(&#39;.cursor&#39;,{
            x:xVal,
            y:yVal
  })</code></pre><p>생긴 포인터때문에 뒤에 내용이 선택이 안될 수 있다.</p>
<blockquote>
<pre><code class="language-css">pointer-events: none; //css에 작성</code></pre>
</blockquote>
<pre><code>
![](https://velog.velcdn.com/images/kimjiji_0/post/5b3ae965-efd8-4f18-94e3-85ab795775bd/image.png)

`pointer-event`를 써서 뒤에가 선택되게한다. 마치 포인터가 뒤로 뚫린느낌!!




&gt;
**`mouseover`** : 마우스를 요소 안에 들어올 때 발생
```jsx
$(&#39;a&#39;).mouseover(function(){
        if($(this).data(&#39;name&#39;)){
            val = $(this).data(&#39;name&#39;);
        }else{
            val=&#39;&#39;
        }
    /*$(this).data(&#39;name&#39;)?val=$(this).data(&#39;name&#39;):val=&#39;&#39;;*/ //줄여쓰기
        gsap.to(&#39;.cursor&#39;,{
            scale:1.8,
            opacity:0.7
        })
})</code></pre><blockquote>
</blockquote>
<p><strong><code>mouseleave</code></strong> : 마우스가 요소의 경계 내부에서 외부로 이동할 때 발생</p>
<pre><code class="language-jsx">$(&#39;a&#39;).mouseleave(function(){
        $(&#39;.cursor&#39;).text(&#39;&#39;);
        gsap.to(&#39;.cursor&#39;,{
            scale:1,
            opacity:1
        })
})</code></pre>
<br>

<h3 id="✏-mouseover시-글자-나타나기">✏ mouseover시 글자 나타나기</h3>
<blockquote>
<pre><code class="language-jsx">if($(this).data(&#39;name&#39;)){
            val = $(this).data(&#39;name&#39;);
        }else{
            val=&#39;&#39;
        }
</code></pre>
</blockquote>
<pre><code>   //줄여쓰기 $(this).data(&#39;name&#39;)?val=$(this).data(&#39;name&#39;):val=&#39;&#39;;</code></pre><blockquote>
<pre><code>   //줄여쓰기 
    val = $(this).data(&#39;name&#39;)?$(this).data(&#39;name&#39;):&#39;&#39;;
   //줄여쓰기 =&gt;$(&#39;.cursor&#39;).html(`&lt;span&gt;${val}&lt;/span&gt;`);

   // if ($(this).parents(&#39;.sc-featured&#39;).length) {
    //     // $(&#39;.cursor&#39;).text(&#39;featured&#39;);
    //     $(&#39;.cursor&#39;).html(&#39;&lt;span&gt;featured&lt;/span&gt;&#39;);
    // }else if ($(this).parents(&#39;.recom-artist-area&#39;).length) {
    //     $(&#39;.cursor&#39;).html(&#39;&lt;span&gt;추가&lt;/span&gt;&#39;);
    // }</code></pre></blockquote>
<pre><code>



&lt;br&gt;
</code></pre><h3 id="✏-스크롤이벤트">✏ 스크롤이벤트</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/18830267-8085-4942-851b-bcdcb6145dc3/image.png" alt=""></p>
<pre><code class="language-jsx">gsap.to(&#39;.recom-artist-area .img-box&#39;,{
        // y:-180 픽셀
        scrollTrigger:{
            trigger:&quot;.recom-artist-area&quot;, //총구,기준태그 recom-artist-area의 시작과 끝
            start:&quot;top 80%&quot;, //(트리거기준, 윈도우기준) 둘이 만나야 실행
            end: &quot;bottom top&quot;, //(트리거기준, 윈도우기준) 둘이 만나야 실행
            markers:true, //좌표표시
            scrub:1, //이게 있어야 여러번 사용가능, 없으면 1회성
        }, //컴마 필수

        yPercent:-10 //퍼센테이지, 움직이는 애가 -10%까지 가라
    })</code></pre>
<p><code>start:&quot;top 80%&quot;</code> → 윈도우기준이 <code>100%</code> 혹은 그냥 <code>bottom</code>이였다면 흐르는게 잘 안보임으로 <code>80%</code>정도가 적당하다.</p>
<br>

<h3 id="✏-스크롤시-텍스트-움직이기-gsap">✏ 스크롤시 텍스트 움직이기 (gsap)</h3>
<p><strong><code>scrollTrigger</code></strong>을 이용하여 간편하게 흐를수있게 만들어줌</p>
<blockquote>
<pre><code class="language-jsx">gsap.to(&#39;.txt-area&#39;,{
</code></pre>
</blockquote>
<pre><code>    scrollTrigger:{
        trigger:&quot;.txt-area&quot;, //기준태그 recom-artist-area의 시작과 끝
        start:&quot;top 100%&quot;, //(트리거기준, 윈도우) 둘이 만나야 실행
        end: &quot;bottom top&quot;, //(트리거기준, 윈도우) 둘이 만나야 실행
        // markers:true, //좌표표시
        scrub:1, //이게 있어야 여러번 사용가능, 없으면 1회성
    }, //컴마 필수</code></pre><blockquote>
</blockquote>
<pre><code>    xPercent:-50 //움직이는 애가 -100프로까지 가라
  })</code></pre><pre><code>

&lt;br&gt;

## 📌 동영상 iframe

`.contract-box` 클릭시 동영상 링크인 iframe으로 이동하기


&gt;```jsx
$(&#39;.contract-box&#39;).click(function(){
        iframe = `&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/omuSTuF-fxk?autoplay=1&amp;mute=1&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;`
        $(this).html(iframe)
      })</code></pre><br>

<h3 id="✏-iframe-추출법">✏ iframe 추출법</h3>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/e02240c0-1dff-4a5a-bed3-75776a63978e/image.png" alt=""></p>
<p>퍼가기에서 코드추출</p>
<p><br><br></p>
<hr>
<h2 id="오답✍◔◡◔✧">오답✍(◔◡◔)✧</h2>
<p>1.<img src="https://velog.velcdn.com/images/kimjiji_0/post/cc468182-3eb2-4e9d-8764-1524122ee38c/image.png" alt=""></p>
<p>swiper에서 btn-nav는 클래스 공통으로 주면된다.
괜히 btn-nav1,2,3쓰지 않기</p>
<br>


<p>2.</p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/613100c9-9ac5-4f1a-8c39-b0018ca232b7/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/kimjiji_0/post/6133980c-9aaf-4137-8c04-cb5ac18ae868/image.png" alt=""></p>
<blockquote>
<pre><code></code></pre></blockquote>
<div class="img-box"><img src="./asset/imges/contents/biglarge_Tiger_Gaulino_469c752944.jpg" alt=""></div>
<div class="txt-box">
  <strong class="txt-subtitle">art editions</strong>
  <h3 class="txt-title">tiger art gaulino</h3>
  <span class="txt-madeby">oscar tusquets</span>
</div>
```

<blockquote>
<pre><code class="language-css">.recom-artist-area .txt-box{
    padding: 20% 0;
    text-align: center;
    color: #fff;
}</code></pre>
</blockquote>
<pre><code>
- 이미지로 높이잡기
→❌ 좋지않음

이미지가 없으면 높이가 사라지게 된다.
-&gt;공존하는 것은 좋지 않다.❌

이미지말고 text한테 패딩을 줘서 크게 영역을 잡아준다. → 더 편해짐


&lt;br&gt;&lt;br&gt;&lt;br&gt;


💬
gsap는 해도해도 어렵다...
스스로 예제 만들어서 여러번 반복해보자


</code></pre>]]></description>
        </item>
    </channel>
</rss>