[레벨1 - 미션3] 나만의 유튜브 강의실 기억에 남는 피드백
우테코가 비대면으로 이루어지고 있지만 제가 집에만 있다고 노는 건 아닙니다. 할 게 엄청 많습니다.
- 피드백은 할수록 느끼는 거지만 반의 반만 체화시켜도 성공이다!!
💪HTML
태그 속성은 생각보다 대단하다!
태그를 적극 활용하려는 노력이 필요합니다.
- type: search가 있네요.
<input id="search-input-keyword" type="search" placeholder="검색" class="search-input__keyword">
💪CSS
BEM
- BEM을 사용하는 시도들이 곳 곳에 보입니다.
💪JS
DOM Select 함수
- default값을 이용하여 기본을 유지하되, 추가 Element가 있다면 해당 Element만 탐색하는 점에서 유용한 메서드네요! (성능 측면)
const selectDom = (element, parent = document) => parent.querySelector(element);
API 재사용 함수
- API에 따라 다양하게 사용할 수 있을 텐데 재사용 함수로 만들어보는 건 어떨까요?
Template 분리
- 템플릿은 보기에 너무 복잡하죠.
- 템플릿을 생성해주는 메서드들을 따로 분리해보는 건 어떨까요?
Snackbar의 활용
- 사용성을 고려하여 굉장히 좋은 시도인 것 같아요.
@keyframes fadeIn {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
@keyframes fadeOut {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
.snackbar-container.show {
visibility: visible;
animation: fadeIn 0.6s, fadeOut 0.6s 3.5s;
}
Custom EventListener
사용 방법 -> MDN 참고했어요.
- 어떤 곳(form)에서 이벤트가 발생하면 다른 곳(textarea)에서의 값을 가져올 수 있어요.
const form = document.querySelector('form');
const textarea = document.querySelector('textarea');
// 'awesome'이라는 이벤트를 만듭니다.
const eventAwesome = new CustomEvent('awesome', {
bubbles: true, // bubble 옵션을 true로 하고,
detail: { text: () => textarea.value } // detail 안에 전달하고 싶은 데이터를 작성해요.
});
// 'awesome' 이벤트가 발생하면 textarea의 value를 출력합니다.
form.addEventListener('awesome', e => console.log(e.detail.text()));
// form 내부의 textarea에서 input 이벤트가 발생하면,
textarea.addEventListener('input', e => e.target.dispatchEvent(eventAwesome)); // 강제로 dispatchEvent(eventAwesome)을 통해 eventAwesome 이벤트를 발생시킵니다.
- 크루 중 한 분의 실제 코드를 가져와봤어요.
// 참고로 이 함수는 스크롤 이벤트 리스너 함수의 콜백함수가 될 겁니다!
onScrollVideoList() {
const { scrollTop, clientHeight, scrollHeight } = this.searchResultVideoList; // 3개의 변수를 가져와서
const searchOnScrollEvent = new CustomEvent('searchOnScroll', {
detail: { scrollTop, clientHeight, scrollHeight }, // serachOnScroll이라는 이벤트가 발생할 때 전달할 값으로 위 3개의 변수를 설정해요.
});
this.searchModal.dispatchEvent(searchOnScrollEvent); //스크롤이벤트 발생시 이 값을 전달해주겠다는 겁니다.
}
- A 요소와 B 요소가 별도로 역할이 분리되어 있는데 이벤트를 발생시키는 A요소에 있는 값들을 해당 이벤트를 수신하는 상위 컨테이너 B 요소에서 그 전달 받은 값들로 새로운 값으로 가공하거나 변경해서 다른 C 요소에게 전달해야할 때, 각 요소에 대한
의존성을 분리시키고 이벤트에 의존하게 하면서
좀 더 유연하게 처리할 수 있는 장점이 있어요.
<ul>
<li class="a"> </li>
<li class="b"> </li>
</ui>
👍 보통 b에서 이벤트 발생했는데, b의 값을 부모인 <ul>
에서 b의 값을 받아 가공하고 a에게 넘겨줄 때 사용한다고 이해했어요. 맞는지는 모르겠고 필요성도 잘 모르겠지만 많은 크루들이 사용하더라구요. 그냥 넘겨요!
EventHandler 재사용 함수
addEvent(this.container, {
eventType: EVENT_TYPE.CLICK,
selector: '#remove-video-button',
handler: this.handleClickRemoveButton,
});
👆좋긴한데 코드가 길어지고 굳이? 라는 생각도 좀 드네요.
👇이건 좀 의미가 있어 보이네요!
export const addEvent = (component, eventType, selector, callback) => {
const children = [...component.querySelectorAll(selector)];
const isTarget = (target) => children.includes(target) || target.closest(selector);
component.addEventListener(eventType, (event) => {
if (!isTarget(event.target)) {
return false;
}
return callback(event);
});
};
객체의 인스턴스를 하나로 관리
이걸 싱글톤 패턴이라고 부르네요!
export default class StorageEngine {
static _instance = null;
static get instance() {
if (!StorageEngine._instance) {
StorageEngine._instance = new StorageEngine();
}
return StorageEngine._instance;
}
DOM Clear하기
this.#myVideoList.replaceChildren();
이벤트 핸들러 네이밍
이벤트핸들러는 on/handle + {target} + {eventType}
이런 식으로 네이밍을 합니다.
예를 들면 onXXXClick/Change, handleXXXClick/Change 같은 식으로요!
this.mainView.bindModalOpenButton(this.onModalOpenButtonClick.bind(this));
Element.closest()
- 언제까지 타고 갈래요?
closest()
를 사용해봅시다.
const target = e.target.parentNode.parentNode;
다이어그램
맵을 그려볼까요? 아키텍처 맵은 두 가지로 분리해서 한 번 그려보시면 좋을 것 같아요.
-
폴더 스트럭쳐: 폴더 스트럭쳐단위로, 서로의 폴더가 어떤걸 참조하고 있는지!
-
SoC: 관심사 단위로 어떤 것들이 어떻게 분리되고 어떻게 참조하고 있는지!
-> 그려보는 것 또한 공부입니다!
Author And Source
이 문제에 관하여([레벨1 - 미션3] 나만의 유튜브 강의실 기억에 남는 피드백), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jhy979/레벨1-미션3-나만의-유튜브-강의실-기억에-남는-피드백저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)