Web

[프론트엔드 날개달기 by짐코딩] DOM, 이벤트, js 함수, 웹팩, 외

반응형
DOM  Document Object  Model  문서 객체 모델(The Document Object Model, 이하 DOM) 은 HTML, XML 문서의 프로그래밍 interface 이다.  - 표준화(W3C)
출처 : https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction


document.getRootNode()  -> #document
document.childNodes[1].childNodes[1].textContent
document.querySelector('h1')

BOM  Browser Object Model BOM은 웹 브라우저가 제공하는 객체들

DOM (문서 객체 모델): 웹 페이지의 내용과 구조를 제어 BOM (브라우저 객체 모델): 웹 페이지가 표시되는 브라우저 환경을 제어
BOM (브라우저 객체 모델): 웹 페이지가 표시되는 브라우저 환경을 제어
window 
window.open()   == (생략가능)  open()
window의 하위객체 document , navication .....


출처 : https://en.wikipedia.org/wiki/Browser_Object_Model
window  document DOM
navigator 브라우저의 정보 (버전, 플랫폼, userAgent 등)

navigator.geolocation.getCurrentPosition(
  function(pos) {
    console.log("위도:", pos.coords.latitude);
    console.log("경도:", pos.coords.longitude);
  },
  function(err) {
    console.error("에러 발생:", err.code, err.message);
  }
);
location 현재 URL 정보 및 주소 이동 기능
history 사용자의 방문 기록을 제어 (back(), forward() 등)
screen 사용자의 화면 해상도, 색상 정보 등
COM  Css Object Model    
js태그

과거
1. button  등록후 js 실행
<button>버튼<button>
<script type="text/javascript" async="" src="/index.gtm.min.js"></script>

2. 이벤트 실행 
- DOMContentLoaded 는 HTML 완전히 파싱되었을때 바로 실행 추천 onload 보다 이미지, 리소스 기다리지 않아 더 빠름
- window.onload = function () {
   console.log("DOM이 모두 준비되었습니다!");
};
-  document.addEventListener("DOMContentLoaded", function () {
  console.log("DOM이 모두 준비되었습니다!");
});

defer (일반적사용) HTML5 비동기로 js 코드 가져옴 = Html 과 병렬로 가져옴 , 실행은 HTML 파싱후 실행(DOMContentLoaded 직전 ) <script src="script.js" defer></script>
async HTML5 비동기로 js 코드 가져옴 = Html 과 병렬로 가져옴 , 실행은 가져오자마자 실행 - HTML 로딩이 중지됨
<script src="script.js" async></script>
this 누구에 의해 호출되었는지
기본호출 기본값 전역에서
console.log(this === window);  // 브라우저 환경에서는 `window` 객체
기본함수에서
console.log(this); //  브라우저 환경에서는 `window` 객체
객체 메서드안 const obj = {
  name: "hello",
  sayHi: function () {
    console.log(this.name);
  }
};
const f = obj.sayHi.bind(obj);
f(); // 👉 "hello"
람다식 const obj = {
  name: "hi",
  sayHi: () => {
    console.log(this.name);
  }
};
obj.sayHi();   //undefined
strict 모드
(엄격모드 활성화시)
"use strict";

function show() {
  console.log(this);  // undefined
}
show();
bind bind 는 최초 1번만 됨. function sayName() {
  console.log(this.name);
}

const person1 = { name: "Alice" };
const person2 = { name: "Bob" };

const bound1 = sayName.bind(person1);   // this → person1
const bound2 = bound1.bind(person2);    // ❌ 무의미, 여전히 person1

bound1(); // Alice
bound2(); //Alice

 

API Application Programming Interface 응용프로그램 간의 요청과 응답을 주고받기 위한 약속 (= 인터페이스)

- 함수 / 메서드 (브라우저 API, 라이브러리)
- HTTP URL 호출 (REST API, Web API)
- SDK (앱용 API 모음)

- Private API
- Public API 
동기/비동기 동기  기다리는것
blocking
단순하나 업무프로새스 단순   ~ blocking
비동기 기다리지않는것
Non- blocking
효율적이나 업무프로세스가 복잡해짐
프론트엔드/백엔드 프론트엔드 사용자 보이는영역
백엔드 사용자 보이지 않는 영역

 

 

이벤트 전파 브라우저 body > main > div > p > span  형태일때 
이벤트흐름은 최상위 -> 최하위 -> 최상위  로 전파 
캡쳐링  최상위 -> 타겟 body → main  →  div → p → span 

document.addEventListener('click', function(event) {
  console.log('* ' + event.eventPhase + ' - capturing span 단계');
}, true);   < 끝에 true 시 캡쳐링

  * event.eventPhase
         1: 
Capturing phase, 2: Target phase, 3: Bubbling phase
버블링  타겟 -> 최상위 span → p → div → main → body
event.stopPropagation() 이벤트 전파 중단
event.preventDefault(); 폼 제출 막음 ex) a 태그 이동 막기, form 제출막기

 

JS 함수 반복/변형 forEach() 각 요소에 대해 함수 실행 arr.forEach(x => console.log(x))
map() 배열 변형 → 새 배열 반환 arr.map(x => x * 2)
filter() 조건에 맞는 요소만 추출 arr.filter(x => x > 2)
reduce() 누적 계산 (합계 등) arr.reduce((a, b) => a + b, 0)
  정렬/변환 sort() 정렬 (문자 기준, 숫자는 주의) arr.sort((a, b) => a - b)
reverse() 배열 반전 arr.reverse()
join() 문자열로 변환 arr.join(", ")
toString() 문자열 변환 arr.toString()
  탐색 조회 관련 includes() 값이 있는지 확인 arr.includes(3)
indexOf() 처음 등장 위치 arr.indexOf(3)
lastIndexOf() 마지막 등장 위치 arr.lastIndexOf(3)
find() 조건에 맞는 첫 요소 arr.find(x => x > 5)
findIndex() 조건에 맞는 첫 인덱스 arr.findIndex(x => x > 5)
some() 조건 하나라도 만족 arr.some(x => x < 0)
every() 모든 요소가 조건 만족
  생성 /변형 push() 배열 끝에 추가 arr.push(4)
pop() 배열 끝 제거 arr.pop()
unshift() 배열 앞에 추가 arr.unshift(0)
shift() 배열 앞 제거 arr.shift()
concat() 배열 병합 arr1.concat(arr2)
slice() 배열 일부 복사 arr.slice(1, 3)
splice() 배열 추가/삭제/변경 arr.splice(1, 2, "x")
fill() 배열을 특정 값으로 채움 arr.fill(0)
flat() 중첩 배열을 평탄화 [1,[2,[3]]].flat(2)
  길이/구조 length 배열 길이 arr.length
Array.isArray() 배열인지 확인 Array.isArray(arr)
Array.from() 유사 배열 → 진짜 배열 Array.from("hello")
Array.of() 개별 값 → 배열 생성 Array.of(1, 2, 3)

 

모듈시스템 모듈 분리된 하나의 파일 = 독립된 기능을 갖는 코드 조각
정의 코드 조각을 정의하고 불러오는 규칙(시스템)
없을때 <script src="a.js"></script>
<script src="b.js"></script>
a.js   
     number = 10 
b.js     
      number = 20
출력시 늦게 정의된 number =20 이 출력됨
있을때 

ES6 (ECMAScript 2015)
<script type="module" src="a.js"></script>
<script type="module" src="b.js"></script>
a.js 
     var number = 10;
     export default  number;
b.js 
     var number = 20;
     export default  number;
<script type="module">
import a_number from './a.js';
import b_number from './b.js';
console.log('a_number: ', a_number);
console.log('b_number: ', b_number);
</script>
종류 AMD Asynchronous Module Definition
설명: 비동기적으로 모듈을 로딩하는 방식. 주로 브라우저 환경에서 사용됨.
UMD Universal Module Definition
설명: AMD와 CommonJS를 모두 지원하는 범용 모듈 정의 방식.
ES Module
- ES6(ES2015) 에 도입된 js 방식
ECMAScript 6
설명: ES6(ECMAScript 2015)에서 도입된  JavaScript의 여섯 번째 버전. 모듈, 클래스, let/const 등 많은 기능이 도입됨.
math.js 
  const perfectScore = 100;
  export { perfectScore }; 
  export const sum = (num1, num2) => {
    return num1 + num2;
  };
  const avg = (num1, num2) => {
    return (num1 + num2) / 2;
  };
export default avg   // export default { 여러개 입력가능 }  

index.js 
  import { perfectScore, sum} from './math.js';
  import avg2 from './math.js';
  console.log('perfectScore: ', perfectScore);
  console.log('sum: ', sum(80, 10));
  console.log('avg: ', avg2(80, 90));

index.js 
  import * as math from './math.js';
  console.log('perfectScore: ', math.perfectScore);
  console.log('sum: ', math.sum(80, 10));
  console.log('avg: ', math.avg(80, 90));
CommonJS Node.js에서 사용되는 동기 방식 모듈 시스템.
math.js 
  exports.perfectScore = 100;
  exports. sum = (num1, num2) => {
    return num1 + num2;
  };
  const avg = (num1, num2) => {
    return (num1 + num2) / 2;
  };
module.export = { avg  };


index.js - 전개구문
  const { perfectScore, sum, avg } = require( './math.js' );
  console.log('perfectScore: ', perfectScore);
  console.log('sum: ', sum(80, 10));
  console.log('avg: ', avg2(80, 90));

index.js 
  const math = require( './math.js' );
  console.log('perfectScore: ', math.perfectScore);
  console.log('sum: ', math. sum(80, 10));
  console.log('avg: ', math. avg2(80, 90));
ES Module for NodeJS NodeJS 버전 13.2부터 ES모듈 시스템에 대한 정식 지원
package.json → "type": "module" 선언시 동일하게 사용가능

 

NPM Node Package Manager 패키지 관리자
모듈을 을 저장해두었다 사용 ex) npm install 모듈명
node.js 설치사용
라이브러리 조회  : npmjs.com    https://www.npmjs.com/package/dayjs
node.js  javascript 런타임 환경 - 백엔드 어플리케이션
NVM Node Version Manager
https://github.com/coreybutler/nvm-windows/releases 설치 
nvm version

nvm install 18.17.1     # 원하는 버전 설치
nvm use 18.17.1         # 해당 버전 사용 설정
nvm list available  설치가능 목록
nvm list                # 설치된 버전 목록 보기
nvm ls 
nvm uninstall  버전 
nvm current          현재버전
nvm use 버전         사용버전 이동
사용 package.json 프로젝트 정보 갖고 있는파일, 의존된 라이브러리 관리( dependencies )
cf)
하기 nodejs cmd 입력으로도 자동으로 만들어줌
npm init 
npm install dayjs 
{
  "name": "learn_npm",   // 프로젝트 이름
  "version": "1.0.0",   // 주로 3단계버전 많이사용
  "description" : "프로젝트 설명",
  "keywords" : "검색시 참조",
  "private": true ,//  npm 검색 거부 
  "author": "작성자",
  "main": " index.js ",
  "scripts": {
    "start": "hello worldhello worldhello world",   // 명령어 미리작성사용
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "license": "ISC",
  "dependencies": {   // 프로젝트 사용모듈 기술
    "dayjs": "^1.10.8"
  },
  "devDependencies": {   // 개발할때만 사용
    "moment": "^2.29.1"
  }
}
index.js const dayjs = require('dayjs');

console.log(dayjs('2019-01-25').format('[YYYYescape] YYYY-MM-DDTHH:mm:ssZ[Z]'));
package-lock.json 프로젝트에 설치된 모듈들의 의존성 트리기록
node_modules npm 으로 받은 것이 들어감 
명령어 패키지 설치 관련 npm init package.json 생성 (질문에 따라)
npm init -y package.json 기본값으로 자동 생성
npm install 또는 npm i package.json에 명시된 의존성 설치
npm install <패키지명> 패키지 설치 후 dependencies에 등록
npm install <패키지명> --save-dev 개발용 의존성으로 설치 (devDependencies)
npm install <패키지명>@버전 특정 버전 설치 예: npm install dayjs@1.10.8
npm install -g <패키지명> 전역(global)으로 패키지 설치
패키지 제거 및 업데이트 npm uninstall <패키지명> 패키지 제거
npm update 모든 의존성 업데이트
npm outdated 오래된 패키지 확인
스크립트 실행 npm run <스크립트명> package.json의 scripts 항목 실행
npm start scripts.start 실행 (기본 스크립트)
npm test scripts.test 실행
기타 유용한 명령어 npm list 현재 설치된 패키지 목록
npm list -g --depth=0 전역 설치 패키지 (1단계 깊이만)
npm config list npm 설정 보기
npm cache clean --force npm 캐시 정리
npx <명령어> 설치하지 않고 1회 실행 (예: npx create-react-app)
설치 전역설치 npm install -g 패키지명
커맨드라인 도구 
지역설치 npm install 패키지명
특정프로젝트에만 필요, 배포할 앱의 종속성
버전 시멘틱 버저닝
(Semantic Versioning)
MAJOR: 기존 사용자 코드를 깨뜨릴 수 있음
MINOR: 새로운 기능이지만 기존 코드는 잘 돌아감
PATCH: 작고 안정적인 버그 수정

1.2.3 정확히 1.2.3만 설치됨 고정 버전
~1.2.3 >=1.2.3 <1.3.0 PATCH만 허용 (버그 수정만)
^1.2.3 >=1.2.3 <2.0.0 MINOR + PATCH 허용 (기능 추가까지)

참고 ~(틸드) ^(캐럿)

 

 

Webpack 여러 개의 자바스크립트/리소스 파일들을 하나의 번들 파일로 묶어주는 도구
운영 배포시 웹팩에 지정한이름으로 생성되는 파일 ex) bundle.js 만 배포하여 사용

npm install --save-dev webpack webpack-cli
  "devDependencies": {
    "webpack": "^5.92.1",
    "webpack-cli": "^5.1.4"
  }
코드 작성후 
npx webpack 실행
사용이유 모듈이 여러개면 속도가 늦어짐
브라우저에서 모듈번들러로 하나의 모듈로 묶어(번들링) 배포
사용 my-webpack-app/
├── src/
│   ├── a.js
│   ├── b.js
│   └── index.js
├── dist/
│   └── index.html
├── webpack.config.js
└── package.json

src/a.js
  export const a = '🍎 Apple';
src/b.js
  export const b = '🍌 Banana';
webpack.config.js const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  mode: 'development'
};

src/index.js import { a } from './a.js';
import { b } from './b.js';

console.log('Module A:', a);
console.log('Module B:', b);
index.html   <body>
    <h1>Open Console</h1>
    <script src="main.js"></script>
  </body>

 

  원본 const original = {
  name: '홍길동',
  info: {
    age: 30
  }
};
js 복사 얕은 복사 Shallow Copy
쉘로우 카피
객체 최상위 속성만 복사 
중첩된 객체는 참조만 복사
하위는 값 변경시 원본영향 있음
- const copy = Object.assign({}, original);
- const copy = { ...original };
- 배열 : const copy = arr.slice(); const copy = [...arr];



const shallowCopy = { ...original };  //전개연산자

shallowCopy.name = '이몽룡';           // ✅ name은 독립적으로 바뀜
shallowCopy.info.age = 40;            // ⚠️ 내부 객체(info)는 공유됨

console.log('shallowCopy:', shallowCopy);

original:     { name: '홍길동', info: { age: 40 } }
shallowCopy:  { name: '이몽룡', info: { age: 40 } }
  깊은 복사 Deep Copy 하위는 값 변경시 원본영향 없음
- const deepCopy = JSON.parse(JSON.stringify(original));
- cloneDeep  라이브러리
     import cloneDeep from 'lodash/cloneDeep';
     const deepCopy = cloneDeep(original);

const deepCopy = JSON.parse(JSON.stringify(original));

deepCopy.name = ' 이몽룡 ';             // ✅ 독립적
deepCopy.info.age = 40 ;              // ✅ 내부 객체도 독립적

console.log('original:', original);
console.log('deepCopy:', deepCopy);

original:  { name: '홍길동', info: { age: 30 } }
deepCopy:  { name: ' 이몽룡 ', info: { age: 40 } }