기본적인 기능의 앱들을 만들어 보면서 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

홈페이지에서 질문과 답변에 대한 내용을 찾아볼 수 있는 FAQ페이지를 쉽게 찾아 볼 수 있다. 

이는 사용자와의 소통에서 중요한 요소로 작용할 수 있다. 

 

<body>
      <section class="questions">
        <!-- title -->
        <div class="title">
          <h2>general questions</h2>
        </div>
        <!-- questions -->
        <div class="section-center">
          <!-- single question -->
          <article class="question">
            <!-- question title -->
            <div class="question-title">
              <p>do you accept all major credit cards?</p>
              <button type="button" class="question-btn">
                <span class="plus-icon">
                  <i class="far fa-plus-square"></i>
                </span>
                <span class="minus-icon">
                  <i class="far fa-minus-square"></i>
                </span>
              </button>
            </div>
            <!-- question text -->
            <div class="question-text">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est
                dolore illo dolores quia nemo doloribus quaerat, magni numquam
                repellat reprehenderit.
              </p>
            </div>
          </article>
          <!-- end of single question -->
          <!-- single question -->
          <article class="question">
            <!-- question title -->
            <div class="question-title">
              <p>do you suppport local farmers?</p>
              <button type="button" class="question-btn">
                <span class="plus-icon">
                  <i class="far fa-plus-square"></i>
                </span>
                <span class="minus-icon">
                  <i class="far fa-minus-square"></i>
                </span>
              </button>
            </div>
            <!-- question text -->
            <div class="question-text">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est
                dolore illo dolores quia nemo doloribus quaerat, magni numquam
                repellat reprehenderit.
              </p>
            </div>
          </article>
          <!-- end of single question -->
          <!-- single question -->
          <article class="question">
            <!-- question title -->
            <div class="question-title">
              <p>do you use organic ingredients?</p>
              <!-- button -->
              <button type="button" class="question-btn">
                <span class="plus-icon">
                  <i class="far fa-plus-square"></i>
                </span>
                <span class="minus-icon">
                  <i class="far fa-minus-square"></i>
                </span>
              </button>
            </div>
            <!-- question text -->
            <div class="question-text">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est
                dolore illo dolores quia nemo doloribus quaerat, magni numquam
                repellat reprehenderit.
              </p>
            </div>
          </article>
          <!-- end of single question -->
      </section>
    </main>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>

이 <body>에 해당하는 이 부분은 실질적인 질문과 답변의 UI를 보여주는 부분이다. 

 

JS

1. 모든 질문 선택

const questions = document.querySelectorAll(".question");

- .question클래스를 가진 모든 요소를 선택한다. 

 

2. 각 질문 순회

questions.forEach(function (question) {
  const btn = question.querySelector(".question-btn");
  // console.log(btn);

  btn.addEventListener("click", function () {
    // console.log(question);

    questions.forEach(function (item) {
      if (item !== question) {
        item.classList.remove("show-text");
      }
    });

    question.classList.toggle("show-text");
  });
});

- forEach매서드는 questions노드 리스트의 각 요소를 순회한다. 

- 각 질문에 대해서 question.querySelector(".question-btn")을 사용하여 내부의 버튼을 찾는다.

 

3. 이벤트 리스너 추가

btn.addEventListener("click", function () { ... });

- 버튼에 'click' 이벤트를 추가한다. 

 

4. 다른 질문 닫기 

questions.forEach(function (item) {
  if (item !== question) {
    item.classList.remove("show-text");
  }
});

- 버튼이 클릭되면, 먼저 모든 질문을 다시 순회합니다

- 루프 내 현재 항목이 클릭된 질문이 아닌 경우, 해당 항목에서 .show-text클래스를 제거한다. 

 

5. 클릭된 질문 전환 

question.classList.toggle("show-text");

- 마지막으로 스크립트는 클릭된 질문에 .show-text클래스를 전환하여 텍스트를 보이거나 숨긴다. 

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

[JS] To do List 만들기 !  (0) 2024.09.05
[JS]날씨앱을 만들어 보자  (2) 2024.09.04
[JS]modal만들기  (0) 2024.06.23
[JS] 사이드 바 만들기  (1) 2024.06.16
[JS] 반응형 네비게이션바  (0) 2024.06.09

모달창이란?

컴퓨터 프로그램에서 사용되는 일종의 창으로, 사용자가 이 창을 닫기 전까지 다른 창과 상호작용할 수 없게 만듭니다. 일반적으로 중요한 정보를 표시하거나 사용자로부터 특정 입력을 받기 위해 사용됩니다. 예를 들어, 확인 대화 상자, 경고 메시지, 또는 로그인 창 등이 모달 창의 예입니다.

 

index.html

<body>
    <!-- hero -->
    <header class="hero">
      <div class="banner">
        <h1>modal project</h1>
        <button class="btn modal-btn">
          open modal
        </button>
      </div>
    </header>
    <!-- modal -->
    <div class="modal-overlay">
      <div class="modal-container">
        <h3>modal content</h3>
        <button class="close-btn"><i class="fas fa-times"></i></button>
      </div>
    </div>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>

index에서 body에 해당하는 부분의 코드이다. 

hero에 해당하는 부분은 모달 버튼을 눌러지기 이전의 기본 화면에 해당한다. 

그리고 modal에 해당하는 부분이 버튼을 눌렀을 때 화면이 펼쳐 지는 부분이다. 

 

JS

 

1. 선택자 입력

각각의 클래스에 선택자를 입력한다.

const modalBtn = document.querySelector(".modal-btn");
const modal = document.querySelector(".modal-overlay");
const closeBtn = document.querySelector(".close-btn");

 

2. 이벤트 할당 

modalBtn.addEventListener("click", function () {
  modal.classList.add("open-modal");
});
closeBtn.addEventListener("click", function () {
  modal.classList.remove("open-modal");
});

- modalBtn에 "click"이 발생하게 되면 modal의 클래스인 .open-modal이 추가되고

- closeBtn에 "click"이 발생하게 되면 제거된다

 

사실 버튼을 통해 창을 발생시키고 사라지게 하는 매우 간단한 실습이다. 

 

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

[JS]날씨앱을 만들어 보자  (2) 2024.09.04
[JS]FAQ만들기  (0) 2024.06.24
[JS] 사이드 바 만들기  (1) 2024.06.16
[JS] 반응형 네비게이션바  (0) 2024.06.09
[JS] Review Carousel 리뷰캐러셀  (1) 2024.06.08

지난 강의에서는 반응형 화면에서 사이즈가 줄어들었을 때 원래 있던 메뉴들이 사라지고

토글버튼이 생기면서 그 버튼을 누르면 아래로 네비게이션 바가 만들어지는 프로젝트를 진행했다. 

 

이번에는 햄버거 버튼을 누르면 사이드 바가 생성되는 비슷한 프로젝트를 진행해본다. 

 

HTML

완성된 index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Sidebar</title>
    <!-- font-awesome -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
    />

    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <button class="sidebar-toggle">
      <i class="fas fa-bars"></i>
    </button>
    <aside class="sidebar">
      <div class="sidebar-header">
        <img src="logo.svg" class="logo" alt="" />
        <button class="close-btn"><i class="fas fa-times"></i></button>
      </div>
      <!-- links -->
      <ul class="links">
        <li>
          <a href="index.html">home</a>
        </li>
        <li>
          <a href="about.html">about</a>
        </li>
        <li>
          <a href="projects.html">projects</a>
        </li>
        <li>
          <a href="contact.html">contact</a>
        </li>
      </ul>
      <!-- social media -->
      <ul class="social-icons">
        <li>
          <a href="https://www.twitter.com">
            <i class="fab fa-facebook"></i>
          </a>
        </li>
        <li>
          <a href="https://www.twitter.com">
            <i class="fab fa-twitter"></i>
          </a>
        </li>
        <li>
          <a href="https://www.twitter.com">
            <i class="fab fa-behance"></i>
          </a>
        </li>
        <li>
          <a href="https://www.twitter.com">
            <i class="fab fa-linkedin"></i>
          </a>
        </li>
        <li>
          <a href="https://www.twitter.com">
            <i class="fab fa-sketch"></i>
          </a>
        </li>
      </ul>
    </aside>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>
</html>

 

이를 통해 오픈되었을 때의 사이드 바 형태가 완성이 된다. 

 

CSS

styles.css

.sidebar-toggle {
  position: fixed;
  top: 2rem;
  right: 3rem;
  font-size: 2rem;
  background: transparent;
  border-color: transparent;
  color: var(--clr-primary-5);
  transition: var(--transition);
  cursor: pointer;
  animation: bounce 2s ease-in-out infinite;
}
.sidebar-toggle:hover {
  color: var(--clr-primary-7);
}
@keyframes bounce {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(1);
  }
}

.sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.5rem;
}
.close-btn {
  font-size: 1.75rem;
  background: transparent;
  border-color: transparent;
  color: var(--clr-primary-5);
  transition: var(--transition);
  cursor: pointer;
  color: var(--clr-red-dark);
}
.close-btn:hover {
  color: var(--clr-red-light);
  transform: rotate(360deg);
}
.logo {
  justify-self: center;
  height: 40px;
}

.links a {
  display: block;
  font-size: 1.5rem;
  text-transform: capitalize;
  padding: 1rem 1.5rem;
  color: var(--clr-grey-5);
  transition: var(--transition);
}
.links a:hover {
  background: var(--clr-primary-8);
  color: var(--clr-primary-5);
  padding-left: 1.75rem;
}
.social-icons {
  justify-self: center;
  display: flex;
  padding-bottom: 2rem;
}
.social-icons a {
  font-size: 1.5rem;
  margin: 0 0.5rem;
  color: var(--clr-primary-5);
  transition: var(--transition);
}
.social-icons a:hover {
  color: var(--clr-primary-1);
}

.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--clr-white);
  display: grid;
  grid-template-rows: auto 1fr auto;
  row-gap: 1rem;
  box-shadow: var(--clr-red-dark);
  transition: var(--transition);
  transform: translate(-100%);
}
.show-sidebar {
  transform: translate(0);
}
@media screen and (min-width: 676px) {
  .sidebar {
    width: 400px;
  }
}

 

호버 효과 

.sidebar-toggle:hover

 

호버 시 텍스트 색상이 다른 CSS 변수로 변경되는 속성이다.

color: var(--clr-primary-5); --> color:var(--clr-primary-7);

 

애니메이션

animation: bounce 2s ease-in-out infinite;

 

animation속성은 애니메이션을 2초 동안 부드럽게 시작하고 끝나게 하며 무한반복하도록 적용한다. 

 

키프레임

@keyframes bounce

bounce 키프레임은 버튼의 크기 변화를 정의한다.

버튼은 원래 크기에서 시작하여 애니메이션 중간에 1.5배로 커졌다가 다시 원래 크기로 돌아오게 한다. 

 

Javascript

app.js

// 사이드바 토글 버튼, 닫기 버튼, 사이드바 요소를 선택합니다.
const toggleBtn = document.querySelector(".sidebar-toggle");
const closeBtn = document.querySelector(".close-btn");
const sidebar = document.querySelector(".sidebar");

// 사이드바 토글 버튼에 클릭 이벤트 리스너를 추가합니다.
toggleBtn.addEventListener("click", function () {
  // 사이드바의 클래스 목록에 "show-sidebar" 클래스가 있는지 확인하고,
  // 있으면 제거하고, 없으면 추가하는 토글 기능을 수행합니다.
  sidebar.classList.toggle("show-sidebar");
});

// 닫기 버튼에 클릭 이벤트 리스너를 추가합니다.
closeBtn.addEventListener("click", function () {
  // 사이드바의 클래스 목록에서 "show-sidebar" 클래스를 제거합니다.
  sidebar.classList.remove("show-sidebar");
});

 

1. 요소 선택

toggleBtn: .sidebar-toggle클래스를 가진 요소를 선택한다. 이 버튼은 사이드 바를 열거나 닫는 역할을 한다. 

closeBtn: .close-btn클래스를 가진 요소를 선택한다. 이 버튼은 사이드바를 닫는 역할을 한다. 

sidebar: .sidebar클래스를 가진 요소를 선택한다. 이 요소는 실제 사이드 바이다. 

 

2. 토글 버튼 클릭 이벤트 

toggleBtn에 클릭 이벤트 리스너를 추가한다. 클릭시 sidebar요소의 클래스 목록 중에서 show-sidebar클래스가 있는지를 확인한다. 

classList.toggle메서드는 클래스가 있으면 제거하고 없으면 추가하는 기능을한다. 

 

3. 닫기 버튼 클릭 이벤트 

closeBtn에 클릭 이벤트 리스너를 추가한다. 

클릭시, sidebar요소의 클래스 목록에서 show-sidebar클래스를 제거한다. 

 

완성

다음 토글버튼만 있는 기본화면에서 버튼을 누르게 되면 다음과 같이 사이브가 생성된 것을 확인할 수 있다.

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

[JS]FAQ만들기  (0) 2024.06.24
[JS]modal만들기  (0) 2024.06.23
[JS] 반응형 네비게이션바  (0) 2024.06.09
[JS] Review Carousel 리뷰캐러셀  (1) 2024.06.08
[JS] Counter 만들기  (1) 2024.06.08

이번 예제는 반응형 네비게이션 바입니다. 

 

먼저 html 파일입니다. 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Navbar</title>
    <!-- font-awesome -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
    />

    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <nav>
      <div class="nav-center">
        <!-- nav header -->
        <div class="nav-header">
          <img src="./logo.svg" class="logo" alt="logo" />
          <button class="nav-toggle">
            <i class="fas fa-bars"></i>
          </button>
        </div>
        <!-- links -->
        <ul class="links">
          <li>
            <a href="index.html">home</a>
          </li>
          <li>
            <a href="about.html">about</a>
          </li>
          <li>
            <a href="projects.html">projects</a>
          </li>
          <li>
            <a href="contact.html">contact</a>
          </li>
        </ul>
        <!-- social media -->
        <ul class="social-icons">
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-facebook"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-twitter"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-behance"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-linkedin"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-sketch"></i>
            </a>
          </li>
        </ul>
      </div>
    </nav>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>
</html>

 

반응형 웹이란? 

반응형 웹은 다양한 디바이스와 화면 크기에 따라 웹 페이지의 레이아웃과 콘텐츠가 자동으로 최적화 되는 웹 디자인 접근 방식이다. 이를 통해 데스크톱, 테블릿, 스마트폰 등 다양한 환경에서 사용자가 일관된 사용자 경험을 누릴 수 있다.

 

그래서 위의 코드로 완성된 전체 화면은 이런 모습을 가지고 있다. 

 

 

 

 

페이지의 사이즈가 작아짐에 따라서 화면을 구성하는 레이아웃들이 변동된다. 

또한 이에 따라 기존의 메뉴들이 navbar로 변동되었다. 

 

이 네브바를 펼치는 버튼을 햄버거 버튼이라고하는데 

이 버튼을 눌렀을 때 내부에서는 코드가 다음처럼 변하게 된다.

<ul class="links">...</ul>

 

 

<ul class="links">...</ul>

 

<ul class="links">...</ul>

<ul class="show-links">...</ul>

 

CSS파일에서 댜음 코드들을 확인해보자 

 

.links와 .show-links

.links {
  height: 0;
  overflow: hidden;
  transition: var(--transition);
}
.show-links {
  height: 10rem;
}

 

- .links에서는 높이를 0으로 설정하여 화면에 보이지 않도록 하였고 overflow를 hidden으로 하여 요소내부의 콘텐츠가 넘칠 경우에 이를 숨기도록 하였다. 이 hidden설정은 높이가 0일때 콘텐츠가 보이지 않도록 하는데 중요한 역할을 한다. transition: var(--transition);는 css변수를 사용하여 트랜지션효과를 설정한다. --transition변수는 일반적으로 트랜지션 지속 시간과 속성을 정의하는데에 사용된다.

 

- .show-links클래스가 추가되면 높이가 10rem으로 확장된다. 1rem은 루트 요소의 폰트크기를 의미하므로 10rem은 루트요소 폰트 크기의 10배 높이를 의미한다. 

 


그럼 이러한 화면의 동작을 구현하기 위한 javascript이다.

const navToggle = document.querySelector(".nav-toggle");
const links = document.querySelector(".links");

navToggle.addEventListener("click", function () {
  links.classList.toggle("show-links");
});

 

1.선택자 정의

navToggle에는 .nav-toggle을 links에는 .llinks를 querySelector를 이용해서 할당해준다. 

nav-toggle은 navbar를 화면에 표시해주는 햄버거 버튼이다. 

 

2. 이벤트리스너 추가 

navToggle에 이벤트리스너를 추가해서 "click"해주면 함수가 발생하도록 한다. 

 

3. 클래스 토글링

함수에서 link.classList.toggle메서드는 show-links가 요소에 존재하면 제거하고 존재하지 않으면 추가한다. 

이를 통해 사용자가 버튼을 클릭할 때마다 링크 목록의 가시성이 전환된다. 

 

 

 

 

 

 

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

[JS]modal만들기  (0) 2024.06.23
[JS] 사이드 바 만들기  (1) 2024.06.16
[JS] Review Carousel 리뷰캐러셀  (1) 2024.06.08
[JS] Counter 만들기  (1) 2024.06.08
[JS]Color Flipper 만들기2  (2) 2024.06.07

Review Carousel 

세번째 예제는 Review Carousel을 만드는 것이다. 

이 예제에서는 버튼을 누르면 랜덤으로 리뷰를 보여주는 기능을 만들 수 있다.

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Starter</title>
    <!-- font-awesome -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
    />

    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main>
      <section class="container">
        <!-- title -->
        <div class="title">
          <h2>our reviews</h2>
          <div class="underline"></div>
        </div>
        <!-- review -->
        <article class="review">
          <div class="img-container">
            <img src="person-1.jpeg" id="person-img" alt="" />
          </div>
          <h4 id="author">sara jones</h4>
          <p id="job">ux designer</p>
          <p id="info">
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Iusto
            asperiores debitis incidunt, eius earum ipsam cupiditate libero?
            Iste, doloremque nihil?
          </p>
          <!-- prev next buttons-->
          <div class="button-container">
            <button class="prev-btn">
              <i class="fas fa-chevron-left"></i>
            </button>
            <button class="next-btn">
              <i class="fas fa-chevron-right"></i>
            </button>
          </div>
          <!-- random button -->
          <button class="random-btn">surprise me</button>
        </article>
      </section>
    </main>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>
</html>

 

1. 리뷰 객체 배열 설정 

const reviews = [
  {
    id: 1,
    name: 'susan smith',
    job: 'web developer',
    img: 'https://www.course-api.com/images/people/person-1.jpeg',
    text: "I'm baby meggings twee health goth +1. Bicycle rights tumeric chartreuse before they sold out chambray pop-up. Shaman humblebrag pickled coloring book salvia hoodie, cold-pressed four dollar toast everyday carry",
  },
  {
    id: 2,
    name: 'anna johnson',
    job: 'web designer',
    img: 'https://www.course-api.com/images/people/person-2.jpeg',
    text: 'Helvetica artisan kinfolk thundercats lumbersexual blue bottle. Disrupt glossier gastropub deep v vice franzen hell of brooklyn twee enamel pin fashion axe.photo booth jean shorts artisan narwhal.',
  },
  {
    id: 3,
    name: 'peter jones',
    job: 'intern',
    img: 'https://www.course-api.com/images/people/person-4.jpeg',
    text: 'Sriracha literally flexitarian irony, vape marfa unicorn. Glossier tattooed 8-bit, fixie waistcoat offal activated charcoal slow-carb marfa hell of pabst raclette post-ironic jianbing swag.',
  },
  {
    id: 4,
    name: 'bill anderson',
    job: 'the boss',
    img: 'https://www.course-api.com/images/people/person-3.jpeg',
    text: 'Edison bulb put a bird on it humblebrag, marfa pok pok heirloom fashion axe cray stumptown venmo actually seitan. VHS farm-to-table schlitz, edison bulb pop-up 3 wolf moon tote bag street art shabby chic. ',
  },
];

- 배열을 만들어서 이 안에 작성된 리뷰 데이터를 넣는다. 한 사람의 데이터는 딕셔너리 형태로 설정되어 있고 각각 id, name, job, img, text데이터를 추가할 수 있다. 

 

2. 초기 설정 

let currentItem = 0;

첫번째 리뷰를 초기 항목으로 설정하는 과정이다. 

 

3. DOM요소 선택 

const img = document.getElementById('person-img');
const author = document.getElementById('author');
const job = document.getElementById('job');
const info = document.getElementById('info');

const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
const randomBtn = document.querySelector('.random-btn');

- 변수에 getElementById와 querySelector를 이용하여 각각의 맞는 id와 class값을 선택한다. 

 

4. 초기 아이템 로드 

window.addEventListener('DOMContentLoaded', function () {
  const item = reviews[currentItem];
  img.src = item.img;
  author.textContent = item.name;
  job.textContent = item.job;
  info.textContent = item.text;
});

- 여기서 등장하는 window객체란 무엇일까? 

1. 브라우저 안의 모든 요소들이 소속된 객체로, 최상위에 있기 때문에 어디서든 접근이 가능하여 '전역객체'라고 불린다. 

2. 일반적으로 우리가 열고 있는 브라우저의 창을 의미하며 이 창을 제어하는 다양한 메서드를 제공한다. 

- 여기서는 이벤트 리스너를 추가하여 웹페이지가 로드된후 실행할 코드를 지정한다. 

 

- addEventListenr에서 "DOMContentLoaded"이벤트는 초기 html문서가 완전히 로드되고 파싱되었을 때 발생한다.

스타일시트, 이미지, 하위 프레임의 로드가 완료될 때까지 기다리지 않고 페이지의 나머지 리소스가 로드되기 전에 필요한 초기화 작업을 수행할 수 있다. 

 

- const item =reveiws[currentItem];

현재 표시할 리뷰 객체를 가져온다.  reviews 배열에서 currentItem인덱스에 있는 객체를 item변수에 저장한다. currentItem은 현재 선택된 리뷰의 인덱스를 나타내며 초기값은 0이다. 

 

- img.src=item.img;

HTML요소 img의 src속성을 현재 리뷰 객체의 img속성으로 설정한다. 이는 이미지 요소가 해당 URL을 사용하여 이미지를 로드하게 한다. 

 

- author.textContent = item.name;

- job.textContent = item.job;

- info.textContent = item.text;

HTML의 author, job, info속성을 리뷰 객체의 각각 name, job, text속성으로 설정한다. 

 

5. 특정 리뷰를 표시하는 함수 

function showPerson(person) {
  const item = reviews[person];
  img.src = item.img;
  author.textContent = item.name;
  job.textContent = item.job;
  info.textContent = item.text;
}

- 주어진 인덱스에 따라 리뷰를 표시하는 함수

 

6. 다음 및 이전 버튼 

nextBtn.addEventListener('click', function () {
  currentItem++;
  if (currentItem > reviews.length - 1) {
    currentItem = 0;
  }
  showPerson(currentItem);
});

prevBtn.addEventListener('click', function () {
  currentItem--;
  if (currentItem < 0) {
    currentItem = reviews.length - 1;
  }
  showPerson(currentItem);
});

- 다음버튼을 클릭하면 currentItem이 1 씩 증가하게 된다.

- 이전버튼을 클릭하면 currentItem이 1씩 감소하게 된다.

- 만약 마지막 리뷰 인덱스를 넘어서게 되면 첫번째 리뷰로 돌아가게 설정되었다. 

 

7. 랜덤버튼

randomBtn.addEventListener('click', function () {
  currentItem = Math.floor(Math.random() * reviews.length);
  showPerson(currentItem);
});

 

- 무작위 버튼에 이벤트 리스너를 추가하여 무작위로 리뷰가 표시될 수 있도록 한다.

 

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

[JS] 사이드 바 만들기  (1) 2024.06.16
[JS] 반응형 네비게이션바  (0) 2024.06.09
[JS] Counter 만들기  (1) 2024.06.08
[JS]Color Flipper 만들기2  (2) 2024.06.07
[JS] Color Flipper만들기  (0) 2024.06.07

두번째 프로젝트로 Counter를 만드는 프로젝트이다. 

이 프로젝트에서는 표시되는 값이 양수인지 음수인지에 따라서 색이 달라지는 기능을 포함하고 있다. 

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Counter</title>

    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main>
      <div class="container">
        <h1>counter</h1>
        <span id="value">0</span>
        <div class="button-container">
          <button class="btn decrease">decrease</button>
          <button class="btn reset">reset</button>
          <button class="btn increase">increase</button>
        </div>
      </div>
    </main>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>
</html>

 

counter의 경우에는 조건문을 적절하게 활용하면 쉽게 만들 수가 있다. 

1. 초기 카운트 값 설정 

let count = 0;

- count변수를 선언해서 초기값으로 0을 설정해준다. 

- 이 count변수는 현재의 카운트 값을 저장하는 변수이다. 

 

2. 요소선택

const value = document.querySelector("#value");
const btns = document.querySelectorAll(".btn");

- value에는 querySelector를 이용해서 #value인 id값을 할당해준다. 

- btns에는 querySelectorAll을 이용해서 클래스가 btn인 모든 요소를 선택해서 배열형태로 저장한다. 

 

3. 각 버튼에 이벤트 리스너 추가 

btns.forEach(function (btn) {
  btn.addEventListener("click", function (e) {
    const styles = e.currentTarget.classList;
    if (styles.contains("decrease")) {
      count--;
    } else if (styles.contains("increase")) {
      count++;
    } else {
      count = 0;
    }

    if (count > 0) {
      value.style.color = "green";
    }
    if (count < 0) {
      value.style.color = "red";
    }
    if (count === 0) {
      value.style.color = "#222";
    }
    value.textContent = count;
  });
});

3.1 각 버튼에 대한 'forEach'루프 

- forEach메서드는 for 반복문과는 다른 방식으로 함수를 사용한다. 

- forEach메서드는 매개변수와 함께 배열의 각 요소에 적용하게 될 콜백함수를 전달한다. 

  • Current Value (명명된 매개변수) - 처리할 현재 요소
  • Index (선택적 매개변수) - 처리할 현재 요소의 인덱스
  • Array (선택적 매개변수) - forEach 메서드를 호출한 배열

- forEach메서드를 사용해 배열을 순회하기위해서는 콜백함수 또는 익명함수가 필요하다.

const numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(number) {
    console.log(number);
});

 

- Index 

numbers.forEach((number, index) => {
    console.log('Index: ' + index + ' Value: ' + number);
});

 

- Array

numbers.forEach((number, index, array) => {
    console.log(array);
});

 

3.2 클릭 이벤트 리스너 추가 

btn.addEventListener("click", function (e) {

- "click" 이벤트가 발생되면 매개변수 e가 전달된다. 

const styles = e.currentTarget.classList;

- 전달된 매개변수에서 e.currentTarget은 이벤트가 발생한 요소를 가리킨다. (클릭된 버튼) 

- 그리고 해당 요소의 클래스 목록을 반환한다. 

 

3.3 클래스에 따라 카운트 값 변경 

if (styles.contains("decrease")) {
  count--;
} else if (styles.contains("increase")) {
  count++;
} else {
  count = 0;
}

- decrease가 포함되면 감소 

- increase가 포함되면 증가 

- 그렇지 않은 경우 (이 예제에서는 reset으로 설정되어 있다) count를 0으로 설정 

 

3.4 카운트 값에 따라 텍스트 색상 변경 

if (count > 0) {
  value.style.color = "green";
}
if (count < 0) {
  value.style.color = "red";
}
if (count === 0) {
  value.style.color = "#222";
}

- count의 값에 따라서 value요소의 텍스트 색상을 변경한다. 

 

3.5 현재의 카운트 값을 표시

value.textContent = count;

value요소의 텍스트 내용을 현재 count값으로 업데이트 한다. 

 

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

[JS] 반응형 네비게이션바  (0) 2024.06.09
[JS] Review Carousel 리뷰캐러셀  (1) 2024.06.08
[JS]Color Flipper 만들기2  (2) 2024.06.07
[JS] Color Flipper만들기  (0) 2024.06.07
[JS] 시작  (1) 2024.06.07

지난 color flipper만들기 내용보다 조금 더 심화 버전의 내용이 있다. 

 

hex.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Color Flipper || Hex</title>

    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>

  <body>
    <nav>
      <div class="nav-center">
        <h4>color flipper</h4>
        <ul class="nav-links">
          <li><a href="index.html">simple</a></li>
          <li><a href="hex.html">hex</a></li>
        </ul>
      </div>
    </nav>
    <main>
      <div class="container">
        <h2>background color : <span class="color">#f1f5f8</span></h2>
        <button class="btn btn-hero" id="btn">click me</button>
      </div>
    </main>
    <!-- javascript -->
    <script src="hex.js"></script>
  </body>
</html>

html파일의 내용은 hex인것만 빼고는 딱히 달라진건 없다. 

 

이전의 내용에서는 color라는 배열 안에서 random으로 색을 지정 했었다. 

이번에는 16진수로 색을 표현하는 방식을 hex 색지정 방식인데 이를 통해서 더 다양한 색을 랜덤으로 구현해 볼 수 있다. 

 

전체적인 코드는 아까와 거의 비슷하고 hex라는 랜덤배열과 이벤트리스너에서 함수가 작동하는 방식이 달라졌다. 

 

1. 배열설정

const hex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"];

- 16진수를 이루는 16자리의 문자를 hex에 담아준다. 

 

2. 이벤트 리스너 설정 

btn.addEventListener("click", function () {
  let hexColor = "#";
  for (let i = 0; i < 6; i++) {
    hexColor += hex[getRandomNumber()];
  }

- hexColor라는 변수를 선언하고 초깃값으로 "# "으로 설정한다. 

- 모든 16진수의 색상값은 '#'으로 시작하며 이 변수를 기반으로 색상코드를 생성할 것이다. 

for (let i = 0; i < 6; i++) {
    hexColor += hex[getRandomNumber()];
  }

 

- 자바스크립트의 반복문을 사용한다. 

- for 루프는 조건에 의하여 6번 반복된다. 이는 16진수의 색상코드가 6자리로 이루어져 있기 때문이다. 예를 들어 #ff5733, #12ab9c.

- 각 반복마다 getRandomNumber를 호출하여 0부터 hex길이 미만에 해당하는 숫자를 생성한다.

- hexColor += hex[getRandomRandomNumber()]는 hexColor에  무작위로 선택된 16진수의 문자를 추가하여 랜덤 색상을 만들어낸다.

 

이후의 과정은 이전의 내용과 동일하다. 

 

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

[JS] Review Carousel 리뷰캐러셀  (1) 2024.06.08
[JS] Counter 만들기  (1) 2024.06.08
[JS] Color Flipper만들기  (0) 2024.06.07
[JS] 시작  (1) 2024.06.07
자료구조와 자료형  (0) 2024.04.14

+ Recent posts