PJ1. jlab_ebook

quokka·2022년 4월 27일
0

Project

목록 보기
6/6
post-thumbnail

🛎  프로젝트 소개

✏️ 이번 프로젝트는 사용자가 로그인을 한 후 소설 페이지가 보여지고, 소설을 보다가 랜덤의 확률로 광고 팝업창이 나오게 된다. 이 광고창은 사용자가 종료할 수 없고, 5초 동안 강제 시청이 된 후 5초가 지나면 자동 종료된다. 광고창이 종료 될때 50%로의 확률로 적립금 모달창이 구현되고, 적립금 모달창도 2초가 지나면 자연 종료되는 모바일 버전의 소설 앱이다.


📆  진행 기간

    1. 08 ~ 2022. 04. 19
      (약 1주간 진행)

👭  팀 구성

Design, Publish : 이나영
Front, Back : 정지후


💻  기술 스택

AI문서, 와이어프레임, Figma, html, Css, Javascript, jQuery, php, PDO, SQL


🌀  구현 기능

  • 소설 페이지 아래로 스크롤 되면서, 무한스크롤로 기능 구현
    • 무한스크롤 될 때 페이지가 변경되면 텍스트의 색상이 변경되도록 구현
  • 모달창 구현
    • 랜덤 확률로 광고 모달창이 보여지고, 사용자가 종료할 수 없도록 5초동안 강제시청 후 강제 종료
    • 포인트 적립금 모달창이 50%로의 확률로 구현 되고 2초 후 강제 종료 되게 구현
  • 디비 모델링
    • 프로젝트에 필요한 데이터를 처음 디비 모델링을 통해서 테이블 작성
  • php , PDO 작성,
    • 모델링한 데이터들을 php, PDO를 통해서 작성
  • aJax
    • 프론트와 백엔드와의 데이터 전송을 aJax로 구현

프로젝트 시작!!!

✏️  처음 프로젝트를 시작하면서 노션에 프로젝트 기간별 상세 업무를 작성해서 sprint형식으로 작성해서 구현 상황들을 매일매일 체크했다.

Project - jlab_eBook

😳 어려웠던 부분

중첩된 기능들을 함수 코드로 구현하는데 꽤 많은 시간이 소요되었다.

무한스크롤링 이벤트가 일어나면서 랜덤 확률료 광고 모달창이 구현되고, 그 모달창은 5초 동안 강제 시청 후 자동 종료 되게 구현해야했다. 또 그 광고창이 종료되면서 50% 확률로 적립금 모달창이 팝업으로 떠오르고, 2초 후 강제 종료. 그 광고 적립창에는 사용자에게 적립된 적립금과 이름, 총 적립금을 보여 줘야 했다. 그 부분을 php PDO로 작성하는데 오류를 접근하는데도 꽤 애를 먹었고 어려웠던 기억이 많이 남는다. ㅠㅠㅠ

  1. 먼저 무한스크롤링 이벤트에 대한 코드다.
// 스크롤링 이벤트를 구현하는데 필요한 것들을 변수로 선언

let scroll_event_flag = 10; //스크롤 이벤트를 발생시킬 임의의 기준 값
let body_height = document.body.offsetHeight; //현재 문서의 총 높이
let scroll_observe_start = false; //스크롤 이벤트 활성화 여부 (스크롤이 발생하지 않는 컨텐츠를 고려)
let is_modal_show = false; //모달창 중복출력 방지용 플래그 값
const random_color = ['00FF7F', '	006400', '7CFC00', 'FF4500', 'FF00FF','00FFFF', 'FFFF00', '0000FF', 'FF0000'];

// 기본적으로 소설 텍스트 1페이지가 보여지도록 구현한 코드 
$(document).ready(function(){
    get_content(1);
  })

//ajax를 통해서 json파일을 불러오도록 구현
  function get_content(page){
    $.ajax({
      url: "./resource/json/data.json",
      dataType: "json",
      success: function(res){
        // 인자값으로 받은 페이지 정보와 각 json객체가 보유한 id와 맵핑
        $("#content_area").append(res.data[page-1].text);
        // json 데이터 중 소설 내용 Dom객체 바인딩 이후 문서의 총 높이 파악 후 변수에 할당
        body_height= document.body.offsetHeight;
        $("#page_num").val(page);
        $('.av_modal').css('height' , body_height); //모달 백그라운드 높이값도 현재 문서 총 높이와 동일하게 설정
        scroll_observe_start = true;
      }
    });
  }

// 윈도우 스크롤 이벤트
  $(window).scroll(function(){
    let down_position = $("#scroll_page").offset().top; 
    //스크롤 이동시 작동코드 (scroll_observe_start가 true이고 현재 스크롤위치가 400px이상(임의 초기 값) 일때부터)
    if(scroll_observe_start && $(this).scrollTop() >= 800){
      let now_scroll_position = $(this).scrollTop();
      if(now_scroll_position%scroll_event_flag == 1){ // 현재 스크롤위치에서 위에서 임의로 설정한 기준치를 나누었을 떄 나머지가 1로 떨어지는 경우(임의설정)에만 모달이벤트 실행 
        // make_modal();
      }
    }
      if($(this).scrollTop() >= body_height-screen.height) {
        let next_page = Number($("#page_num").val())+1 
        alert('next page : '+ next_page);
        get_content(next_page);
        $('#content_area').css("color", "#" + random_color[Math.floor(Math.random() * random_color.length)]);
        make_modal(); //페이지 전환에 따른 광고 모달창 띄우기
      }
  });

👉  이 코드들은 전부 나 혼자 로직을 구현한 것이 아니라, 많이 물어봤고, 원격으로 코드 알려주시는 걸 보면서 이해했던 코드이다. 무한 스크롤링을 구현하는데 하단부의 지정된 값에 들어가면 다음 페이지가 자동으로 넘어가는 형식으로 구현했다.

  • 스크롤을 발생시킬 값
  • 현재 문서의 총 높이 값 - 현재 보여지는 문서의 값
  • Number() 숫자로 변경해주는 메소드
  1. 모달창 (광고, 포인트 적립금)
function make_modal() {
    if(!is_modal_show){
      const result = Math.floor(Math.random() * videos.length);
      let adv_link = videos[result];
      // console.log('make_modal : ' + adv_link)
      $("#modal_video").attr('src', adv_link);
      $("#modal_video").css('width', '280px');
      $("#modal_video").css('height', '400px');

      // modal_call -> 모달 실행해 5초동안 그리고 꺼져.
      control_modal('ad_modal', 5000);
    } else if (!is_modal_show) {
      $('body').css('overflow-y','auto');
    }
  };
  
  // 공통 모달(광고, 적립금 모달)
  function control_modal(selectorClass, close_duration){
    if(selectorClass == 'ad_modal'){
      if(Math.floor(Math.random()* 10) < 5){ //위 조건을 모두 충족한다해도 50%확률로 다시 검사하여 출력여부 결정 
        $("."+selectorClass).fadeIn();
      }
    }else{
      $("."+selectorClass).fadeIn();
    }
    is_modal_show = true;
    $('body').css('overflow-y','hidden');
    setTimeout(function(){
      $('body').css('overflow-y','auto');
        $("."+selectorClass).fadeOut();
        is_modal_show = false;
        if(selectorClass == 'ad_modal'){
          emoney_check();
        }
      }, close_duration)
    }

// 포인트 적립금 모달창 
function emoney_check(){
    // 50% 확률로 지급 여부결정 
    let able_update = Math.floor(Math.random() * 10) < 5;
    let user_id = 1; //적립할 대상 회원의 고유 아이디 고정
    let value = 500; //적립금액 고정
    if(able_update){
      insert_emoney(user_id, value);
    }else{
    } 
  }

👉  처음 광고 모달창을 구현하는데 까지는 함수를 짰었다. 그런데 포인트 적립금 모달과 광고 모달을 공통 함수로 작성하는 곳에서 헷갈리고 어려움이 있었다. 반복되는 로직 이였으므로 공통 함수로 빼고, 이것이 코드의 가독성과 단순함으로서 좋은 코드를 작성할 수 있는 방법이라는 것을 알게 되었다.


✏️  php PDO

이번 프로젝트에서 처음으로 백엔드 파트를 진행해보았다.

디비 모델링, 데이터를 생성하는것, 백엔드에서 어떤식으로 코드를 보내주는지도 처음으로 알게 되었다. 😂

먼저 php는 프론트와, 백엔드 두개의 영역을 하나의 언어로 모두 다 만들 수 있는 언어라는 것을 알게 되었다. 이 php에서 PDO라는 여러 데이터베이스를 제어하는 방법을 표준화시킨 것으로 아직도 낯설고 생소하지만 계속 공부 중에 있다.

일부 간단한 login.php, 로그인시에 php문서를 정리해보았다.

<?php
include_once('../common.php');

// ex) 조회의 경우 GET요청만 허용하고 나머지는 POST만 허용하기로 하였을 때
$table_name = 'db_user'; //필수적인것은 아니나 오타, 기타 이슈 발생 예방 차원에서 테이블 네임을 글로벌 변수에 담아 사용
$query = 'SELECT * FROM '.$table_name.' WHERE email = "'.$_POST['email'].'" AND name = "'.$_POST['name'].'" AND pwd = "'.$_POST['pwd'].'"';   //띄어쓰기 주의 
$stmt = $db->query($query);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if (isset($result)) {
  $code = 200;
  session_start();
  if ($_SESSION['name'] = $result['name']) {
    $message = "로그인에 성공하셨습니다.";
    header('location: http://combinedev.cafe24.com/jlab_eBook/novel.html');
  }
}

// JSON 응답할때 객체 형태로 클라이언트측에 
echo json_encode(array(
  'code' => $code,
  'message' => $message,
  'result' => $result
)); 

?>
  • SELECT FROM = 어디로부터 조회하다.
    • (아스타) = 전체 데이터를 의미한다.
  • WHERE = 어디에서 (email이라는 위치를 표시해준다)
  • dbquery(db→query(query) = 데이터를 읽어오는 쿼리 실행시, 결과 객체를 반환 해준다(입력, 수정 쿼리 실행시에 성공여부에 따라 true, false로 반환)
  • fetch(PDO::FETCH_ASSOC) 결과를 반환해준다(key값으로 접근 가능하도록 해준다)
    • fetchAll(PDO::FETCH_ASSOC) 일 경우에는 결과를 배열로 한번에 전부 반환해준다.
  • isset() = 변수가 있는지, 없는지 확인하는 함수
  • Sessiont_start() = 클라이언트에 값을 저장하지 않고 서버쪽에 값을 저장, 즉 사용자의 값을 서버에 저장해주는 역할

☀️  프로젝트를 마무리하며

📌  아쉬웠던 점

  • 개인적으로 많은 공부가 필요하고 오류가 났을 때 당황하지 않고 침착하게 오류 메세지를 분석하고 그 오류를 해결 할 수 있는 능력을 키워야겠다는 생각이 많이 들었었다.
  • PDO, php라는 처음 써본 언어에 대해서 그 언어를 조금 더 빠르게 숙지할 수 있고 빠르게 코드를 응용해 볼 수 있는 공부를 해야겠다는 생각이 들었다.
  • 코드를 짤때도 무조건적으로 바로 찾아보고 힌트를 얻고 이런 것을 반복하기 보다는 처음에는 조금 맨 땅에 스스로 로직을 생각해보고 이 로직을 어떻게 코드화 할 수 있을지에 대한 생각을 해야겠다 라는 생각이 많이 들었다.

💛  첫 실무 협업 프로젝트이다보니, 설렘도 컸고, 열정도 더 높았던것 같다. 하지만 아직은 그 열정에 비해 나의 실력이 많이 부족하다는 것을 느끼고 더 많이 공부하고 노력해야겠다는 생각이 들었다. 또한 어떻게 하면 좋은 코드, 어떻게 하면 이 오류를 해결 할 수 있을지(침착하게 디버깅하는 방법), 조금 더 구체적으로 생각 해봐야 할 필요가 있다는 것을 알았다.

profile
👩🏻‍💻 매일매일이 기대되는 개발자 ^^

0개의 댓글