구현하게 된 배경

회사에서 웹뷰이지만 모바일에서 PDF가 이미지로 보여야 한다는 요구사항을 받았습니다.

여기서 제약사항은 HTML, CSS, JavaScript만 사용해야 한다는 것입니다.

결과물은 페이지가 한 개만 있는 pdf 파일을 웹뷰로 보여주는 게 끝이었습니다(정적인 페이지).

 

모바일에서 웹뷰를 띄우고 거기다가 PDF를 이미지로 변환하는 것이기 때문에 너무 무거우면 안 된다고 생각했습니다.

그래서 바닐라 자바스크립트를 사용해서만 구현하게 되었습니다.

 

 

PDF.js란?

웹 표준 호환 HTML5 Canvas를 사용해 PDF 파일은 렌더링 하는 자바스크립트의 라이브러리입니다.

모질라 제단의 Andreas Gal가 2011년에 런칭 했습니다.

웹 브라우저에서 기본적으로 PDF 문서를 볼 수 있는 방법을 제공하기 위해 만들어졌으며 문서를 표시하기 위한 코드가

브라우저에서 샌드박스 처리되기 때문에 브라우저 외부에서 PDF 문서를 열 때 보안 위험을 방지합니다.

HTML5의 Canvas를 사용하기 때문에 빠른 렌더링 속도를 보여줍니다.

* 문서를 이미지화하기 때문에 PDF 내 텍스트를 복사하는 것을 방지할 수 있습니다.

 

공식 사이트에 보면 promise 를 사용하는데 자바스크립트 promise에 대한 개념을 모른다면 해당 내용을 이해하고

라이브러리를 적용 해보는것을 권장하고 있습니다.

(하지만 해당 라이브러리를 활용해 방대한 프로젝트를 만들고 있는게 아니라 우선 사용해 봤습니다.)

 

 

개발에 참고한 링크들

1. PDF.JS 공식 사이트

https://mozilla.github.io/pdf.js/

 

 

2. PDF.JS 공식 예제 코드

https://mozilla.github.io/pdf.js/examples/

 

 

3. PDF.JS 라이브러리 docs

https://mozilla.github.io/pdf.js/api/draft/module-pdfjsLib.html

 

 

구현한 코드

 

더보기
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="style.css">
    <link rel="stylesheet" href="https://fonts.sandbox.google.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
    <script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>
    <script defer src="main.js"></script>
    <title>Title</title>
</head>
<body>
    <main class="main-notice">
        <div class="notice">
            <div class="notice__title">
                <h3>sample 1-1</h3>
            </div>
            <canvas id="jsSampleOneCanvas" class="notice__canvas"></canvas>
            <div class="notice__btn" >
                <span class="material-symbols-outlined">
                    expand_more
                </span>
            </div>
        </div>
        <div class="notice">
            <div class="notice__title">
                <h3>sample 1-2</h3>
            </div>
            <canvas id="jsSampleTwoCanvas" class="notice__canvas"></canvas>
            <div class="notice__btn">
                <span class="material-symbols-outlined">
                    expand_more
                </span>
            </div>
        </div>
        <div class="notice">
            <div class="notice__title">
                <h3>sample 1-3</h3>
            </div>
            <canvas id="jsSampleThreeCanvas" class="notice__canvas"></canvas>
            <div class="notice__btn">
                <span class="material-symbols-outlined">
                    expand_more
                </span>
            </div>
        </div>
        <div class="notice">
            <div class="notice__title">
                <h3>sample 1-4</h3>
            </div>
            <canvas id="jsSampleFourCanvas" class="notice__canvas"></canvas>
            <div class="notice__btn">
                <span class="material-symbols-outlined">
                    expand_more
                </span>
            </div>
        </div>
    </main>
</body>
</html>

 

더보기
let noticeBtnAll = document.querySelectorAll(".notice__btn");

const SAMPLE_ONE_CANVAS = document.getElementById("jsSampleOneCanvas");
const SAMPLE_TWO_CANVAS = document.getElementById("jsSampleTwoCanvas");
const SAMPLE_THREE_CANVAS = document.getElementById("jsSampleThreeCanvas")
const SAMPLE_FOUR_CANVAS = document.getElementById("jsSampleFourCanvas")

const CMAP_URL = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/';

const CANVAS_ARRAY = [SAMPLE_ONE_CANVAS,
                      SAMPLE_TWO_CANVAS,
                      SAMPLE_THREE_CANVAS,
                      SAMPLE_FOUR_CANVAS];

// PDF.JS (pdf to image convertor)
let pdfJsLib = window['pdfjs-dist/build/pdf'];

pdfJsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';

function imgOpenClose(event) {
    let btn = event.target;
    let btnDiv = btn.parentNode;
    let canvas = btnDiv.parentNode.querySelector(".notice__canvas");

    if(!canvas.style.display || canvas.style.display === "none") {
        canvas.style.display = "block";
        btn.innerHTML = "expand_less";
        btnDiv.style.borderBottom = "1px solid rgba(128, 128, 128, 0.3)";
    } else {
        canvas.style.display = "none";
        btn.innerHTML = "expand_more";
        btnDiv.style.borderBottom = "none";
    }
}

function pdfToImg(urlArr) {

    let pdfUrl = ["/static/pdf/1-1.pdf",
                  "/static/pdf/1-2.pdf",
                  "/static/pdf/1-3.pdf",
                  "/static/pdf/1-4.pdf"];

    for (let i = 0; i < pdfUrl.length; i++) {
        pdfRender(pdfUrl[i], CANVAS_ARRAY[i]);
    }
}

function pdfRender(url, canvas) {
    let loadingTask = pdfJsLib.getDocument({
        cMapPacked: true,
        disableFontFace: true,
        cMapUrl: CMAP_URL,
        url: url
    });

    loadingTask.promise.then(function (pdf) {
        // Fetch the first page
        let pageNumber = 1;
        pdf.getPage(pageNumber).then(function (page) {

            let scale = 1.5;
            let viewport = page.getViewport({scale: scale});

            // Prepare canvas using PDF page dimensions
            let context = canvas.getContext('2d');
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            // Render PDF page into canvas context
            let renderContext = {
                canvasContext: context,
                viewport: viewport
            };
            let renderTask = page.render(renderContext);
            renderTask.promise.then(function () {
            });
        });
    }, function (reason) {
        console.error(reason);
    });
}

function init() {
    for(const btn of noticeBtnAll) {
        btn.childNodes[1].addEventListener("click", imgOpenClose);
    }
    pdfToImg();
}

init();

 

더보기
body {
    display: flex;
    align-items: center;
    flex-direction: column;
    margin: 0;
}

.notice {
    width: 100vw;
    margin-bottom: 10px;
}

.notice__title {
    display: flex;
    align-items: center;
    background-color: rgba(128, 128, 128, 0.1);
    border-bottom: 1px solid rgba(0, 0, 0, 0.3);
    border-top: 1px solid rgba(0, 0, 0, 0.3);
    border-top-left-radius: 15px;
    border-top-right-radius: 15px;
}

.notice__title h3 {
    margin-left: 13px;
}

.notice__btn {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
}


.material-symbols-outlined {
    font-variation-settings:
            'FILL' 0,
            'wght' 800,
            'GRAD' 0,
            'opsz' 48;
    opacity: 0.5;
}

.notice-question {
    margin-top: 9vh;
    background-color: rgba(128, 128, 128, 0.05);
    border: 2px solid rgba(0, 0, 0, 0.2);
    border-radius: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.notice-question__btn {
    border: none;
    background-color: rgba(128, 128, 128, 0.01);
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 5px;
}

.notice-question__arrow span {
    background-color: rgba(128, 128, 128, 0.05);
}

.notice-question__title {
    display: flex;
    align-items: center;
    margin-left: 15px;
}

.notice-question__title h3 {
    display: flex;
    align-items: center;
    margin-left: 7px;
}

.notice-question__title img {
    width: 25px;
}

.notice__canvas {
    display: none;
    width: 100vw;
}

.modal-wrap {
    position:fixed;
    top:0;
    left:0;
    right:0;
    bottom:0;
    background:rgba(0,0,0,.5);
    font-size:0;
    text-align:center;
}

.modal-wrap:after {
    display:inline-block;
    height:100%;
    vertical-align:middle;
    content:'';
}

.modal-wrap .modal-inner  {
    display:inline-block;
    padding: 8px 8px;
    background:#fff;
    width:95vw;
    vertical-align:middle;
    font-size:15px;
}

.modal-inner img {
    width: 90vw;
}
  • HTML, CSS는 제외하고 자바스크립트 소스만 보셔도 됩니다.
  • 예제코드와 거의 똑같아서 주석이나 설명은 달아놓지 않았습니다.

 

트러블 슈팅) 한국어가 글자가 렌더링 되지 않는 문제

 

구현을 하면서 한국어를 입력한 부분의 글자가 깨지는 문제가 발생했습니다.

해당 내용을 해결하기 위해 찾아보다가 중국 개발자들이 해당 문제를 해결한 것을 봤습니다.

 

 

문제를 해결하는데 큰 도움이 된 링크 => https://github.com/mozilla/pdf.js/issues/12629

 

Part of the Chinese character cannot be rendered · Issue #12629 · mozilla/pdf.js

Attach (recommended) or Link to PDF file here: pdf link Configuration: Web browser and its version: chrome 86.0.4240.193 Operating system and its version: macOS 10.13.6 PDF.js version: 2.5.207 Is a...

github.com

 

확인해보니 CDN이 형식이 잘못된 데이터를 반환하는 것이라고 합니다.

bCmap 형식을 리턴해야 하는데 잘못된 형식이 반환되는 것입니다.

그래서 cMapUrl을 변경하니까 문제가 바로 해결되었습니다.

 

 

bCmap == binary cmap

* bCmap이란? => 링크

 

cMap(Character Maps)는 PostScript 나 기타 Adobe 제품에서 문자 코드를 CID 글꼴의 문자를 매핑하는데 사용되는 텍스트 파일

(CID 폰트에 대한 설명은 오른쪽 링크 참조(영문 사이트) => 링크)

주로 동아이사 문자 체계를 다룰 때 사용되고 이 기술은 레거시 기술이므로 최신 도구로 만든 pdf에서는 사용이 안된다고 합니다.

 

pdf.js는 이런 CID 폰트를 화면상에 나타내기 위해서는 CMap 파일이 필요하다고 합니다.

그래서 같은 아시아권인 중국 개발자가 해결한 방법으로 해결이 가능했던 것 같습니다.

 

 

구현하면서 의문점

  • pdf가 이미지로 변환된 파일을 다운로드 못하게 해야 하지 않는지?
    • 이 부분은 해당 PDF 파일을 따로 암호화를 진행 해야 한다는 것을 알게 되었습니다.
      그래서 민감한 정보가 들어있는 PDF파일은 암호화 토큰 값을 주입해서 위조 및 변형이 힘들도록 하는 방식을 적용합니다.
      * 제가 구현한 방식은 단순히 텍스트를 복사 붙여넣기만 못하도록 막는 방식입니다.
  • html <head> 태그 안에 PDF.js 에 필요한 스크립트 태그 하나 추가했는데 라이브러리가 쉽게 적용되는 이유는 무엇인지?
    • CDN에 대한 개념 이해 필요

 

 

반응형

모바일 기준으로 이미지 터치 슬라이더를 구현해봤습니다.

터치 슬라이더는 이미 다양한 블로그에서 정리를 해놔서 구현하기 쉬었습니다.

 

그런데 여기서 사람이 직접 슬라이드를 넘기는 것이 아닌 자동으로 시간이 지나면 슬라이드 되는 기능을 추가해봤습니다.

 

자동으로 슬라이드가 되는 기능은 setInterval을 사용하면 쉽게 구현 할 수 있지만,

터치를 한 순간에는 setInterval이 멈춰야 하기 때문에 그 부분에서 고민을 많이 했습니다.

 

 

오토 슬라이드 시연 gif

 

터치 슬라이드 시연 gif

 

 

HTML 구현 코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="style.css">
    <title>slider</title>
</head>
<body>
    <div class="slideshow-container">
        <div class="images">
            <img src="image/1.jpg">
            <img src="image/2.jpg">
            <img src="image/3.jpg">
            <img src="image/4.jpg">
        </div>
    </div>
<script src="slide.js"></script>
</body>
</html>

HTML은 위의 코드를 참고하셔도 괜찮고 직접 작성하셔도 됩니다.

여기서 class 값으로 JS에서 querySelector를 사용하기 때문에 그 부분만 유의하시면 될 것 같습니다.

 

 

CSS 구현코드

body {
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.slideshow-container {
    overflow: hidden;
    width: 100vw;
    position: relative;
    overflow: hidden;
    display: flex;
}

.images {
    position: relative;
    display: flex;
    transition: transform 0.5s;
}

.images img {
    vertical-align: middle;
    width: 100vw;
}

CSS는 반응형으로 디자인 하기 위해서 flex 컨테이너를 사용했습니다.

이미지 혹은 div의 widh 값도 반응형으로 만들기 위해 'vw' 단위를 사용했습니다.

 

 

 

 

자바스크립트 구현코드

const IMAGE_VW = 100;
const IMAGES = document.querySelector(".images");
const INTERVAL_TIME = 5000;
const IMG_COUNT = IMAGES.childElementCount;
const LAST_INDEX = IMG_COUNT - 1;

let curIndex = 0;
let curImgVw = 0;
let startX, endX;
let interval;

function prevImg() {
    if(curIndex > 0) {
        curImgVw += IMAGE_VW;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex--;
    }
}

function nextImg() {
    if(curIndex < LAST_INDEX) {
        curImgVw -= IMAGE_VW;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex++;
    }
}

function touchStart(event) {
    stopInterval();

    startX = event.touches[0].pageX;
}

function touchEnd(event) {
    startInterval();

    endX = event.changedTouches[0].pageX;
    if(startX > endX) {
        nextImg();
    } else {
        prevImg();
    }
}

function autoSlide() {
    if(curIndex === LAST_INDEX) {
        stopInterval();
        curImgVw = 0;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex = 0;
        startInterval();
    } else if(curIndex < LAST_INDEX) {
        curImgVw -= IMAGE_VW;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex++;
    }
}

function startInterval() {
    if(interval === null) {
        interval = setInterval(autoSlide, INTERVAL_TIME);
    }
}

function stopInterval() {
    clearInterval(interval);
    interval = null;
}

function init() {
    IMAGES.addEventListener("touchstart", touchStart);
    IMAGES.addEventListener("touchend", touchEnd);
    startInterval();
}

init();
  • 고정적인 값을 나타내는 변수는 const(상수)와  전역변수로 선언 했습니다.
    ex) 인터벌 시간, 이미지의 가로 길이
  • 자동으로 슬라이드가 되는 함수(autoSlide)는 브라우저가 렌더링 되면 바로 실행이 되도록 init 함수에 넣어놨습니다.
  • 이미지를 클릭하면 touchstart 함수가 실행되고 autoSlide를 일정 간격으로 실행시키는 인터벌을 정지하도록 했습니다.
  • startInterval() 함수를 만들어서 하나의 인터벌만 실행되도록 코드를 작성했습니다.
    => 동일하게 stopInterval() 실행중인 하나의 인터벌을 clearInterval() 함수를 사용해서 종료하도록 했습니다.
    => 실행 할 하나의 interval은 미리 전역변수로 설정을 해놨습니다.
  • 터치 슬라이드에서 각 이미지에 인덱스 값이 있다는 가정하에 curIndex, LAST_INDEX 변수 선언
    => curIndex는 유저가 현재 보고있는 이미지의 인덱스입니다.
    => LAST_INDEX는 말그대로 마지막 이미지의 인덱스입니다.

 

 

 

 


참고자료

  • 블로그 [탐구소년] 자바스크립트 모바일 터치 슬라이더 구현하기 => 링크

 

 

 

 

반응형

 

참고자료

  • 유튜브 노마드코더 채널 [반드시 "함수형 프로그래밍"을 알아야 할까?] => 링크

 

 


 

 

 

😎 개발자는 반드시 함수형 프로그래밍을 배워야 한다!

  • '함수형 프로그래밍'은 코드 작성 '스타일'이라고 할 수 있다.
  • 함수형 프로그래밍을 배우고 컨셉과 아이디어를 좋아한다면, 해당 개념을 좋아하는 언어에 적용할 수 있다.
  • Clojure와 Scala는 함수형 프로그래밍으로 아예 설계된 언어이다.
  • 배워두면 무슨 언어로 코드를 작성하든 도움이 된다!
  • 이미 좋은 기술과 경력을 갖춘 시니어 개발자들은 점진적으로 함수형 언어를 사용하게 된다.
    => 점차 커리어가 발전함에 따라서 함수형 언어를 사용
  • 함수형 방식에서는 버그 자체가 발생하기 어렵다.
    => 함수형 코드에서는 버그가 쉽게 숨겨지지도 않는다.

 

 

 

😀 함수형 프로그래밍은 일종의 새로운 사고방식을 배우는 것이다.

  • 코드를 쓰고 설계하는 새로운 관점
  • 배워두면 더 나은 개발자가 될 것이다.
  • 니꼬쌤은 시작부터 함수형 프로그래밍에 따라 코딩을 쓰는 것이 더 깔끔하다고 생각

 

 

 

😶 명령형(imperative) 코드와 선언형(declarative) 코드의 차이

 

선언형 코드

Make em a sandwich 🥪

 

  • 원하는 결과를 표현하기 위해 코드가 작성된다.
  • 선언형 언어의 예시로 CSS가 있다.
  • 선언형 코드는 원하는 결괏값을 선언하는 것이다.
  • 필요한 것을 달성하는 과정을 하나하나 기술하는 것보다 필요한 것이 어떤 것인지 기술하는 데 방점을 두고
    애플리케이션의 구조를 세워 나가는 프로그래밍 구조입니다.

 

 

선언형 코드 예시(JS)

function spaceToHeart(text) {
	return text.replaceAll(" ", "💜");
}
  • 명령 함수와 동일한 결과를 갖지만, 읽기가 더 쉽다
  • 함수가 무슨 역할을 하는지 이해하기 편하다.

 

 

 

 

 

명령형 코드

1. 🍞 toast
2. 🧀  + 🍅 + 🥓 + 🥗
3. combine
4. done!!! 🥪
  • 원하는 결과를 얻기 위해 필요한 지침에 따라 코드가 작성된다.
  • 요구사항을 충족하는데 필요한 모든 단계를 하나씩 적어야 함.
  • 명령형 프로그래밍은 무엇을 어떻게 할 것인가에 가깝다.
  • 코드로 원하는 결과를 달성해 나가는 과정에만 관심을 두는 프로그래밍 스타일

 

 

명령형 코드 예시(JS)

function spaceToHeart(text) {
	let result = "";			 // 1. 최종 결과를 보유할 변수 선언 및 초기화
    for (let i = 0; i < text.length; I++) {	 // 2. 지우려는 텍스트의 각 문자 내부의 살펴보기
    	if (text[i] === " ") {			 // 3. 문자가 공백인지 여부 체크
        	result += "💜";                 // 4. 문자에 공백이 있다면 하트를 추가
        } else {
        	result += text[i];		// 4. 문자에 공백이 없다면 text의 i번째 문자 추가
        }
    }
    return result;				// 5. 완료 후 결과 리턴
}

 

명령형 코드의 단점

  • 코드가 길어진다.
  • 요구사항의 구현이 개발자인 우리에게 달려있기 때문에 버그나 실수가 더 생길 수 있다.
  • 팀 동료들이 이해하기 어려울 수 있다.
  • 함수가 정확히 무엇을 하려고 하는지 한 줄 한줄 자세히 읽어야 한다.

 

 

 

🤔 느낀 점 혹은 생각

  • 선언적 접근 방식이 읽기 쉽고 더 직관적이라고 느꼈습니다.
  • 함수형 프로그래밍에 대해 1도 모르고 있었다는 것을 알게 되었습니다.
  • 둘 다 공부를 하면서 작성했던 코드들이라는 것을 알게 되었습니다.

 

반응형

 

 

 

* Ajax란?

 

Ajax(Asynchronous JavaScript and XML, 에이잭스)는 비동기적인 웹 애플리케이션의 제작을 위해 아래와 같은 조합을 이용하는 웹 개발 기법이다.

 

  • 표현 정보를 위한 HTML (또는 XHTML) 과 CSS
  • 동적인 화면 출력 및 표시 정보와의 상호작용을 위한 DOM, 자바스크립트
  • 웹 서버와 비동기적으로 데이터를 교환하고 조작하기 위한 XML, XSLT, XMLHttpRequest (Ajax 애플리케이션은 XML/XSLT 대신 미리 정의된 HTML이나 일반 텍스트, JSON, JSON-RPC를 이용할 수 있다).

 

 

 

 

* AJAX란 무엇인가?

 

https://velog.io/@surim014/AJAX%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

 

AJAX란 무엇인가?

AJAX (Asynchronous Javascript And XML) AJAX란, JavaScript의 라이브러리중 하나이며 Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자이다. 브라우저가 가지고있는 XMLHttpRequest 객체를 이용해서 전

velog.io

 

블로그에 내용 및 목차

  • AJAX (Asynchronous Javascript And XML)
  • 비동기 방식의 개념과 장점
  • AJAX로 할 수 있는 것
  • 클라이언트와 서버란?
  • AJAX를 사용하는 이유와 장단점

 

 

 

* Ajax의 개념과 Jquery를 이용한 사용법

 

 

https://devyj.tistory.com/1

 

Ajax 란?

Ajax (Asynchronous JavaScript and XML) 자바스크립트를 이용해서 비동기식으로 XML을 이용하여 서버와 통신하는 방식 최근에는 XML 보다  JSON을 더 많이 사용한다. 비동기식이란 여러가지 일이 동시적으

devyj.tistory.com

 

 

  • Ajax에 대한 개념
  • Ajax의 동작방식
  • jQuery를 이용한 Ajax
  • Get과 Post의 차이점

 

 

 

반응형

 

변수는 유효범위에 따라 전역변수(Global Variable)와 지역변수(Local Variable)로 구분할 수 있습니다.

 

지역변수

 

지역변수는 함수 내부에서 선언된 변수로, 함수가 실행되면 만들어지고 함수가 종료되면 소멸하는 변수입니다.

지역 변수(local variable)는 함수 안에서만 접근할 수 있습니다.

 

<!DOCTYPE html>
<script>
"use strict";globalThis.__codeBoxId = "lpd4va32eg";

function showMessage() {
  let message = "안녕하세요!"; // 지역 변수

  alert( message );
}

showMessage(); // 안녕하세요!

alert( message ); // ReferenceError: message is not defined (message는 함수 내 지역 변수이기 때문에 에러가 발생합니다.)
</script>

 

 

 

 

전역변수

 

전역변수는 함수 외부에서 선언된 변수로, 프로그램 전체에서 접근할 수 있는 변수입니다.

 

전역 변수는 같은 이름을 가진 지역 변수에 의해 가려지지만 않는다면 모든 함수에서 접근할 수 있습니다.

 

let x = 3; // 글로벌 변수, 전역 변수(Global Variable)

function myFunction(){  
	console.log(x);
} 

myFunction(); // 3 

console.log(x); // 3 

 

변수는 연관되는 함수 내에 선언하고, 전역 변수는 되도록 사용하지 않는 것이 좋습니다.

비교적 근래에 작성된 코드들은 대부분 전역변수를 사용하지 않거나 최소한으로만 사용합니다.

 

* 다만 프로젝트 전반에서 사용되는 데이터는 전역 변수에 저장하는 것이 유용한 경우도 있습니다.

 


참고 자료

 

모던 JavaScript 튜토리얼

 

CODING FACTORY(티스토리 블로그)

반응형

* HTML에 대한 사전지식을 가지고 DOM을 공부 하시는걸 권장드립니다.

HTML을 무료로 배울 수 있는 사이트들

 

 


 

 

DOM이란?

 

Document Object Model의 약자로 문서(Document)를 객체 모델(Object Model)로 구현한 것입니다.

* 문서 객체 모델(DOM 위키백과 링크)

 

DOM은 HTML문서의 요소를 제어하기 위해 웹 브라우저에서 처음 지원되었습니다.

 

 

 브라우저의 동작 과정

 

  • 이런 모든 객체는 자바스크립트를 통해 접근할 수 있고, 페이지를 조작할 때 사용합니다.
  • 위 사진을 보면 DOM과 HTML이 엄연히 다른 것임을 알 수 있습니다.

 

 

DOM에 대해 잘 정리되어 있는 사이트들

 

 

ddinggu velog(간단하지만 포인트를 정리한 블로그)

 

  • 브라우저, HTML, DOM의 정의와 서로의 상관관계
  • DOM과 HTML의 차이점

 

 

surim014 velog(자세하게 정리되어 있는 블로그)

 

  • 웹페이지가 만들어지는 과정
  • DOM에 대한 정의와 생성방법
  • DOM과 HTML의 차이점
  • DOM Elements 제어방법 (DOM의 생성, 제거 등)
  • DOM Events

 

 

모던 자바스크립트(JavaScript) 듀토리얼

 

  • DOM 트리에대한 정의와 예제
  • DOM의 구조
  • 위의 두 블로그를 보고 이 사이트를 보면 크게 도움이 됩니다.
반응형

 

객체란?

  • 현실의 사물을 프로그래밍에 반영한 것 입니다.
  • 키로 구분된 데이터 집합이나 복잡한 개체(entity)를 저장할 수 있습니다.
  • 원시형과 다르게 다양한 데이터를 담을 수 있습니다.

* 여덞가지 자료형 중 7개는 오직 하나의 데이터(문자열, 숫자 등)만 담을 수 있어'원시형(primitive type)'이라 부릅니다.

 

 

객체는 자바스크립트 거의 모든 면에 녹아있는 개념입니다.

자바스크립트를 잘 다루려면 객체를 잘 이해하고 있어야 합니다.

 

 

 

객체 만드는 법

 

중괄호 {...} 를 이용해서 만듭니다.

중괄호 안에는  키(key): 값(value)’ 쌍으로 구성된 프로퍼티(property) 를 여러 개 넣을 수 있습니다.

* 키엔 문자형, 엔 모든 자료형이 허용합니다.

 

 

 

빈 객체를 만드는 2가지 예시

let user = new Object(); // '객체 생성자' 문법
let user = {};  // '객체 리터럴' 문법

* 객체 리터럴이란? (링크 참조)

 

 

 

리터럴과 프로퍼티

let user = {     // 객체
  name: "John",  // 키: "name",  값: "John"
  age: 30        // 키: "age", 값: 30
};

'콜론(:)'을 기준으로 왼쪽엔 키(key)가, 오른쪽엔 값(value)이 위치합니다.

* 프로퍼티 키는 프로퍼티 ‘이름’ 혹은 '식별자’라고도 부릅니다.

 

프로퍼티 값엔 모든 자료형이 올 수 있습니다.

 

 

 

프로퍼티 읽기

점 표기법(dot notation)을 이용하면 프로퍼티 값을 읽는 것도 가능합니다.

// 프로퍼티 값 얻기
alert( user.name ); // John
alert( user.age ); // 30

 

 

프로퍼티 삭제

delete 연산자를 사용하면 프로퍼티를 삭제할 수 있습니다.

delete user.age;

 

 

단어 조합해 만든 프로퍼티 이름

let user = {
  name: "John",
  age: 30,
  "likes birds": true  // 복수의 단어는 따옴표로 묶어야 합니다.
};

여러 단어를 조합해 프로퍼티 이름을 만든 경우엔 프로퍼티 이름을 따옴표로 묶어줘야 합니다.

 

여러 단어를 조합해 프로퍼티 키를 만든 경우엔, 점 표기법을 사용해 프로퍼티 값을 읽을 수 없습니다.

 

 

 

 

상수(const)로 선언된 객체는 수정이 가능

const user = {
  name: "John"
};

user.name = "Pete"; // (*)

alert(user.name); // Pete

(*)로 표시한 줄에서 오류를 일으키는 것처럼 보일 수 있지만 그렇지 않습니다. 

const user의 값을 고정하지만, 그 내용은 고정하지 않습니다.

 

 

 

대괄호 표기법

let user = {};

// set
user["likes birds"] = true;

// get
alert(user["likes birds"]); // true

// delete
delete user["likes birds"];

 

대괄호 표기법은 키에 어떤 문자열이 있던지 상관없이 동작합니다.

 

 

 

* 위 글은 모던 자바스크립트 튜토리얼 사이트의 내용을 요약한 글입니다.

자세한 정보는 모던 자바스크립트 튜토리얼 채널을 참고하시기 바랍니다.


참고자료

 

제로초(객체와 배열)

 

모던 자바스크립트(JavaScript) 튜토리얼

 

반응형

 

MVC 패턴이란?(링크로 이동)

 

 

에플리케이션을 세가지의 역할로 구분한 개발 방법론이다

소프트웨어 디자인 패턴 중 하나이다.

 

 

M = [Model]  애플리케이션의 정보(데이터)

V = [View]  텍스트, 체크박스 항목 등과 같은 사용자 인터페이스 요소

C = [Controller]  데이터와 비즈니스 로직 사이의 상호동작을 관리

 

 

 

 

 

  1. 사용자가 웹사이트에 접속한다. (Uses)
  2. Controller는 사용자가 요청한 웹페이지를 서비스 하기 위해서 모델을 호출한다. (Manipulates)
  3. 모델은 데이터베이스나 파일과 같은 데이터 소스를 제어한 후에 그 결과를 리턴한다.
  4. Controller는 Model이 리턴한 결과를 View에 반영한다. (Updates)
  5. 데이터가 반영된 VIew는 사용자에게 보여진다. (Sees)

 

 

 

 

디자인 패턴을 사용하는 이유

 

 소수의 뛰어난 엔지니어가 해결한 문제를 다수의 엔지니어들이 처리 할 수 있도록 한 규칙이다.

구현자들 간의 커뮤니케이션의 효율성을 높이는 기법이다.

 

 

 

 

MVC 패턴을 사용하는 이유

 

서로 분리되어 각자의 역할에 집중할 수 있게끔하여 개발을 하고 그렇게 애플리케이션을 만든다면,

 

  • 유지보수성
  • 애플리케이션의 확장성
  • 유연성 증가(클라이언트의 새로운 요구사항에 대해 최소한의 비용으로 보다 유연하게 대처)
  • 중복코딩의 문제점 감소

클라이언트의 새로운 요구사항에 대해 최소한의 비용으로 보다 유연하게 대처

 

 

 

 

 

Model View Controller 각자의 역할

 

Model

처음에 정의하는 상수, 초기화값, 변수 등을 뜻합니다.
또한 DATA 정보들의 가공을 책임지는 컴포넌트를 말합니다.
(데이터베이스)

View

클라이언트 측 기술인 html/css/javascript들을 모아둔 컨테이너. 

Controller

사용자가 접근 한 URL에 따라 요청사항을 파악한 후,
그 요청에 맞는 데이터를 Model에 의뢰 및 View에 반영해서 사용자에게 알려준다. 

 

 

 

 


참고자료

 

 

생활코딩 MVC 디자인 패턴

 

m.blog.naver.com/jhc9639/220967034588

반응형

 

 null 값

 

 

자바스크립트에서 null 값이란

 

자바스크립트의 null은 자바스크립트 이외 언어의 null과 성격이 다릅니다.

다른 언어에선 null을 '존재하지 않는 객체에 대한 참조’나 '널 포인터(null pointer)'를 나타낼 때 사용합니다.

 

 

null 값은 지금까지 자료형(문자열, 숫자열 등) 중 어느 자료형에도 속하지 않는 값입니다.

 

null값은 오로지null값만 포함하는 별도의 자료형을 만듭니다.

 

  1. 존재하지 않는(nothing) 값
  2. 비어 있는(empty) 값
  3. 알 수 없는(unknown) 값

 

let age = null;

 

let age = null;은 나이(age)를 알 수 없거나 그 값이 비어있음을 보여줍니다.

 

 

 

 

 

 undefined 값

 

undefined 값도 null 값처럼 자신만의 자료형을 형성합니다.

undefined는 '값이 할당되지 않은 상태’를 나타낼 때 사용합니다.

변수는 선언했지만, 값을 할당하지 않았다면 해당 변수에 undefined가 자동으로 할당됩니다.

 

let age;

alert(age); // 'undefined'가 출력됩니다.

 

개발자가 변수에 undefined를 명시적으로 할당하는 것도 가능하긴 합니다.

 

let age = 100;

// 값을 undefined로 바꿉니다.
age = undefined;

alert(age); // "undefined"

 

 

하지만 이렇게 undefined를 직접 할당하는 걸 권장하진 않습니다.

변수가 ‘비어있거나’ ‘알 수 없는’ 상태라는 걸 나타내려면 null을 사용하세요. 

undefined는 값이 할당되지 않은 변수의 초기값을 위해 예약어로 남겨둡시다.

 

 

 

 

 


참고자료

 

모던 JavaScript 튜토리얼

 

webclub.tistory.com/1

 

MDN 웹 문서 - 모질라

 

반응형

변수 명명 시 두 가지 제약 사항

 

  1. 변수명에는 오직 문자와 숫자, 그리고 기호 $와 _만 들어갈 수 있습니다.

  2. 첫 글자는 숫자가 될 수 없습니다.

 

 

 

 

변수, 함수명은 카멜 케이스를 사용한다.

 

 

여러 단어를 조합하여 변수명을 만들 땐 카멜 표기법(camelCase)가 흔히 사용됩니다.

카멜 표기법은 변수 첫 단어를 제외한 각 단어의 첫 글자를 대문자로 작성합니다.

 

예시)

let myName = "smith";
let myAge = 40;

 

* 프로그래밍 변수명 표기법(링크로 이동)

 

 

 

 

 

 

 

특수 기호는 일반 글자처럼 특별한 의미를 지니진 않음

 

let $ = 1; // '$'라는 이름의 변수를 선언합니다.
let _ = 2; // '_'라는 이름의 변수를 선언합니다.

alert($ + _); // 3

 

 

 

 

 

잘못된 변수명의 예시

 

let 1a; // 변수명은 숫자로 시작해선 안 됩니다.

let my-name; // 하이픈 '-'은 변수명에 올 수 없습니다

 

# 대·소문자 구별

 

apple AppLE은 서로 다른 변수입니다.

 

 

 

 

변수명은 영어로 표기하는 것을 권장함

let имя = '...';
let 我 = '...';
let 나이 = 40;

위 코드에는 기술적인 에러가 없습니다. 변수명도 유효합니다.

하지만 영어를 변수명에 사용하는 것이 국제적인 관습이므로, 변수명은 영어를 사용해서 만들길 권유 드립니다.

다른 나라 사람이 스크립트를 볼 경우 등을 대비해 장기적인 안목을 가지고 코드를 작성합시다.

 

 

 

 

 

 

예약어(reserved name)는 변수명으로 사용할 수 없음

 

let let = 5; // 'let'을 변수명으로 사용할 수 없으므로 에러!
let return = 5; // 'return'을 변수명으로 사용할 수 없으므로 에러!

이 단어들은 자바스크립트 내부에서 이미 사용 중이기 때문입니다.

예약어 예시: let, class, return, function

아래 코드는 문법 에러를 발생시킵니다.

 

 

 


 

참고자료

 

변수와 상수(모던 JavaScript 튜토리얼)

 

자바스크립트 변수 명명 규칙

반응형

+ Recent posts