일정 정리
220119 수: 퇴근 전 과제 부여. dmp 개발환경 세팅
220120 목: 본격적으로 개발 시작. 소스 코드 분석. 전체 메뉴 드롭다운 구현.
220121 금: figma ui와 동일한 수준까지 구현 완료. dmp 메뉴 순서 수정 작업 완료. 기존 animation 효과들 삭제 작업 (여기서 막힘)
220124 월: 저번주 막힌 부분 해결. 하위 메뉴 hover 시 " > " 를 최대한 깔끔하게 구현하기. 창 줄였을 때도 고려해서 만듦. 자잘한 수정으로 완성도 높이기. 리뷰 전 최종 완성.
총 3일 정도 걸림.
요구사항
- 네비바에 마우스 hover하면 전체 메뉴가 나와야 함.
- 메뉴를 그룹별로 묶어서 border 라인 컬러 넣을 것
- 현재 들어와있는 active 메뉴에 대해 active class 효과: border 라인, font weight
- hover 된 메뉴에 대해 hover 효과: ">" 아이콘, 해당 메뉴가 속한 그룹 전체에 대한 font weight
- 기존 애니메이션 효과 삭제
ci 스터디 및 소스 코드 파악
- 네비바 코드 위치: app/Views/templates/header.php
- 컨트롤러: app/Controllers/AppProfile.php
기본적으로 큰 페이지들은 controllers에 파일이 하나씩 있다. 해당 컨트롤러 가장 상단에서 pagetitle을 거기에 맞게 바꿔주면 처음 들어갔을 때 그에 맞는 컨텐츠들을 list()로 뿌려주는 구조다. header 뷰, 컨텐츠 뷰, footer 뷰 를 각각 echo 함으로써 페이지가 완성된다. (나는 header와 footer는 안 바뀌고 content 만 바뀌는 구조를 생각했는데 그런 구조는 아니었고, 각각 그때마다 echo 하는 구조였다)'
네비게이션 바 드롭다운 시, 전체 메뉴가 나오도록 하기
네비게이션 바에 마우스 hover 시, 각 드롭다운 메뉴들을 모두 display: block 처리해주고, 뒤에 동일한 배경색의 div를 덧대는 방식으로 구현했다.
.page-header:hover ~ .submenu-wrapper{
position: absolute;
top: 65px;
width: 100%;
height: 210px;
background: #fff;
z-index: 3;
}
- css 인접 형제 선택자 사용
- z-index 사용
메뉴 그룹별 border 컬러 구분하기
.page-menu-bar #js-nav-menu {
--nav-menu-group-1-color: #EF4F23;
--nav-menu-group-2-color: #1F2353;
--nav-menu-group-3-color: #4BC3E9;
}
.page-header:hover #js-nav-menu li.mr-3.nav-menu-group-1 {
border-color: var(--nav-menu-group-1-color);
}
.page-header:hover #js-nav-menu li.mr-3.nav-menu-group-2 {
border-color: var(--nav-menu-group-2-color);
}
.page-header:hover #js-nav-menu li.mr-3.nav-menu-group-3 {
border-color: var(--nav-menu-group-3-color);
}
- css 사용자 속성 변수 사용 (var)
현재 들어와있는 active 메뉴에 대해 active class 효과 주기
- 기존 코드에 현재 활성화된 메뉴에 대한 active 클래스를 표시해주는 기능은 이미 완성되어 있었다.
hover 된 메뉴에 대해 hover 효과: ">" 아이콘, 해당 메뉴가 속한 그룹 전체에 대한 font weight
- 이건 사실 아주 간단하게 구현할 수 있었는데, 기존 구조를 안 바꾸고 하려다보니까 좀 복잡하게 돌아간 케이스였다. 고민했던 점은 hover 될 때마다 UI의 변화없이 오로지 ">"아이콘 유무의 차이만 있었으면 했고, 화면 사이즈가 줄어들어도 깔끔하게 간격과 정렬이 유지됐으면 했다. 기존 코드는 hover 시에 before 클래스를 활용해서 아이콘을 그때그때 추가해주는 방식이었다. 그러다보니 해당 요소의 크기에도 변화가 생겨서 hover 시에 원치 않는 UI의 미세한 움직임들이 보였다. (아주 거슬림...ㅋㅋㅋ) 그렇다고 position 속성을 바꾸자니 기존의 간격과 정렬이 망가져서 그걸 다시 세팅해주는 수고가 적지 않았다. 물론 단순히 수고스러워서 하지 않았던 것은 아니고 그 작업을 해준다고 해서 UI가 아주 깔끔하게 정렬되는 것도 아니었기 때문에 분명 더 좋은 방법이 있을 거라는 확신이 들었다.
- 결국 요소의 변동 없이 css 만 깔끔하게 바꾸려면 html 자체를 조금 수정해줄 필요가 있었다. 그래서 before 클래스를 추가하는 방식이 아니라, 애초에 아이콘을 html에 넣어주어서 hover 시에 css color 를 바꿔서 보였다가 안 보였다가 할 수 있도록 만들었다. 정렬과 간격도 아주 깔끔했고, before 요소처럼 있다 없다 하는 게 아니라 언제나 존재하고 있기 때문에 수정 작업을 할 때도 훨씬 수월했다. before 와 after 클래스가 어떤 면에서는 정말 좋은 방법이지만, 가끔씩은 정말 불편하다는 생각이 들었다. 특히 UI 작업할 때는 더 까다롭고 작업하기에 불편한 점이 있다고 느꼈다.
기존 애니메이션 효과 삭제
- 해당 코드 찾아내기: 내가 삭제하고자 하는 애니메이션 효과가 css 효과인지, 아니면 js 이벤트인지 모르는 상황이기 때문에 우선은 찾아내는 것이 우선이었다. 개발자 도구를 통해 animation, transition 등을 검색해서 알아내는 방법, 혹은 걸려있는 event listener 를 보는 방법이 있는데 나는 둘다 그렇게 해서는 찾을 수 없었다. 소스코드에 직접 들어가서 해당 요소에 걸려있는 이벤트나 css 들을 일일이 찾아보는 방법도 시도해보았고, 이벤트 액션명으로 검색하고 의심되는 코드를 주석처리 해가면서 제대로 찾은 건지 확인했다. 결국은 찾아내긴 했다. (mousedown) 어쨌든 검색 키워드들은 알고 있으니 그냥 마음을 편히 먹고 소스코드를 하나씩 둘러보면서 찾다보면 어떻게든 찾아지긴 했다. 없는 코드가 작동하는 경우는 절대 없으므로.
- 주석 처리로 제거해야 될 부분 정확히 발라내기: 참고로 나는 public/js/app.bundle.js 에서 해당 코드를 찾았는데, 코어에 해당하는 js 파일이므로 무작정 애니메이션 하나 없애겠다고 주석 처리했다가는 다른 코드들에도 영향을 미칠 수 있었다. 그래도 우선은 주석 처리해보면서 잘 없어지는 지 확인을 해볼 필요는 있는데, 이때 정확히 어떤 부분을 주석처리 했을 때 어떠한 변화가 일어나는지 잘 들여다볼 필요가 있었다. 가끔씩은 해당 부분을 주석처리해서 원하는 애니메이션이 없어졌다고 착각할 수도 있기 때문이다. 해당 부분이 주석 처리되면서 그와 연결된 다른 부분에 에러가 생기면서 렌더링이 멈춘 경우도 있고, 주석 처리를 애매하게 해줘서 syntax error 가 발생(정확히 한 블럭을 제대로 주석처리 해줘야 syntax error 같은 게 나지 않을 수 있다) 하는 경우도 있으니 착각하지 않도록 주의해야 한다. 이럴 때 대충 오 애니메이션 없어졌네, 하고 그냥 넘어가면 정작 건드려줘야 하는 부분은 그대로 남아있고 엉뚱한 곳에 에러만 뜨기 때문에 주석 처리를 해주면서 제거해줘야 하는 부분을 찾을 때는 인과관계를 명확히 하면서 찾아내야 한다. 그리고 가장 중요한 것은 내 작업이 기존의 코드에 미치는 사이드 이펙트가 있는지 없는지 항상 주의해야 한다.
/**
* click events
**/
self.find("li a").on('mousedown', function(e) {
if ($(this).parent().find("ul").length !== 0) {
if (opts.accordion) {
/**
* do nothing when the list is open
**/
if (!$(this).parent().find("ul").is(':visible')) {
parents = $(this).parent().parents("ul");
visible = self.find("ul:visible");
visible.each(function(visibleIndex) {
var close = true;
parents.each(function(parentIndex) {
if (parents[parentIndex] == visible[visibleIndex]) {
close = false;
return false;
}
});
if (close) {
if ($(this).parent().find("ul") != visible[visibleIndex]) {
$(visible[visibleIndex]).slideUp(opts.speed + 300, opts.animate, function() {
$(this).parent("li")
.removeClass("open")
.find("a:first")
.attr('aria-expanded', false)
.find("b:first")
.html(opts.closedSign);
if (myapp_config.debugState)
console.log("nav item closed")
});
}
}
});
}
}
- css 애니메이션 제거: css 효과 같은 경우는 선택자를 좀더 구체적으로 사용해줌으로써 혹은 정확히 해당 부분을 none으로 덮어씌우면서 기존의 것을 제거할 수 있었다.
/* remove animation */
.nav-function-top .page-sidebar .primary-nav .nav-menu > li:hover > a + ul {
animation: none;
-webkit-animation: none;
}
- js 이벤트 같은 경우는, 이벤트가 걸려 있는 요소들의 부모 요소에 동일한 이벤트를 걸어주고 이벤트 캡쳐링(하위 전파)를 막아주는 방식으로 기존 이벤트를 동작하지 않도록 할 수 있었다.
그런데 문제는 방법은 알겠는데 막상 코드를 작성하면 의도대로 동작하진 않는다는 것이다. 첫 시도에는 부모요소에 mousedown 이벤트를 걸어주고, preventDefault()를 해주었는데 잘 동작하지 않았다. 결국 다른 매니저님께 여쭤봤고 방법을 찾을 수 있었다.
그동안은 이벤트 리스너에서 이벤트 타입과 콜백 함수 이렇게 2가지 인자만 받아서 사용해왔는데, 옵션인 세번째 인자에 이벤트 버블인지 이벤트 캡쳐인지를 boolean으로 지정해줘서 사용할 수 있었다. 이벤트 버블 (false), 이벤트 캡쳐(true)
나의 경우, 1차적으로는 부모 요소의 mousedown 이벤트가 이벤트캡쳐링으로 하위 요소들에게 전달되도록 할 것이고 2차적으로는 그 전달되는 이벤트를 preventDefault()로 막아줌으로써 기존에 자식 요소들에 걸려있던 mousedown 이벤트가 동작하지 못하도록 막을 것이다. addEventListener('click', callback, true). 여기서 callback 안에 preventDeafult() 함수를 써줄 것이다.
var headerSelected = document.querySelector("header");
headerSelected.addEventListener('mousedown', function(e){
e.stopPropagation();
e.preventDefault();
}, true);
https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener
화면 크기에 따라 css 변화주기. 미디어쿼리 사용
/* media query */
@media screen and (max-width: 1350px) {
.page-header:hover ~ .submenu-wrapper{
height: 250px;
}
}
comment
- figma는 디자이너와 협업하기 좋은 툴 같다. 요구사항이 좀더 명확해짐을 느꼈다.
- 기존에 걸려있는 css 효과나(특히 애니메이션) js 이벤트들을 없애는 것이 가장 어려웠던 부분이었다. 부트스트랩과 같이 어떻게든 작동되도록 만들어진 프론트엔드 프레임워크로 이미 만들어져있는 코드들을 수정하는 건 정말 어려웠다. 그래서 다른 매니저님들은 아예 새로 만드는 것이 더 쉽고 배우는 점도 많을 것이란 조언을 해주셨다. 그 말에 완전히 동의했지만, 지금까지 해온 작업이 있었고 애니메이션만 제거하면 완성이었기 때문에 일단 이번 업무는 그냥 있는 것들을 수정하는 방법을 택했다. 일단은 주어진 업무이므로 지금까지 소요된 시간과, 앞으로 소요될 시간을 계산했을 때, 이 정도 수준의 업무라면 우선은 빨리 끝내는 방법을 택하는 게 더 맞다고 판단했다. 아마 과제를 부여받은 처음 시점으로 돌아간다면 부트스트랩을 좀 버리고,,,ㅋㅋㅋ 새로 만들 것 같다.
- 코드가 의도한 대로 동작하지 않으면 우선은 해당 함수에 대한 공식 문서를 보는 것이 가장 빠른 길일 수도 있다. 의외로 소득이 없을 수도 있지만 예외적인 상황에 대한 팁을 얻을 수도 있고, 잘 몰랐던 옵션들을 통해서 원하는 대로 동작하게끔 만들 수도 있다.
- css 작업은 처음 생각했던 todo가 10가지였다면 하나를 수정할 때마다 거기서 파생된 할일들이 또 생겨서 10가지의 todo 각각이 가지치기를 하는 느낌이 든다. 할일이 점점 늘어난다는 뜻이다. 생각보다 마음처럼 되지도 않고 진행되었던 작업을 다시 엎기도 해서 어디까지 했는지 todo를 잘 정리하면서 작업해야 할 것 같다. 그리고 항상 언제 구조를 엎을지 모르니 css 코드에 주석을 반드시 그때그때 달아줘야 할 것 같다.
'기타' 카테고리의 다른 글
환경 변수 관련 스터디 (2) - zsh 에서 .bash_profile 적용 (0) | 2022.01.26 |
---|---|
22년 1월 3주차 TIL (0) | 2022.01.25 |
github 인증 오류 / password authentication was removed / 인증 토큰 발급 (0) | 2022.01.19 |
라라벨 과제 코드리뷰 후기 / 라라벨 과제 최종 리뷰 (0) | 2022.01.18 |
라라벨 과제 2차 리뷰 (210113) (0) | 2022.01.17 |
댓글