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 기반으로 위치를 구한다고 나오는데.... 나중에 꼭 알아 냈으면 좋겠다.
'TIL > HTML, CSS, JS 이것저것' 카테고리의 다른 글
JS30-Countdown Timer (0) | 2021.06.27 |
---|---|
JS30 - Video Speed Controller (0) | 2021.06.25 |
JS30- Sticky Nav / Event Capture, propagation (0) | 2021.06.23 |
JS30 - Follow Along Link Highlighter (0) | 2021.06.21 |
JS30-Local storage, Mouse Move, Sort (0) | 2021.06.16 |
댓글