본문 바로가기
TIL/HTML, CSS, JS 이것저것

JS30-Stripe Follow Along Dropdown

by Dev_Dank 2021. 6. 24.

JS30 26강을 진행하면서 배운 내용을 정리해두려 합니다. 


1. Arrow function은 this를 바인딩 하지 않기 때문에 arrow function 에서 this를 쓰면 바깥 스코프의 this를 사용함. 

function handleEnter() {
this.classList.add('trigger-enter');
setTimeout(() => {
//여기서 this는 addeventlistener 가 붙은 element를 가리킨다.
this.classList.add("trigger-enter-active");
}, 150)
function handleEnter() {
this.classList.add('trigger-enter');
setTimeout(
//setTimeout은 기본적으로 콜백함수의 this를 전역객채로 생성해서 이렇게 하면 오류가나옴.
this.classList.add("trigger-enter-active");
}, 150)

2. display:none은 transition 적용이 않되고 특정 CSS 코드블럭에 존재하면 모든 transition이 안먹힘. 

.dropdown {
opacity: 0;
...
transition: all 2s;
display: none;
}
<!--이렇게 하면 트랜지션이 적용되지 않아서 부드럽지 않다.-->
.trigger-enter .dropdown {
display: block;
opacity: 1;
}
<!--이렇게 먼저 display를 block으로 바꿔서 화면에 표시한후 opacity를 바꿔줘야 transition이 적용됨-->
.trigger-enter .dropdown {
display: block;
}
.trigger-enter-active .dropdown {
opacity: 1;
}

 

3. nested 된 element의 getBoundingcCientRect는 해당 element를 감싸고 있는 요소의 좌표 값또한 고려해야 정확한 x, y 좌표를 알 수 있다. 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Comparison of positioning schemes</title>
<style>
html {
box-sizing: border-box;
font-family: "Arial Rounded MT Bold", "Helvetica Rounded", Arial,
sans-serif;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
nav {
position: relative;
perspective: 600px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
li {
position: relative;
display: flex;
justify-content: center;
border: 1px solid black;
margin: 20px;
}
.square {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
display: none;
}
.square2 {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
display: none;
}
.test1 {
display: block;
}
</style>
</head>
<body>
<h2>testing</h2>
<nav>
<div class="square"></div>
<div class="square2"></div>
<ul>
<li>test</li>
<li>test</li>
</ul>
</nav>
</body>
<script>
let test = document.querySelector("li");
let testul = document.querySelector("ul");
let nav = document.querySelector("nav");
let rect = test.getBoundingClientRect();
let square = document.querySelector(".square");
let square2 = document.querySelector(".square2");
function show() {
square.style.top = test.getBoundingClientRect().bottom + "px";
square.style.left = test.getBoundingClientRect().left + "px";
square.classList.add("test1");
console.log(square.style.left, square.style.top);
square2.style.top = square.getBoundingClientRect().bottom + "px";
square2.style.left = square.getBoundingClientRect().left + "px";
square2.classList.add("test1");
console.log(square2.style.left, square2.style.top);
}
function hide() {
square.classList.remove("test1");
}
function log(e) {
console.log(e);
}
test.addEventListener("mouseover", show);
//test.addEventListener('mouseleave', hide);
addEventListener("click", log);
</script>
</html>

위의 예제에서는 nav 안에 square 와 square2가 중첩되어있어서 getBoundingRect를 쓰면 제대로된 값이 안나온다. 따라서 DOMrect에 square 와 square2를 감싸고 있는 nav의 DOM rect 값을 빼줘야 정확한 값이 나온다. 

만약 그게 싫다면 그냥 nav에서 square 와 square2를 빼버려도 정확한 값으로 DOMrect를 구할수 있다. 

...
<body>
<h2>testing</h2>
<nav>
<ul>
<li>test</li>
<li>test</li>
</ul>
</nav>
<div class="square"></div>
<div class="square2"></div>
</body>
...

근데 사실 내부원리가 뭔지 잘 이해가 안간다. 대체 왜 중첩된 요소에서 getBoundingRect를 쓰면 x, y 좌표가 감싸고 있는 요소의 x, y 까지 더해서 나오는걸까?? MDN 문서나 스펙시트를 봐도 getBoundingRect는 viewport 기반으로 위치를 구한다고 나오는데.... 나중에 꼭 알아 냈으면 좋겠다. 

댓글