공부 과정 기록07_노마드코더 시청 후 제작 페이지 코드 설명_메인페이지 인사 표현, 로그아웃, 날씨 정보 받아오기(03_03)
지난 글에 이어서 계속 만들어 보겠습니다.
이번 글에서는 메인 화면에 보이는 인사말(Hello asdf)과 우측 상단에 띄워져 있는 위치 정보 표현, 로그아웃 기능을
코드로 한 번 보도록 하겠습니다.
const greetingText = document.getElementById("greetingText");
//localStorage의 길이값 가져옴
const localStorageLen = localStorage.length;
//i => 반복문에 사용되는 변수, key => localStorage의 key값을 담을 변수
//value => key에 대응되는 내용을 담을 변수
let i, key, value;
//localStorage에 저장된 값들 중 status 값이 1인 객체를 찾아 해당 객체를 반환하는 함수
function searchStatus() {
for(i = 0; i < localStorageLen; i++) {
key = localStorage.key(i);
value = JSON.parse(localStorage.getItem(key));
if(value.status === 1) {
return value;
}
}
}
const userName = searchStatus().id;
greetingText.innerText = "Hello " + userName;
todoGreeting.js라는 파일의 코드입니다.
이 코드의 기능을 대략적으로 설명하면 웹 저장소(localStorage)에 현재 로그인되어 있는 계정의 ID 값을 갖고 와서
메인 페이지의 Hello 문자열 뒤에 ID 값을 붙여 주게 됩니다.
변수 선언부터 보면 "Hello ~" 문자열이 담긴 html 요소(greetingText)를 갖고 오고, 웹 저장소의 데이터 탐색을 위해
웹 저장소의 길이값을 갖고 옵니다.
그리고 웹 저장소를 탐색하는 searchStatus 함수에서 사용될 변수 (i, key, value)를 선언했습니다.
searchStatus 함수를 보면 웹 저장소의 길이값을 이용해 반복문을 돌며 웹 저장소의 객체를 하나씩 받아 옵니다.
(value 변수에 객체가 담기게 됨)
그리고 그 객체에는 이 계정이 로그인이 되어 있는 상태인지 나타내는 값인 status 값이 있는데, 이 값은 0일 때는
로그아웃 상태이고 1일 때는 로그인 상태라는 것을 나타냅니다.
이를 통해 조건문으로 해당 계정이 로그인 상태인지를 검사하여 로그인 상태라면 그 객체를 return 해 주고
함수를 종료하게 됩니다.
그래서 밑의 코드를 보면 const userName 변수에 searchStatus 함수의 반환값을 이용하여 id 값을 받아와
넣어 주고 greetingText 객체의 innerText 값에 "Hello" + id 값 을 넣어 줌으로써 인사말 기능을 구현할 수
있게 된 것입니다.
const logoutbtn = document.getElementById("logoutbtn");
//각각 user의 키값, 정보가 들어갈 변수이다.
let userk, userO;
//현재 로그인 되어 있는 객체(status 1)를 찾아 해당 객체의 키값을 반환한다.
function returnUserKey() {
let key, value, i;
for(i = 0; i < localStorage.length; i++) {
key = localStorage.key(i);
value = JSON.parse(localStorage.getItem(key));
if(value.status === 1) {
return key;
}
}
}
//현 상태를 localStorage에 저장하는 역할의 함수
function saveLocal() {
localStorage.setItem(userk, JSON.stringify(userO));
}
//logout 버튼을 눌렀을 때 해당 계정의 status를 0으로 바꾸고 로그인 창으로 페이지를 바꾸는 역할의 함수
function handleLogout() {
userk = returnUserKey();
userO = JSON.parse(localStorage.getItem(userk));
//로그인 상태를 나타내는 status를 0으로 바꾸고, 변경된 상태를 localStorage에 저장한다.
userO.status = 0;
saveLocal();
//alert 창으로 로그아웃 되었음을 알리고, 로그인 페이지로 돌아간다.
alert("로그아웃 되었습니다. 로그인 페이지로 돌아갑니다.");
window.location.href = "index.html";
}
logoutbtn.addEventListener("click", handleLogout);
다음은 로그아웃 기능을 담은 코드입니다.
로그아웃 기능을 구현하려면 필요한 동작이 있는데, 웹 저장소에서 로그인된 계정에 대한 객체를 얻어낼 수
있어야 하고, 해당 객체의 status 값을 0으로(로그아웃 상태로) 바꾼 후 변경 사항을 다시 웹 저장소에 저장할
수 있어야 하고, 마지막으로 로그인 페이지로 사용자를 돌려 보내야 합니다.
위의 코드에는 함수가 3개 있는데, returnUserKey 함수는 로그인된 상태의 객체를 찾아 그 객체의 키값을 반환하는
함수이고 saveLocal 함수는 현 상태의 키값과 객체값을 사용하여(userk, userO) 웹 저장소에 저장하는 함수입니다.
마지막으로 handleLogout 함수는 메인 페이지의 로그아웃 버튼을 눌렀을 때(onclick) 호출되는 이벤트 함수로
위의 2개의 함수 기능을 사용하여 웹 저장소의 값을 바꾸고 로그인 페이지로 현재 페이지를 바꾸는 함수입니다.
returnUserKey 함수를 보면 인사말 구현 코드와 동일하게 웹 저장소를 탐색하며 로그인 상태의 객체를 찾으면
그 객체의 키값을 반환하게 되고, handleLogout 함수에서는 호출되자마자 returnUserKey 함수를 사용하여
키값과 데이터값(userk, userO)을 각 변수에 할당합니다.
그리고 데이터 중 status 데이터를 로그아웃 상태를 나타내는 0으로 바꾼 후(userO.status = 0;) saveLocal 함수를
호출하여 변경 사항을 다시 웹 저장소에 저장합니다.
그리고 alert 창으로 로그아웃 사실을 알린 후 location.href로 index.html 페이지에 돌아가게 합니다.
//html에서 지역명, 온도, 날씨를 표현할 span 태그의 id 값들로 불러왔다.
const locName = document.getElementById("locName");
const locTemp = document.getElementById("locTemp");
const locWeather = document.getElementById("locWeather");
//openweathermap api 키값
const USER_API_KEY = apiConfig.apikey;
//현재 위치 정보를 가져오는 것을 성공했을 때 호출되는 함수이다.
//event 함수와 마찬가지로 다양한 위치 정보가 들어 있는 매개 변수 1개를 넘겨주게 된다.
function displayPosition(pos) {
//매개 변수에서 위도, 경도 값을 변수에 저장한다.
const lat = pos.coords.latitude;
const lon = pos.coords.longitude;
//위치 정보를 불러오려면 url 값에 현재 위치의 위도, 경도, 나의 api 키값을 넣어야 하기 때문에,
//따로 변수로 저장해 주었다.
const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${USER_API_KEY}`;
//fetch로 url에 담긴 파일을 불러와 json 정보를 추출하고(response.json()), 추출한 데이터 중
//원하는 정보를 화면에 표시하게끔 했다.(위에서 순서대로 지역명, 온도, 날씨)
fetch(url).then((response) => response.json()).then((data) => {
locName.innerText = data.name + ", ";
//온도의 소수점 두 자리수까지 표현을 위해 100을 곱한 후 floor로 나머지 소수점을 버린 숫자에,
//다시 100을 나눠 줌으로써 소수점 두 자리수로 표현을 했다.
locTemp.innerText = (Math.floor((data.main.temp - 273.15) * 100) / 100) + "℃";
locWeather.innerText = data.weather[0].main;
});
}
//어떤 이유로(ex : 사용자가 브라우저에서 위치 허용 X) 위치 정보를 가져오는 데 실패했을 때 호출되는 함수
function errPosition() {
alert("사용자가 위치 허용을 하지 않았기에 위치 정보가 표시되지 않습니다.");
}
//사용자의 현재 위치를 가져오고, 성공했을 때 실행할 함수(displayPosition)와,
//실패했을 때 실행할 함수(errPosition)를 지정한다.
navigator.geolocation.getCurrentPosition(displayPosition, errPosition);
마지막으로 메인 페이지 접속 시 위치 정보 허용을 한 상태라면 우측 상단에 현재 위치와 날씨 정보를 띄우게 해 주는
todoWeather.js 코드입니다.
이 코드를 이해하기 위해서는 api가 무엇인지와 fetch로 json 파일의 데이터를 가져오는 것에 대한 개념을 알고 있어야
하는데, 이 글에서 설명하기에는 길어지기 때문에 이 기능이 무엇인지 알고 계신다는 가정을 하고 설명을 드리겠습니다.
먼저 메인 페이지에 위치와 날씨 정보를 띄우기 위해 getElementById로 html 요소를 가져오고, USER_API_KEY 변수에
제 api 키값을 담았습니다.
(참고로 저는 openweathermap에서 제 계정의 api 키값을 가져온 것이고, 저 변수에 제 api 키값이 그대로 나타나면
안 되기 때문에 저는 다른 js 코드에 apiConfig라는 객체를 만들어 거기에 apikey라는 변수값에 제 api 키값을 담고
이 코드에서는 해당 값을 받아와 변수에 넣어 줌으로써 api 키값이 드러나지 않도록 한 것입니다.)
그리고 함수가 2개 있는데 displayPostion 함수는 사용자의 현재 위치를 성공적으로 가져왔을 경우 호출되는
함수이고 errPosition 함수는 위치값을 가져오지 못 했을 때 호출되는 함수입니다.
즉, 메인 페이지에 들어갈 때 위 사진과 같이 권한 요청을 하게 되는데 허용을 눌렀을 때 위치값을 받아올 수 있으므로
displayPostion 함수가 호출될 것이고, 차단을 눌렀을 때는 errPosition 함수가 호출될 것입니다.
이렇게 할 수 있는 기능의 코드는 맨 아래에 있는데, navigator.geolocation.getCurrentPosition 이라는 함수입니다.
이 함수의 매개 변수를 보면 displayPosition과 errPosition 함수를 넘겨 주고 있는데 이를 통해 상황에 따라
다른 함수를 호출할 수 있게 되는 것입니다.
위치값을 성공적으로 받아와 displayPosition 함수가 호출되면 이 함수의 첫 번째 매개변수에 받아 온 위치값에
대한 여러 정보가 담긴 객체를 코드에서 주게 됩니다.
(event 호출 함수에서 매개변수로 event 객체를 받아 오는 것과 동일하게 생각하면 됩니다.)
이 객체에는 위치값의 경도와 위도값도 포함되는데 경도와 위도값은 api로부터 날씨 정보를 받아 오기 위해
필요한 값이므로 lat, lon 변수에 넣어 줍니다.
그리고 날씨 정보를 받아 오기 위한 주소 값을 url 변수에 문자열 형태로 넣어 주는데, 여기서 미리 받아 놓았던
경도와 위도값 그리고 본인의 api 키값을 포함시켜 주소를 작성하게 됩니다.
이렇게 주소값을 작성하면 해당 주소에는 경도와 위도값 위치의 날씨에 관련된 여러 정보가 담긴 json 파일이
나오게 되는데 이를 fetch를 통해 데이터로 받아 옵니다.
(fetch에서 .then이라는 것은 괄호 안의 기능이 성공적으로 실행되었을 때 다음 then의 기능이 실행됩니다.)
여기서 화살표 함수로 data에 날씨 정보에 관련된 json 파일이 객체 형태로 받아오게 되고 그 중 현재 위치의
지역 이름, 온도, 날씨 정보를 받아와 html 요소값에 innerText로 넣어 줌으로써 최종적으로 메인 페이지에서
우리가 권한 허용을 했을 때 날씨에 관련된 정보를 볼 수 있게 되는 것입니다.
다음에는 마지막으로 todo 리스트를 작성하고 삭제하는 기능을 어떻게 구현했는지 보도록 하겠습니다.