바탕화면

올리·2023년 10월 4일
0
post-thumbnail

개요

실행 가능한 모든 컴포넌트를 레이블 형태(아이콘)로 보여주고, 레이블을 클릭하면 그에 맞는 컴포넌트(=창)를 실행한다.


main.js 모듈화

모듈을 어떻게 나눌까 고민했는데, 역시 메인 컴포넌트들을 각자의 .js 파일로 구현하고 바탕화면 역할을 하는 main.js에서 불러와서 사용하는 게 제일 직관적이라고 생각했다.

main.js에서 다른 파일에서 작성한 것들을 불러오려고 하니까 Cannot use import statement outside a module 에러가 났다. import를 사용할 스크립트는 최상단 html 파일에서 불러올 때 type="module" 을 사용해 모듈임을 명시해줘야 한다고 해서 다음과 같이 수정했다.

  • index.html
<head>
    <meta charset="UTF-8"/>
    ...
    <script src="./scripts/main.js" type="module" defer></script>
</head>

이제 main.js에서 import 구문을 사용할 수 있고, export하는 파일들은 따로 설정해줄 필요가 없다.


바탕화면 html

바탕화면 구조는

https://codepen.io/Mohiaish/details/yLqXZOw

의 코드를 사용했다. 대강 아래와 같은 구조다.

  • index.html
<body>
        <div id="desktop">
            <label for="windows-document-input" class="desktop-item">
                <div class="icon">
                    <img
                    	src="생략"
                        alt=""
                    />
                </div>
                <div class="text">Documents</div>
            </label>
          
          	...
          
          <div id="start-bar">
            <div id="start-button-items">
                <label
                    id="start-button"
                    class="windows-box-shadow"
                    for="start-button-input"
                ></label>
                <div id="items"></div>
            </div>
            <div id="time-options"></div>
        </div>
        ...

<body>태그 안에 <label>들을 배치했고 마지막에는 startbar가 있다.
(img src 부분은 링크가 너무 길어져서 생략)


main.js

컴포넌트들의 생성과 삭제, 이동을 담당

컴포넌트들을 생성, 삭제하고 이동하는 데 필요한 파일들을 import해오고 각 컴포넌트들의 아이콘(레이블)과 엘리먼트를 전역에서 관리한다.

또한 OPEN_EL_LIST를 두어 현재 열려 있는 창들을 관리한다.
별도의 인덱스 처리 없이 개별 컴포넌트를 담고 꺼내오기 위해 Set을 사용했다.

import { createDraggable } from './utility/drag-event.js';
import { clickCloseBtn, clickWindowEl } from './utility/click-event.js';
import { createClockEl, TIMERID } from './component/clock.js';
...

// Desktop Element: to append a new tab
const desktop = document.querySelector('#desktop');

// Get Desktop Items
const lifequoteLabel = document.querySelector('#life-quote');
const clockLabel = document.querySelector('#clock');
const timetableLabel = document.querySelector('#timetable');

const OPEN_EL_LIST = new Set();

// Elements will be created by click label
let clockEl = null;
let quoteEl = null;
let timetableEl = null;

컴포넌트 생성 과정

컴포넌트를 생성하고 삭제하는 과정은 모든 컴포넌트가 제일 비슷하므로 대표로 시계 컴포넌트를 가져왔다.

// Desktop Element: to append a new tab
const desktop = document.querySelector('#desktop');

// Elements will be created by click label
let clockEl = null;

const clickClockLabel = () => {
    // Make sure only one window is open
    if (desktop.contains(clockEl)) return;

    clockEl = createClockEl();
    setAllListenerForWindowEl(clockEl);
    addWindowElToDesktop(clockEl); 	
};

clockLabel.addEventListener('click', clickClockLabel);
  • 같은 컴포넌트에 대한 창이 여러 개 뜨는 것을 막기 위해desktop.contains() 체크를 제일 먼저 수행한다. 이를 위해서 clockEl 요소를 let 전역변수로 빼줬다.
  • 바탕화면에서 아이콘을 클릭했을 때 clickClockLabel()을 실행할 수 있게 리스너를 달아준다.
  • clockEl을 생성한 이후에 할 수 있는 작업들을 이어서 수행해준다.
const setAllListenerForWindowEl = (elem) => {
    clickWindowEl(elem);
    clickCloseBtn(elem, TIMERID);
    createDraggable(elem);
};

const addWindowElToDesktop = (elem) => {
    desktop.append(elem);
    OPEN_EL_LIST.add(elem);
};
  • 열려있는 창에 상호작용을 가능하게 하는 이벤트 핸들러들을 붙여주고, 바탕화면에 추가해준다.

참고

0개의 댓글