티스토리 뷰

1. Custom Confirm

 기본 내장 메서드인 window.confirm의 디자인이 투박하여 페어 썬과 커스텀 컨펌창을 만들었다. 최초에 만들었던 커스텀 컨펌은 콜백함수를 사용하여 코드가 비동기적으로 돌아가도록 처리하였다. 하지만 콜백함수를 넘기다 보니 커스텀 컨펌을 호출하는 함수의 코드가 지저분해졌다. 이를 해결하기 위해 크리스의 리뷰를 반영하여 커스텀 컨펌을 프로미스로 바꾸었다. 프로미스를 바꾸면 콜백함수를 넘기지 않아도 커스텀 컨펌 로직을 비동기적으로 실행할 수 있다는 장점이 있다. 단 커스텀 컨펌을 호출하는 함수에서는 async/await 키워드를 사용해야 한다. 커스텀 컨펌을 호출하는 함수 내부에서는 코드가 동기적으로 실행되야하기 때문이다. 콜백을 넘기는 방식에서 프로미스로 커스텀 컨펌을 바꾸면서 얻은 이점은 호출 함수의 코드가 깔끔해지는 것 외에도 기존 window.confirm의 사용 방식과 유사해진다는 것이다.

export const customConfirm = (message) => {
  return new Promise((resolve, reject) => {
    $('#app').insertAdjacentHTML('beforeend', confirmTemplate(message));
    $('.confirm-modal').addEventListener('click', ({ currentTarget, target }) => {
      if (currentTarget === target) {
        currentTarget.remove();
        resolve(false);
      }

      if (target.classList.contains('cancel-button')) {
        currentTarget.remove();
        resolve(false);
      }

      if (target.classList.contains('confirm-button')) {
        currentTarget.remove();
        resolve(true);
      }

      return;
    });
  });
};
// 커스텀 컨펌을 호출하는 함수(async 함수여야함)
const confirm = await customConfirm(MESSAGE.DELETE_CONFIRM(lineName));

if (!confirm) {
  return;
}

// Promise로 컨펌창의 버튼 클릭여부를 기다린다.
// 만약 동기적으로 기다리지 않는다면 컨펌창의 '확인', '취소' 클릭여부와 관계없이
// confirm 값이 undefined가 되어 early return 되버린다.

 

2. target="_blank" 보안

target="_blank"에 의해 열린 새 페이지에서 window.opener.location을 변경하여, 기존 페이지를 피싱 페이지로 변경해 사용자 정보를 탈취하는 것이다. 이러한 피싱이 가능한 이유는 기본적으로 새 탭을 열면 현재 탭을 열었던 탭의 참조를 반환하기 때문이다. 이 참조를 없애는 방법이 바로 rel="noreferrer noopener"를 추가하는 것이다. 

 

target="_blank"를 아무생각 없이 쓰면 안되는 이유

HTML 마크업을 작성하다 보면 새창 열기 기능을 위해서 다음과 같이 작성하는 경우가 많습니다. 겉보기에는 새창도 잘 열리고 아무 문제가 없는 것 같지만, 이렇게 작성하면 tabnabbing 피싱 공격에

hogni.tistory.com

 

3. Throttle과 Debounce

- 이벤트 발생 빈도 조절

 

 Debounce는 이벤트를 그룹화하여 특정 시간이 지난 후 하나의 이벤트만 발생하도록 하는 기술이다. 즉, 순차적 호출을 하나로 '그룹화' 할 수 있다. 그래서 연속적으로 호출되는 함수 중 마지막 함수(또는 제일 처음)만 호출할 수 있다. 

 Debounce는 웹에서 주로 AJAX 검색에 자주 쓰인다. 예를 들어 검색창에 검색어를 입력할 때마다 API 요청이 간다면 많은 비용이 발생한다. 따라서 사용자의 입력이 있을 때마다 요청을 보내기보다 사용자의 입력이 끝나고 일정 시간이 지난 다음에 요청을 보내는 것이 합리적이다.

 

  Throttle은 이벤트를 일정한 주기마다 발생하도록 하는 기술이다. 예를 들어 Throttle의 설정 시간으로 1ms를 주게 된다면, 해당 이벤트는 1ms 동안 최대 한 번만 발생하게 된다. 즉 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 한다.

 Throttle은 성능 문제로 인해 스크롤 이벤트에서 주로 사용한다. 스크롤을 올리거나 내릴 때 이벤트가 매우 많이 발생한다. 만약 스크롤 이벤트가 발생할 때마다 많은 기능을 하는 함수가 콜백으로 할당되어있다면 굉장히 안좋은 사용자 경험이 될 수 있다. 그럴 때 Throttle을 사용해주면 된다.

 

디바운스(Debounce)와 스로틀(Throttle ) 그리고 차이점

Throttle, Debounce & Difference 스로틀(Throttle) 과 디바운스(Debounce) 란 무엇일까? 이 두 가지 방법 모두 DOM 이벤트를 기반으로 실행하는 자바스크립트를 성능상의 이유로 JS의 양적인 측면, 즉 이벤트(ev.

webclub.tistory.com

 

4. IntersectionObserver

- 특정 영역이 뷰 포트에 보이는지 체크하는 방법

 

IntersectionObserver.IntersectionObserver() - Web API | MDN

IntersectionObserver.IntersectionObserver() IntersectionObserver() 생성자는 새로운 IntersectionObserver 객체를 생성하고 반환합니다. rootMargin 옵션을 지정했다면 값의 구문이 맞는지, 범위가 0.0 이상 1.0 이하인지

developer.mozilla.org

 

5. 옵저버 패턴

 옵저버 패턴(observer pattern)은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다. 데이터의 변경에 따른 뷰의 변화를 처리할 때 유용하다.

 

[디자인패턴] 옵저버 패턴 (Observer Pattern) 아주 간단하게 정리해보기

옵저버 패턴이란? 옵저버란 스타크래프트 프로토스의 유닛으로 적들을 관찰하기 위해 탄생한 유닛이다. 테란전에서 필수 유닛이며 옵저버 패턴(observer pattern)은 객체의 상태 변화를 관찰하는 관

pjh3749.tistory.com

 

6. 키 값을 동적으로 저장하는 방법

const KEY = {
  FIRST: 1,
  SECOND: 2
}

// 방법 1
const obj = {
  [KEY.FIRST]: '1st'
}

// 방법 2
obj[KEY.SECOND] = '2nd'

console.log(obj) // { '1': '1st', '2': '2nd' }
 

JavaScript_ object_객체의 키를 변수로 가져오기

* Assignment 'getExamResult' 함수 구현하기. 인자 'requiredClasses' 배열의 요소로는 있지만, 인자 'scores'의 키로는 존재하지 않는 요소가 있다면, 해당 요소는 'scores'의 객체의 새로운 키가 되고 값은 0이

velog.io

 

7. Map과 Object의 차이

 

Map - JavaScript | MDN

Map Map 객체는 키-값 쌍을 저장하며 각 쌍의 삽입 순서도 기억하는 콜렉션입니다. 아무 값(객체와 원시 값)이라도 키와 값으로 사용할 수 있습니다.Map 객체는 요소의 삽입 순서대로 원소를 순회합

developer.mozilla.org

 

8. flex-grow: 0은 본인의 크기만큼 차지

 

9. CORS 이슈

 

CORS는 왜 이렇게 우리를 힘들게 하는걸까?

이번 포스팅에서는 웹 개발자라면 한번쯤은 얻어맞아 봤을 법한 정책에 대한 이야기를 해보려고 한다. 사실 웹 개발을 하다보면 CORS 정책 위반으로 인해 에러가 발생하는 상황은 굉장히 흔해서

evan-moon.github.io

 

10. JSON 순환참조 Cyclic object 에러

 

JSON.stringify() - JavaScript | MDN

JSON.stringify() JSON.stringify() 메서드는 JavaScript 값이나 객체를 JSON 문자열로 변환합니다. 선택적으로, replacer를 함수로 전달할 경우 변환 전 값을 변형할 수 있고, 배열로 전달할 경우 지정한 속성만

developer.mozilla.org

 

11. fetch

fetch 메소드로부터 반환되는 promise 객체는 HTTP error 상태를 reject 하지 않고 resolve 한다. (HTTP status가 404여도 resolve 함)

에러 핸들링 위해서 다음과 같이 코드를 작성할 수 있다.

try {
    const response = await fetch(searchURL.href);

    if (response.ok) {
      return response.json();
    } else {
      throw new Error(ERROR_MESSAGE.API_REQUEST_ERROR(response.status));
    }
  } catch (error) {
    throw new Error(error);
  }

 

12. cypress intercept

- cypress에서 HTTP request 테스트 하는 경우에 사용.

 

intercept

Use cy.intercept() to manage the behavior of HTTP requests at the network layer. With cy.intercept(), you can: stub or spy on any type of HTTP request. If cy.intercept() provides a response object, o

docs.cypress.io

 

13. Lazy Loading

 lazy loading은 가능한 한 길게 미루어 웹페이지에서 보여줄 콘텐츠들이 실제로 화면에 보일 때까지 미룬 후 로딩하는 기술이다. 다시 한번 강조하면 이 리소스들은 필요할 때 로드 돼야 한다. 텍스트 외에 이미지와 동영상 같은 콘텐츠들은 모든 웹사이트에 애플리케이션에서 매우 중요한 부분이다. 하지만 이러한 콘텐츠들은 페이지 성능에 가장 많이 영향을 주고 있는 요소이기도 하다. 그래서 많은 엔지니어가 이미지를 최적화해서 사용자에게 보여주기 위해 노력했고 그 해결 방법의 하나가 lazy loading 이다.

 

 사용자가 페이지에서 스크롤을 아래로 내림으로써, 이미지의 placeholder는 뷰포트(웹 페이지 내 보이는 부분)에 다가오게 된다. 그리고 이 뷰포트에 보이게되면 이미지가 로딩되도록 트리거를 일으킨 후, 실제 이미지를 렌더링한다.

 

 이 방식은 웹 성능과 디바이스 내 리소스 활용도 증가, 그리고 연관된 비용을 줄이는 데 도움을 줄 수 있다.

 

Image Lazy Loading 기법 그리고 Google I/O 에서의 새로운 방법

Lazy Loading 기법 이제 이미지가로드되는 것을 막을 것이므로 브라우저에 로드 할 시기를 알려줘야합니다. 이를 위해 이미지가 뷰포트에 입력되는 즉시 로드를 트리거하는지 확인합니

frontdev.tistory.com

 

14. Input type="radio"로 네비게이션 탭 만들기