웹 페이지 내에서 탭으로 두 개의 하위 페이지를 구분하고, 동시에 외부에서 해당 탭으로 즉시 링크해야 하는 케이스의 웹을 구현해야 했다.
지금까지 탭 메뉴를 구성할 때에는 주로 css의 display 속성을 none과 block(혹은 flex)로 전환하는 형태로 구성을 해왔는데, 이 경우에는 외부에서 두 탭으로 즉시 연결되는 url이 각각 필요했기 때문에 활성화 할 탭을 따르는 url이 별도로 필요했다.
그리고 탭이 변경될 때에는 탭 안에 삽입한 기능들이 재실행 되어야 하기 때문에 페이지가 다시 로드되어야 하는 조건이 요구되었다.
조건
1. url을 통해 웹페이지 접근 시 각각의 탭을 활성화 시킬 수 있어야 한다.ex) <a href="https://localhost:8080#tab1"> -> 링크 연결 시 tab1 활성화 <a href="https://localhost:8080#tab2"> -> tab2 활성화
- 탭으로 접근 시 페이지가 새로 로드되어야 한다.
디자인부터 모든 작업이 하나의 페이지를 기준으로 진행되다가 갑작스럽게 url만 2개가 필요해진 상황이었기 때문에, 완전히 다를 두 개의 url을 생성해 사용하는 것은 여러모로 리소스 낭비였고 기획 의도와도 어긋나는 방식이였다.
때문에 위 예시처럼 탭 컨텐츠의 id를 url 뒤에 붙히는 방법으로 페이지를 구분하는 방법을 시도했지만, 해시는 페이지 내에서 id에 해당하는 요소를 찾아 이동하는 방법이기 때문에 새로고침이 되지 않는다는 문제가 있었다.
이러한 문제를 해결하기 위해 URLSearchParams를 사용하여 url에서 쿼리스트링을 통해 탭 페이지를 구분하도록 진행했다.
URLSearchParams()는 url에서 쿼리 파라미터를 가져오거나 수정할 때 사용하는 Web API 객체이다.
공식문서: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
이 중 get()메소드를 사용해 특정 쿼리의 뒤에 붙는 데이터 값을 가져올 수 있다.
const url = https://localhost:8080?type=tab1
const urlSearch = new URLSearchParams(url);
const type = urlSearch.get('type')
console.log(type) //'tab1'
URLSearchParams 객체를 생성하면서 url을 전달한다. 그리고 URLSearchParams 인스턴스의 get() 메서드로 쿼리스트링의 type 값을 받아오면 활성화하고자 하는 탭의 정보를 url을 통해서 받아올 수 있다.
const urlSearch = new URLSearchParams(window.location.search);
const type = urlSearch.get('type')
if(type==='tab2'){
display('tab2')
}else{
display('tab1')
}
앞서 본 예시와는 다르게 실제로는 동적으로 현재 브라우저의 정보를 가져와야 하기 때문에 window.location.search를 사용했다. window.location.href를 사용해도 되지만 window.location.search는 전체 url에서 쿼리 문자열(?이후의 문자열)만 가져오는 역할을 하기 때문에 search를 사용해주었다.
URL에서 탭 타입 정보를 받아오면 조건문을 통해 해당 정보에 맞는 탭을 활성화시키고 보여주도록 구성하여 문제를 해결했다.
url에 포함된 id해시만으로 탭을 활성화 시키는 방법이 필요해졌다. indexOf()를 활용하여 위와 같은 효과를 유지하면서 동시에 id 해시만 존재할 때에도 탭을 활성화 시킬 수 있도록 체크하도록 만들었다.
const url_queryStr = https://localhost:8080?type=tab2 //쿼리스트링 케이스
const url_idHash = https://localhost:8080#tab2 //id해시만 붙은 케이스
if(window.location.href.indexOf('tab2') === -1){
display('tab1');
}else{
display('tab2');
}
공식문서: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
indexOf()메서드는 호출한 string 객체에서 주어진 문자열에 해당하는 요소의 인덱스 값을 반환한다. 만약 문자열이 존재하지 않으면 -1을 반환한다.
만약 주어진 tab2의 값이 url 내에 존재하지 않으면 -1을 반환할 것이다. 이 경우에는 tab1이 활성화 된 경우이므로 tab1에 필요한 기능들을 실행시킨다. 그 외의 값들은 모두 tab2의 값이 포함된 경우이므로 tab2에 필요한 기능들을 실행한다. 이 경우에는 url 전체를 범위로 잡고 탐색해야 하므로 window.location.href를 사용했다.
두 번째 방법을 통해 해시나 쿼리스트링에 구애받지 않고 키워드 문자열만을 이용해 탭을 활성화 시켜 문제를 해결했다!