한번쯤 되돌아볼만한 키워드 리스트

이효범·2022년 4월 21일
0

빵부스러기

목록 보기
1/3
post-thumbnail

개발하며 알게되는 빵부스러기를 기록한다. 빵부스러기 시리즈는 새롭게 알게되는 빵이 있을 때마다 최신화하도록 한다.


빵부스러기

this.parentNode ⇒ this를 감싸고 있는 부모요소를 반환해준다.

this.nextElementSibling ⇒ this 의 다음에 따라오는 형제 요소를 반환해준다.

this.previousElementSibling ⇒ this 의 앞에 오는 형제 요소를 반환해준다.

this.children ⇒ this의 자식 요소들을 리스트(배열) 형태로 반환해준다.

this.textContent ⇒ 선택한 요소(this)의 text 값이 들어있다면 text를 반환해준다.

this.classList.contains("className") ⇒ 클래스가 있는지 없는지에 따라 boolean값을 반환한다.

e.target ⇒ 이벤트의 종류를 클릭으로 예를 들자면, 내가 클릭한 요소가 무엇이지? ⇒ e.target , 즉 클릭한 DOM Element의 정보를 리턴해준다.

e.stopPropagation() ⇒ 이벤트는 기본적으로 전파가 된다.(작은부분에서 큰 부분으로), e.stopPropagation()은 이벤트 전파를 멈추게 한다.

this(parent).removeChild(child: Node) ⇒ 기억해야할 포인트는 DOM에서 어떤 요소를 삭제할 때 그 권한은 내가 삭제 하고자 하는 요소의 부모한테만 있다는 것. 부모요소안에 포함되어있는 선택한 자식 요소를 삭제해준다.

this.appendChild(chile: Node) ⇒ 요소를 추가할 때도 마찬가지로, 추가하고자 하는 요소를 감싸고 있는 부모에게 작업을 해주도록 해야한다. ⇒ append 는 ‘추가하다’ 라는 뜻이며 그냥 사용할 시에는 부모 요소안의 마지막 자식으로 들어가게 된다.

this.prepend(child: Node)appendChild 와 동일하지만 마지막 자식이 아니라 첫 번째 자식으로 들어간다. prepend 는 ‘앞에 붙히다’ 라는 뜻을 가진다.


this.contains(”선택한 명시적 요소”) ⇒ this가 “선택한 명시적 요소”를 포함하고 있는지 없는지에 따라 boolean 값을 리턴해준다. 밑의 설명 참고

const myMenu = document.querySelector('.my-menu')
const myMenuButton = document.querySelector('.my-menu-button')

function closeMyMenuOnClickingOutside(e) {
  if (!myMenu.contains(e.target)) { // myMenu가 e.target을 포함하고 있어? 라고 물어보는것. 그냥 myMenu안에 포함되어있는지(자식~손자 요소인지)를 묻는 것이다.
    myMenu.classList.remove('is-active')
    window.removeEventListener('click', closeMyMenuOnClickingOutside)
  }
}

function toggleMyMenu() {
  if (!myMenu.classList.contains('is-active')) { // classList.contains는 위와 다른 경우, 단순히 myMenu가 "is-active" 라는 클래스명을 가지고 있는지를 판단하는 것임
    window.addEventListener('click', closeMyMenuOnClickingOutside)
  }
  myMenu.classList.toggle('is-active')
}

myMenuButton.addEventListener('click', toggleMyMenu)

this.setAttribute("attributeName", "attributeValue") ⇒ this의 속성값을 설정해준다. 밑의 코드를 참고

Element.setAttribute(qualifiedName: string, value: string): void
// 첫 번째 인자로는 내가 어떤 attribute을 바꾸고 싶은지를 명시하기 위한 이름을 적는다.
// 두 번째 인자로는 위 명시한 attribute에 어떤 값을 넣고 싶은지에 대한 값을 넣어준다.

// setAttribute은 굉장히 다양하게 사용할 수가 있다.
// 그래서 만약 class를 바꾸고 싶을 때에도 classList 메소드를 쓰지 않고도 setAttribute을 이용하여 바꿀 수 있다.
// 다음 예시를 봐보자.
countSpan.setAttribute('class', 'hi')
// 나는 class 라고 하는 속성을 바꿔줄건데, 뭐로 바꿔줄 거냐면 hi로 클래스이름을 바꿔줄거야
// 애초에 class 가 없다고 하면 class를 추가해준다.

this.getAttribute("attributeName") ⇒ setAttribute와 반대로 어떠한 요소가 어떠한 속성값을 가지고 있는지 알고 싶을 때 사용한다. attributeName은 값을 얻고자 하는 속성의 이름이다. 밑의 코드를 참고

let div1 = document.getElementById("div1");
let align = div1.getAttribute("align");

alert(align); // id가 "div1"인 요소(element)의 align 값을 보여줍니다.

---

const TOP_HEADER_DESKTOP = 80 + 50 + 54
const TOP_HEADER_MOBILE = 50 + 40 + 40

const tabPanelId = this.parentNode.getAttribute('aria-labelledby');
console.log(tabPanelId); // product-review

const tabPanel = document.querySelector(`#${tabPanelId}`)
const scrollAmount =
    tabPanel.getBoundingClientRect().top -
    (window.innerWidth >= 768 ? TOP_HEADER_DESKTOP : TOP_HEADER_MOBILE)

  window.scrollBy({
    top: scrollAmount,
    behavior: 'smooth',
  })

String.replaceAll() ⇒ 밑의 설명 참고

const a = 'aaaaaaabbbbbbccccccddddd'

a.replace('b', 'z')  // 나는 a가 갖고있는 b를 z로 바꿔주겠어!
console.log(a)  // aaaaaaazbbbbbccccccddddd 
// 제일 처음에 만나는 b 를 z로 바꿔준다.
// 근데 만약 b의 전체를 다 z로 바꿔주고 싶다면 ? => replaceAll 을 사용하자.

a.replaceAll('b', 'z')
console.log(a)  // aaaaaaazzzzzzccccccddddd 

// 다음 예시도 봐보자.
function toggleOrderCtaBookmark() {
	const [icon, countSpan] = this.children
	console.log(countSpan) // '18,302'
	const count = Number(countSpan.innerHTML.replaceAll(',', ''))  // 콤마가 있으면 지워줘 그리고 숫자로 변환해줘
	console.log(count) // 18302
	
	let newCount = count
	if (this.classList.contains('is-active')) {
	    newCount = newCount - 1
	} else {
	    newCount = newCount + 1
	}
	
	countSpan.innerHTML = newCount.toLocaleString()  // 다시 콤마를 넣어준다.
	countSpan.setAttribute('aria-label', `북마크 ${newCount.toLocaleString()}`)
// 내가 지금 바꾸고 싶은 attribute은 'aria-label' 이고, 뭐로 바꾸고 싶냐면 `북마크 ${newCount.toLocaleString()}회`로 바꾸고 싶다. 
	// ...생략
}

Number.toLocaleString() ⇒ 밑의 설명 참고

Number.toLocaleString(locales?: string | string[], options?: Intl.NumberFormatOptions): string

---

const a = 21342583425252134
console.log(a.toLocaliString()) // '21,342,583,425,252,136'
// toLocaliString()은 알아서 콤마를 알맞은 위치에 넣어주어 포맷팅해주는 자바스크립트 메소드다.
// 다만 스트링 타입으로 리턴하니 필요하다면 숫자 타입으로 바꿔주면 된다.

Element.getBoundingClientRect() ⇒ Viewport 화면 내에서 명시한 요소의 위치가 어디에 위치에있는지에 대한 정보를 반환해준다. 즉, 어떠한 요소가 뷰포트를 기준으로 y축으로 x축으로 얼마나 떨어져 있는지에 대한 정보를 반환해준다. 밑의 이미지와 코드 참고

function scrollToTabPanel() {
  const tabPanelId = this.parentNode.getAttribute('aria-labelledby')
  const tabPanel = document.querySelector(`#${tabPanelId}`)

  const scrollAmount =
    tabPanel.getBoundingClientRect().top -
    (window.innerWidth >= 768 ? TOP_HEADER_DESKTOP : TOP_HEADER_MOBILE)

  window.scrollBy({
    top: scrollAmount,
    behavior: 'smooth',
  })
}

window.innerWidth ⇒ 유저가 현재 보고있는 창의 크기가 얼마인지 알 수 있다. 밑의 코드 참고.

const scrollAmount =
    tabPanel.getBoundingClientRect().top -
    (window.innerWidth >= 768 ? TOP_HEADER_DESKTOP : TOP_HEADER_MOBILE)

window.innerHeight ⇒ 뷰포터의 세로 길이 값을 알 수 있다.

window.scrollY ⇒ 유저가 Y 축으로 스크롤을 얼마나 했는 지 알 수 있다.

window.scrollY + Element.getBoundingClientRect().top 은 해당 요소가 문서의 시작점에서부터 얼만큼 아래에 위치하고 있는지에 대한 정보를 반환한다. 즉 요소의 y축 위치를 항상 동일한 값으로 반환해준다.

또한 이를 활용하면, 만약 유저가 스크롤을 제일 아래까지 내렸을 경우, window.scrollY + window.innerHeight 의 값은 전체 웹페이지 body의 heigth와 같다는 것을 알 수 있다. 밑의 설명 참고

이를 반대로 생각해보면 window.scrollY + window.innerHeight 의 값이 전체 웹페이지의 height 와 같다면, 유저가 현재 웹페이지의 제일 아래 부분까지 스크롤을 했다는 것을 알 수 있다.

그렇다면 웹 페이지 전체 bodyheight 는 어떻게 구할까 ?

document.body.offsetHeight => 전체 문서 body 의 총 길이를 알려준다.

다만 만약 태블릿이나 모바일과 같은 환경에서 order-CTA 와 같은 컴포넌트가 bottomfixed 된 방식으로 표시되어지고 있고 또한 이 컴포넌트에 특정한 마진값이 설정되어있다면 마진값은 따로 사이즈를 가지고 있다고 보지 않기때문에 이를 적절히 계산해주어야 한다. 밑의 코드 참고.

 const bodyHeight =
    document.body.offsetHeight + (window.innerWidth < 1200 ? 56 : 0)
 // 태블릿 사이즈부터는 margin-bottom: 56px 이 주어지기 때문에, 56px을 따로 추가해준 경우이다. 데스크탑은 margin-bottom 이 0으로 설정되어 있다.
profile
I'm on Wave, I'm on the Vibe.

0개의 댓글