1. 구현한 기능

좌측 튜토리얼 화면의 텍스트 콘텐츠를 확대/축소할 수 있는 zoomController 기능.

[100% → 200%로 확대했을 때, 화면]

image-20220915153652420

[100% → 70%로 축소했을 때, 화면]

image-20220915153802382

2. 완성화면 바로가기

완성화면

소스코드

3. 코드 설명

타겟이 되는 DOM은 아래와 같다.

const zoomInBtn = document.querySelector('#zoomController .zoom_in');
const zoomOutBtn = document.querySelector('#zoomController .zoom_out');
const zoomText = document.querySelector('#zoomController .zoom_percentage');
const tutorialHeader = document.querySelector('.left__tutorial .title_2');
const tutorialContents = document.querySelector('.left__tutorial .contents');

zoom 클래스로 객체 생성 시 필요한 값은 (1) 확대/축소할 타겟의 배열, (2) 확대/축소할 타겟의 초기 폰트 크기(‘rem’단위) 이다.

위 params 를 모두 배열로 설정한 까닭은 zoom으로 제어할 타겟이 여럿일 수 있기 때문이다.

(원래는 변수로 작업했지만, 송차장님의 솔루션으로 초기 변수에서 배열로 params의 데이터 구조를 교체하였다 :) )

// zoom('DOM: Array', '초기폰트크기: Array')
// '초기폰트크기'의 단위는 'rem'
class zoom {
    constructor(target = [], initFontSize = []) {
        this.target = target;
        this.initFontSize = initFontSize;
    }
...

zoom 클래스의 필드는 3개이며, 설명은 아래와 같다.

  • zoomStep : 화면을 처음 로드했을 때, 타겟의 초기 폰트 크기에 곱할 값이며, 확대/축소 버튼을 클릭할 때마다 0.1 씩 증가/감소 한다.
  • currFontSize : 각 타겟에 적용할 현재의 폰트 크기를 계산하여 순서대로 저장할 배열이다.
  • currZoomPer : 표시할 확대/축소율이다.

in 함수는 크기가 400%에서 더 확대하지 않도록, out 함수는 70%에서 더 축소되지 않도록 조건을 추가하였다.

    zoomStep = 1;
    currFontSize = [];
    currZoomPer;
    
    in = () => {
        if (this.zoomStep > 4)   return;
        this.zoomStep += 0.1;
        this.show();
    }

    out = () => {
        if (this.zoomStep < 0.8)   return;
        this.zoomStep -= 0.1;
        this.show();
    }
...

show 함수는 생성자의 params로 전달받은 initFontSize 배열의 각 요소를 map으로 끄집어내어 현재의 폰트 크기를 계산, 반환하여 currFontSize에 순서대로 저장한다. (.toString 메서드에서 ()를 빠뜨려 함수가 정상적으로 돌아가지 않았었다. 주의 하도록 하자.)

다음으로 생성자의 params로 전달받은 target 배열의 각 요소를 forEach로 끄집어낸 후, 그 target에 currFontSize 배열의 요소를 폰트 크기로 순서대로 적용했다.

...
    show = () => {
        // fontSize => rem 단위로 변경
        this.currFontSize = this.initFontSize.map((el) => {
        	// 현재의 폰트 크기를 계산
            return (el * this.zoomStep).toFixed(2).toString() + 'rem';
        })

        let i = 0;
        this.target.forEach((el) => {
            el.style.fontSize = this.currFontSize[i];
            i++;
        })

        this.currZoomPer = Math.floor(this.zoomStep * 100).toString() + '%';
        zoomText.innerText = this.currZoomPer;        
    }
}

class로 객체를 생성할 때에는 반드시 class가 정의된 구역을 기준으로 그 아래에 작성하자.

(class가 정의된 구역 위에 해당 class로 객체를 생성하려고 하면, undfined 에러가 발생하니 반드시 아래에 위치하도록 하자.)

let zoomController = new zoom([tutorialHeader, tutorialContents], [1.5, 0.875]);

zoomInBtn.addEventListener('click', () => {
    zoomController.in();
})

zoomOutBtn.addEventListener('click', () => {
    zoomController.out();
})

댓글남기기