<목표>
본인에게 맞는 운동을 유형검사를 통해 쉽고 빠르게 찾아주는 간단한 서비스
<서비스 페이지 링크>
https://bobotrainfit.netlify.com
<참고 소스코드>
https://github.com/bobotrain/TrainingFit-_Test.git
<사용 기술스텍>
<서비스 설명>
· Javascript Export함수를 응용 → 유형별 DATA를 종합
· 데이터 결과를 코드화 하여 parameter로 전달 → 해당 파라미터에 해당하는 결과지 출력
· 외부 공유기능 제공
· 어울리는 추천 성격 키워드 제공
· 배포는 netlify를 통해 자동화 배포.
<코드분석>
css / js / html 로 분리
1. html / css : 소스코드 참고 - 생략
2. js 분석
1) data.js - export함수로 객체배열 형성 - 결과를 const변수에 담아 활용
export const questions = [ //export / 자바스크립트 객체배열 내보내기
{
number: '01',
question: '너는 무슨 목적을 가지고 운동을 시작하니?',
choices: [
{ text: '남들에게 멋있어 보이고 싶어<br>(당장 빠르게 성과를 내고싶어!)', value: 'a' },
{ text: '체력을 기르고 싶어!<br>내 건강이 우선이야...', value: 'b' }
]
},
{
number: '02',
question: '얼마만큼 투자할 수 있니?<br>나의 지갑 사정은?',
choices: [
{ text: '한 푼도 쓰고싶지 않아~', value: 'a' },
{ text: '효과만 좋다면야...<br>얼마든지 쓸 수 있지!', value: 'b' }
]
},
{
number: '03',
question: '너가 운동하고 싶은<br>분위기는?',
choices: [
{ text: '북적북적 씨끌씨끌 으쌰으쌰! ', value: 'a' },
{ text: '조용히 고독하게. 한산한 곳에서 나에게만 집중!', value: 'b' }
]
},
{
number: '04',
question: '나의 의지 수준은?',
choices: [
{ text: '목표한 바는 혼자서도 끝까지 경주하는 독한 성격!', value: 'a' },
{ text: '남이 나를 머리채 잡고 끌어줬으면 좋겠어 ㅠㅠㅠ', value: 'b' }
]
},
{
number: '05',
question: '내가 생각하는 운동이란?',
choices: [
{ text: '땀을 시원하게 쏟아내는 고강도의 운동<br>(암 그래야 운동이지!)', value: 'a' },
{ text: '천천히 하지만 내실있게 꾸준히!<br>(부상조심 휴우~) ', value: 'b' }
]
},
]
export const results = [
{
title: '웨이트 트레이닝<br>고독한 헬서',
character: '/images/result_character1.png',
results: [
'혼자서 멘탈 케어가 가능해요!<br>끈기 있게 혼자서 운동을 잘 다녀요!',
'몸에 대한 욕심이 많아요.<br>행복한 헬스장 출근이에요!',
'자유로운 환경에서 더 잘해요!<br>하지만 누구보다 스스로 시간 관리가 철저해요:)',
'효율적이고 낭비가 적어요!.<br>야무지다는 소리 많이듣죠 (뿌듯)'
],
minds: ['고통에 익숙한', '끈기있는'],
lectureImg: '/images/result_lecture1.png',
},
{
title: '크로스핏<br>완벽한 인싸!',
character: '/images/result_character2.png',
results: [
'나는야 센스쟁이!<br>언제나 토닥토닥 으샤으샤 응원하며 다니는 파워 인싸!',
'강해지고 싶고 건강증진이 최고에요!',
'진행력 갑! 추진력 갑!<br>빠른 속도로 강도높게!',
'함께 운동하는것이 좋아요,<br>함께의 가치를 즐겨요!'
],
minds: ['함께하는', '고양된'],
lectureImg: '/images/result_lecture2.png',
},
{
title: '필라테스&요가<br>정적인 수양',
character: '/images/result_character3.png',
results: [
'스스로의 관조를 즐겨요.<br>조용한게 좋아요',
'섬세함이 장점으로<br>신체 하나하나의 통제력을 높히고 싶어요',
'선을 이쁘게 만들고 싶어요<br>거북목 싫어요 ㅠㅠ',
'하루가 너무 지치지만,<br>그래도 지친몸을 다스리는 시간이 필요해요!'
],
minds: ['섬세한', '정적인'],
lectureImg: '/images/result_lecture3.png',
},
{
title: '클라이밍<br>야심찬 정복가',
character: '/images/result_character4.png',
results: [
'전략적으로 계획을 세우는 걸 좋아해요! 지독한 나!',
'목표가 분명하면 몰입도가 올라가요!',
'성취감이 정말 중요해요<br>성공했을 때의 도파민에 취해있어요',
'일할 땐 일하고! 놀 땐 놀고!<br>뭐든 확실한 게 좋아요.'
],
minds: ['야망러', '목표가 분명한'],
lectureImg: '/images/result_lecture4.png',
}
]
export const sports = {
aaaaa : 1,
aaaab : 0,
aaaba : 0,
aaabb : 3,
aabaa : 0,
aabab : 0,
aabba : 1,
aabbb : 0,
abaaa : 1,
abaab : 3,
ababa : 1,
ababb : 1,
abbaa : 3,
abbab : 2,
abbba : 3,
abbbb : 2,
baaaa : 0,
baaab : 1,
baaba : 0,
baabb : 0,
babaa : 0,
babab : 2,
babba : 0,
babbb : 2,
bbaaa : 1,
bbaab : 1,
bbaba : 3,
bbabb : 3,
bbbaa : 2,
bbbab : 2,
bbbba : 2,
bbbbb : 2
}
2) question.js
- EventListener를 이용하여 질문 페이지를 통제
- data.js객체배열에 담아둔 결과를 뽑아와 import → querySelector를 통해 원하는 위치에 뿌려줌
- 특정 초이스를 선택 시 , 해당 값을 변수에 담아 저장 → 문자열로 형성하여 결과문자열을 파라미터로 전송
- 문제 번호에 따라 progressValue의 width값을 변경 → 테스트의 진행상황을 그래프로 표현
import { questions, sports } from './data.js'
// 질문 화면의 각 요소를 찾아요!
const progressValueEl = document.querySelector('.progress .value')
const numberEl = document.querySelector('.number')
const questionEl = document.querySelector('.question')
const choice1El = document.querySelector('.choice1')
const choice2El = document.querySelector('.choice2')
let currentNumber = 0 // 현재 질문 번호
let sport = '' // 선택지 결과
// 화면에 질문을 랜더링하는 함수에요!
function renderQuestion() {
const question = questions[currentNumber]
questionEl.innerHTML = question.question
numberEl.innerHTML = question.number
choice1El.innerHTML = question.choices[0].text
choice2El.innerHTML = question.choices[1].text
progressValueEl.style.width = (currentNumber + 1) * 20 + '%'
}
// 다음 질문으로 넘어가는 함수에요!
function nextQuestion(choiceNumber) {
const question = questions[currentNumber]
// 더 이상 질문이 없으면, 결과 페이지를 보여줘요!
if (currentNumber === questions.length - 1) {
//sport = sport + 'a'
sport = sport + question.choices[choiceNumber].value
showResultPage()
return
}
sport = sport + question.choices[choiceNumber].value
currentNumber = currentNumber + 1
renderQuestion()
}
// 결과 페이지로 이동!
function showResultPage() {
location.href = 'results.html?sport=' + sport
}
// '답변1' 혹은 '답변2'를 클릭했을 때 동작하는 코드에요!
choice1El.addEventListener('click', function () {
nextQuestion(0)
})
choice2El.addEventListener('click', function () {
nextQuestion(1)
})
// 첫 번째 질문을 렌더링해요!
renderQuestion()
2) result.js
- data.js객체배열에 담아둔 결과를 뽑아와 import
- 파라미터의 값을 가져와 Key값으로 이용
→ data.js에서 가져온 객체 中 일치하는 결과 값만 따로 분류
import { results, sports } from './data.js'
// 주소 쿼리스트링에서 sport 값을 가져오기!
const sport = new URLSearchParams(location.search).get('sport')
const result = results[sports[sport]]
// 결과를 출력할 각 요소를 찾아요!
const titleEl = document.querySelector('.page-title')
const characterEl = document.querySelector('.character')
const boxEls = document.querySelectorAll('.box')
const mindEls = document.querySelectorAll('.mind')
const lectureEl = document.querySelector('.lecture')
const lectureImgEl = document.querySelector('.lecture img')
// 각 요소에 내용을 채워넣어요!
titleEl.innerHTML = result.title
characterEl.src = result.character
boxEls.forEach(function (boxEl, index) {
boxEl.innerHTML = result.results[index]
})
mindEls.forEach(function (mindEl, index) {
mindEl.innerHTML = result.minds[index]
})
lectureImgEl.src = result.lectureImg
<참고 사진>