우리가 가끔 패스워드를 비밀번호찾기를 하게되는데 

그때 임시비밀번호로 프로그램에서 만들어주는 비밀번호를 이메일로 받게되는 경우가 있었다

 

그때의 기억을 되살려 보며 랜덤패스워드를 만들어보자 

 

 

이 프로그램은 '비밀번호 생성하기' 버튼을 누르게 되면 

영어 소문자, 대문자, 숫자, 특수문자를 조합하여 12자리의 랜덤비밀번호를 생성한다

 

그리고 옆의 복사하기 버튼을 누르면 해당 비밀번호를 복사할 수 있다


코드 설명 

 

변수 설정 

const passwordBox = document.getElementById("password");
const length = 12;

const upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const lowerCase = "abcdefghijklmnopqrstuvwxyz";
const number = "0123456789";
const symbol = "@#$%^&*()_+~|}{></-=";

const allChars = upperCase + lowerCase + number + symbol;

 

-  passwordBox는 id가 password인 요소를 선택하여 참조하는 변수이다. 이 요소는 사용자가 생성된 비밀번호를 볼 수 있는 input box이다. 

- length는 생성되는 비밀번호의 길이를 나타내는 변수로 여기서는 12자로 설정되어 있다. 

 

- 아래 uppserCase는 대문자, lowerCase는 소문자, number는 숫자, symbol은 특수문자 문자열을 담는 변수이다. 이것들은 랜덤비밀번호를 생성할 때 랜덤하게 선택하여 생성해서 사용하게 된다. 

 

 

- allChars변수는 대문자, 소문자, 숫자, 특수문자를 모두 포함하는 문자열이다. 비밀번호를 생헝할 때 이 문자열에서 랜덤하게 문자를 선택하게 된다.

 

CreatePassword() 함수 

function createPassword() {
  let password = "";
  password += upperCase[Math.floor(Math.random() * upperCase.length)];
  password += lowerCase[Math.floor(Math.random() * lowerCase.length)];
  password += number[Math.floor(Math.random() * number.length)];
  password += symbol[Math.floor(Math.random() * symbol.length)];

  while (length > password.length) {
    password += allChars[Math.floor(Math.random() * allChars.length)];
  }
  passwordBox.value = password;
}

- 생성하기 버튼을 누르게되면 실행되는 함수이다. 

- password라는 빈 문자열을 초기화하고 대문자, 소문자, 숫자, 특수문자 각각에서 하나씩 랜덤하게 선택해서 password에 추가한다. 이렇게 하면 최소한 하나의 대문자, 소문자, 숫자, 특수문자가 비밀번호에 포함되도록 보장할 수 있다. 

- 이후 while 루프를 사용하여 password의 길이가 length(12)보다 작을 때 까지 allCahrs문자열에서 랜덤하게 문자를 선택해 password에 추가한다. 

- 마지막으로 생성된 비밀번호를 passwordBox입력 상자의 값으로 설정한다. 

 

copyPassword()함수 

function copyPassword() {
  passwordBox.select();
  document.execCommand("copy");
}

이 함수는 생성된 비밀번호를 복사하는 역할을 한다. 

- passwordBox.select()는 passwordBox입력상자의 내용을  선택한다. 

-document.execCommand('copy')는 선택된 내용을 클립보드로 복사한다. 사용자는 이제 이 비밀번호를 다른 곳에 붙여 넣을 수 있게 된다. 

 

끝 

매우 간단한 프로그램이다! 

다만, 이렇게 생성된 문자열의 경우 앞의 4자리가 대문자, 소문자, 숫자, 특수문자로 고정된 위치에 만들어 진다는 점이 매력이 떨어지는 것 같다. 모든 문자들이 포함되면서 랜덤하게 생성될 수 있는 알고리즘에 대해서 고려해 봐야될 거 같다. 

 

'개발 > javascript' 카테고리의 다른 글

[JS]나이 계산기  (0) 2024.09.10
[JS] 노트 앱 만들기!  (0) 2024.09.09
[JS]퀴즈앱 (quiz app)만들기  (0) 2024.09.06
[JS] To do List 만들기 !  (0) 2024.09.05
[JS]날씨앱을 만들어 보자  (2) 2024.09.04

이번에 만들어 볼 앱은 퀴즈앱이다

여기서 만드는 퀴즈는 주관식은 아니고 객관식에 해당하는 퀴즈를 만든다. 

 

해당 문제에서 퀴즈를 맞추면 문항이 초록색으로 표시되어 다음문제로 넘어가고 

퀴즈를 틀리면 선택한 문항은 빨간색으로 표시되면 동시에 정답인 문항은 초록색으로 표시된다. 

그리고 마지막으로 문제들 중에서 몇 개를 맞추었는지도 나타나게 되는 아주아주 간단하고 쉬운 앱이다.

 

1. 문제 형태

 

2. 정답에 틀렸을 때
3. 정답을 맞췄을 때
4. 최종 점수!


1. 문제 생성 

먼저 어떤 질문들이 들어 가야 할지에 대한 내용을 생성해야한다. 

question이라는 변수를 만들어서 이안에 배열 형태로 질문과 정답을 만든다. 그리고 정답 부분에는 text와 correct로 나누어 해당 질문에 대한 정답인지 아닌지를 판단하게 한다. 

const questions = [
  {
    question: "한입 베어 문 사과는?",
    answers: [
      { text: "사과", correct: false },
      { text: "파인애플", correct: true },
      { text: "오렌지", correct: false },
      { text: "복숭아", correct: false },
    ],
  },
  {
    question: "프론트엔드에서 가장 점유율이 높은 라이브러리는? ",
    answers: [
      { text: "Vue.js", correct: false },
      { text: "Svelte", correct: false },
      { text: "typescript", correct: false },
      { text: "React.js", correct: true },
    ],
  },
  {
    question: "저녁 머 먹지?",
    answers: [
      { text: "김밥", correct: false },
      { text: "햄버거 ", correct: false },
      { text: "우동 ", correct: false },
      { text: "몰라", correct: true },
    ],
  },
];

 

2. DOM

그리고 ID값을 받아서 dom을 만든다.

const questionElement = document.getElementById("question");
const answerButtons = document.getElementById("answer-buttons");
const nextButton = document.getElementById("next-btn");

 

3. 변수 초기화 

currentQuestionIndex는 현재 표시되고 있는 질문의 인덱스를 생성하고 

score는 사용자의 점수를 저장한다. 

let currentQuestionIndex = 0;
let score = 0;

 

4. StartQuiz() 함수 

이 함수는 퀴즈가 시작할 때 호출된다. 

currentQuestionIndex와 Score를 초기화 하고, Next버튼의 텍스트를 Next로 설정한 후 showQuestion()함수를 통해 첫번째 질문을 화면에 표시한다. 

function startQuiz() {
  currentQuestionIndex = 0;
  score = 0;
  nextButton.innerHTML = "Next";
  showQuestion();
}

5. ShowQuestion()함수 

이 함수는 현재 질문과 선택지를 화면에 표시하는 역할을 한다. resetState()를 호출해서 이전 질문의 상태를 초기화하고 현재 질문과 선택지를 화면에 표시하고 각 선택지 버튼을 동적으로 생성하여 answerButtons요소에 추가한다. 

 

정답일 경우에는 button.dataset.correct 에 correct값을 설정한다. 

각 버튼에 selectAnswer함수가 클릭이벤트로 연결된다. 

function showQuestion() {
  resetState();
  let currentQuestion = questions[currentQuestionIndex];
  let questionNo = currentQuestionIndex + 1;
  questionElement.innerHTML = questionNo + ". " + currentQuestion.question;

  currentQuestion.answers.forEach((answer) => {
    const button = document.createElement("button");
    button.innerHTML = answer.text;
    button.classList.add("btn");
    answerButtons.appendChild(button);
    if (answer.correct) {
      button.dataset.correct = answer.correct;
    }
    button.addEventListener("click", selectAnswer);
  });
}

 

6. resetState함수 

이 함수는 새로운 질문을 표시하기 전에 이전 질문과 선택지 버튼들을 초기화한다 .

Nex버튼을 숨기고 answerButton요소에 있는 모든 버튼을 제거한다. 

function resetState() {
  nextButton.style.display = "none";
  while (answerButtons.firstChild) {
    answerButtons.removeChild(answerButtons.firstChild);
  }
}

 

7. selectAnswer함수 

사용자가 선택지를 클릭했을 때 호출되는 함수이다. 사용자가 선택한 답변이 정답인지 확인하고 정답일 경우 해당 버튼에 correct클래스를 추가하여 스타일을 변경하고 점수를 증가시킨다. 모든 버튼을 비활성화하고 정답버튼을 항상 correct클래스를 추가하여 표시한다. 

Next버튼을 다시표시한다. 

function selectAnswer(e) {
  const selectedBtn = e.target;
  const isCorrect = selectedBtn.dataset.correct === "true";
  if (isCorrect) {
    selectedBtn.classList.add("correct");
    score++;
  } else {
    selectedBtn.classList.add("incorrect");
  }
  Array.from(answerButtons.children).forEach((button) => {
    if (button.dataset.correct === "true") {
      button.classList.add("correct");
    }
    button.disabled = true;
  });
  nextButton.style.display = "block";
}

8. ShowScore() 함수 

퀴즈가 끝났을 때 사용자의 점수를 표시하는 함수이다. 이전 상태를 초기화한 후, 사용자가 획득한 점수를 화면에 표시한다. Next버튼의 텍스트를 play Again으로 변경하고 버튼을 다시 표시한다. 

function showScore() {
  resetState();
  questionElement.innerHTML = `You scored ${score} out of ${questions.length}!`;
  nextButton.innerHTML = "play Again";
  nextButton.style.display = "block";
}

9. HandleNextButton()함수 

next버튼을 클릭했을 때 호출되는 함수이다. currentQuestionIndex를 증가시키고, 남은 질문이 있다면 showQuestion()함수를 호출하여 다음 질문을 표시한다. 모든 질문이 끝났다면 showScore()함수를 호출하여 점수를 표시한다. 

function handleNextButton() {
  currentQuestionIndex++;
  if (currentQuestionIndex < questions.length) {
    showQuestion();
  } else {
    showScore();
  }
}

10. nextButton클릭 이벤트 리스너 

next버튼이 클릭되었을 때 호출되는 이벤트 리스너 이다. 현재 질문이 남아있다면 handleNextButton()을 호출하고 , 그렇지 않다면 퀴즈를 다시 시작하기 위해 startQuiz()함수를 호추한다. 

 

11. 그리고 마직막으로 startQuiz()호출해서 퀴즈가 처음 로드될때 바로 시작하도록 한다. !! 

 

'개발 > javascript' 카테고리의 다른 글

[JS] 노트 앱 만들기!  (0) 2024.09.09
[JS]랜덤 패스워드 생성기!!  (1) 2024.09.09
[JS] To do List 만들기 !  (0) 2024.09.05
[JS]날씨앱을 만들어 보자  (2) 2024.09.04
[JS]FAQ만들기  (0) 2024.06.24

기본적인 기능의 앱들을 만들어 보면서 javascript를 학습하기로 했다. 

그 중에서 첫번째로 날씨앱을 만들어 보았다.

 

이 앱은 검색창에 영어로 도시이름을 검색하면 해당 도시의 날씨와 기타 정보들을 확인 할 수 있는 앱이다. 

 

 

초기화면은 다음과 같이 검색할 수 있는 창과 버튼이 있다. 

 

해당 화면에서 올바른 이름으로 입력을 하게 되면 해당 도시의 정보를 확인 할 수 있지만 이름이 잘못되면 

"Invalid city name"이라는 문장이 나타나게 된다. 

 

자 그럼 제대로 작성하여 확인해보자 

Korea에 대한 날씨, 습도, 풍속을 확인 할 수 있다.


그렇다면 이것은 어떻게 구현하였을까? 

이것은 Open Weather Map API를 사용하여 해당 내용을 구현할 수 있었다. 

const apiUrl = "https://api.openweathermap.org/data/2.5/weather?units=metric&q=";

apiUrl변수는 openweathermap api의 기본 URL을 포함한다. 이 API는 도시이름을 입력 받아서 해당 도시의 날씨정보를 JSON형식으로 변환한다. 또한 units=metric을 통해 온도를 섭씨 단위로 가져오도록 설정하였다. 

async function checkWeather(city) {
  const response = await fetch(apiUrl + city + `&appid=${apiKey}`);

이 checkWeather함수는 비동기 함수로 선언이 되었는데 aysnc 키워드는 해당함수가 비동기 작업이며 await키워드를 사용할 수 있게 한다. city라는 매개변수를 전달하여 이를 url에 연결 할 수 있게 했다. 

 

fetch함수 호출 

fetch함수는 네트워크 요청을 수행하여 리소스를 가져오는 웹 API이다. 이 프로젝트에서는 openweathermapAPI에 요청을 보내 날씨 정보를 가져왔다. 

 

URL예시

만약 도시가 seoul이고 api가 yourapikey로 설정되어 있다면 완성된 URL은 다음과 같이 나타난다.

https://api.openweathermap.org/data/2.5/weather?units=metric&q=Seoul&appid=yourApiKey

 

HTTP요청 및 응답처리 

- fetch(apiUrl + city + &appid=${apiKey})는 이 URL로 GET요청을 보낸다. 

- 이 요청이 처리된 후, 서버는 해당 도시의 날씨 정보를 포함한 JSON데이터로 응답을 보낸다.

 

await의 사용 

await키워드는 fetch함수가 완료될 때까지 기다린 후, 결과를 response변수에 할당한다. 

이 과정에서 함수의 실행은 일시 중단되지만, 전체 프로그램이 멈추는 것은 아니다. 다른 코드가 계속 실행될 수 있고 response가 준비되면 함수는 다시 실행을 이어나간다. 

 

Response객체

response변수는 서버로부터 받은 HTTP응답을 나타내는 객체이다. 이 객체에는 응답상태코드, 응답데이터, 헤더 등이 포함된다. 

- 예를 들어 ,response.status는 응답의 http상태로 코드를 변환한다. 

- 이후 코드에서는 response.json()을 사용해 응답 데이터를 JSON으로 변환한다. 

 

API호출 결과 처리 

if (response.status == 404) {
  document.querySelector(".error").style.display = "block";
  document.querySelector(".weather").style.display = "none";
} else {

API호출이 성공하지 않으면 status==404에러 메세지를 보여준다. 에러가 발생하면 날씨 정보를 숨기고, 에러 메시지를 표시한다. 

호출이 성공하면 날씨 정보를 화면에 표시하고 에러 메시지를 숨긴다. 

 

날씨 정보 화면에 표시

var data = await response.json();
console.log(data);
document.querySelector(".city").innerHTML = data.name;
document.querySelector(".temp").innerHTML = Math.round(data.main.temp) + "°c";
document.querySelector(".humidity").innerHTML = data.main.humidity + "%";
document.querySelector(".wind").innerHTML = data.wind.speed + "km/h";

response.json()으로 응답 데이터를 JSON형식으로 변환한 후 이를 데이터 변수에 저장한다. 

이를 .city .temp .humidity .wind등의 정보를 HTML요소에 표시한다. 

 

날씨 아이콘 

if (data.weather[0].main == "Clouds") {
  weatherIcon.src = "images/clouds.png";
} else if (data.weather[0].main == "Clear") {
  weatherIcon.src = "images/clear.png";
} else if (data.weather[0].main == "Rain") {
  weatherIcon.src = "images/rain.png";
} else if (data.weather[0].main == "Drizzle") {
  weatherIcon.src = "images/drizzle.png";
} else if (data.weather[0].main == "Mist") {
  weatherIcon.src = "images/mist.png";
}

조건문을 사용하여 data.weather[0].main값에 따라 날씨 상태를 확인하고 이에 맞는 이미지 파일을 weather Icon에 설정한다. 

 

이벤트 리스너 추가

searchBtn.addEventListener("click", () => {
  checkWeather(searchBox.value);
});

그리고 사용자가 검색버튼을 클릭하면 checkweather함수가 실행되어 사용자가 입력한 도시의 날씨 정보를 가져온다. 

 

마지막으로 checkWeather();호출! 

'개발 > javascript' 카테고리의 다른 글

[JS]퀴즈앱 (quiz app)만들기  (0) 2024.09.06
[JS] To do List 만들기 !  (0) 2024.09.05
[JS]FAQ만들기  (0) 2024.06.24
[JS]modal만들기  (0) 2024.06.23
[JS] 사이드 바 만들기  (1) 2024.06.16

+ Recent posts