ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이번주 프로젝트 회고 ( 스파르타 내일 배움 캠프 )
    부트캠프 2022. 11. 18. 00:10

    스파르타 내배캠 node.js 본캠이 시작한지 4일차가 되었다.

     

    프로젝트하랴 sql 강의들으랴 진짜 바쁨.....

     

     

    구현 로직 간단 요약

    (일부 함수만 블로그에 적혀있음)

     

    1. 댓글 저장, 삭제

      1) 댓글 텍스트 박스 value의 문자열을 받고, 작성된 시간을 함께 DB에 저장, 고유 번호 부여

      2) 부여된 번호를 매개변수로 선택 댓글 삭제

      3) 페이지 일부의 HTML만 갱신하여 댓글 최신화

     

    2. 말풍선 하나씩 출력 or 스킵해서 전부 출력

      1) 전체 대화내용 문자열에 .split()을 두번 시행하여 문단과 문장을 구분

      2) 사용자가 조작하며 순차적으로 대화내용을 출력하는 기능

      3) 전체 대화내용을 한번에 출력하는 기능

     

    3. 말풍선 출력 시 측면에 현재 or 과거 시간 선택해서 반영

      1) 대화내용 순차 출력 시 현재 시간으로 반영

      2) 대화내용 전체 출력 시 미리 설정된 과거 시간으로 반영

      3) 대화내용 순차 출력 중, 전체 출력 시 마지막 대화내용 기준으로 시간 설정

      4) 댓글은 작성된 시간을 반영

     

     

    얻은것

     

    1. 오류에 대한 약간의 내성

    2. 굶주림

    3. 수면부족

     

     

     

    미니 프로젝트

    개인페이지

     

    팀 소개 페이지. 좌측의 픽토그램을 누르면 탭이 바뀐다

     

    1주차 첫 프로젝트는 간단하게 팀에대해 소개하는 프로젝트를 했다.

     

    대화하는 식으로 구현해보자는 팀원분의 의견을 듣고! 

     

    카톡을 오마쥬해서 만들었다!

     

     

     

    지옥의 CSS..

     

    저 두 페이지 모두 직접 내가 CSS로 작성했다........

    진짜 머리 다빠지는줄알았따

     

    css는 오류발생해서 구글링해도 그 해결법이 안먹는다 ㅋ

    ㅋㅋ

    ㅋㅋㅋ

     

    대충 무작정 모양만 맞춘 노답태그들

     

    기반 제대로 안다지고 야매로 날림공사 했다고 진짜 내코드는 너무 천대받더라

    진짜 안되면 왜 안되는지 이유좀 알려줘..............css야.....................제발

     

    열심히 해서 만들긴 했는데 나도 내가 뭘 배웠는지 모르겠음 그냥 빡침만 ㅡㄴ낌

    저런건 그냥 고수분들이 만든 좋은 css 그냥 복붙해서 쓰는게 현명한듯 하다 ^^.,.,,.,;';[

     

     

    팀원분들께서는 너무 잘만들었다고 칭찬해주시고 프론트 적성 아니냐고 하셨지만

    난 절대 프론트는 너무 복잡하고 못해먹겠다고 다시 한번 깨닫게 되는 좋은 계기가 되었다.

     

     

     

     

    서버 조작

     

    flask를 이용했고, mongoDB로 데이터를 저장했다.

    언어는 python!

     

    서버쪽에서 크게 느꼈던점은 대표적으로 페이지 이동.

     

     

     

    <div class="list" onclick="location.href='individual/p3'">
        <img src="/static/3.png" class="profileImage"> <span class="name"> 신승훈 </span>
    </div>

    탐색기에서 그냥 실행을하면 이렇게 링크에 다른 페이지 경로만 적어줘도 잘 실행이 되지만

    이대로 아무 추가 작업 없이 서버로 올려버리면!

     

    이것에대한 추측으로는

     

    탐색기에서 페이지이동 링크를 실행시키면

    HTML -> HTML

    이렇게 직접 이동이 되는데 반해

     

    서버에서 링크를 실행시키면

    HTML -> 서버 -> HTML

    중간에 서버를 한번 거쳐서 이동을 하는 듯 하다.

     

    그렇기 때문에

    ' -> 서버 -> '

     

    이 과정을 구현해주면 된다!

    @app.route('/introduce')
    def introduceHtml():
        return render_template('introduce.html');
    
    
    @app.route('/more')
    def moreHtml():
        return render_template('more.html');

    방식은 무지 간단

     

    app.py로 들어가서 그냥 @app.route로 뚫어주기만 하면 됨!

     

     

     

     

     

     

    자바스크립트

     

    이쪽은 꽤 재밌는 부분이 많았다.

     

    내가 구현한 대표적 기능이

     

    1. 댓글 저장, 삭제

     

     

    2. 말풍선 하나씩 출력 or 스킵해서 전부 출력

     

    마우스 hover 시 버튼색이 바뀌고 커서는 pointer로 변경

     

     

    3. 말풍선 출력 시 측면에 현재 or 과거 시간 선택해서 반영

     

     

     

     

     

    첫번째로 댓글저장 삭제!

     

    function saveComment(){
    
        if(cnt < talkingBundleList.length){
    
            alert('대화가 모두 끝난 후 전송해주세요.');
    
            return 0;
        }
    
        let comment = $('#comment').val()
    
        let date = new Date();
        let hour = date.getHours();
        let minute = date.getMinutes();
    
        $.ajax({
            type: "POST",
            url: "/p3_comment",
            data: {comment_give: comment, hour_give: hour, minute_give: minute},
            success: function (response) {
    
                console.log(comment);
                console.log(response['msg']);
    
                reloadArea();
    
            }
        })
    }

    대충 이런식..

     

    여긴 골떄리는 reload 문제가 있었다..

     

     

    카톡창 형태의 개인 페이지에 메시지를 전송하면 말풍선을 보내도록 구현을 했는데

     

    빨간 x 버튼(삭제)이나 전송을 누르면 윗부분의 말풍선은 그대로 두고

     

    아래의 방문자가 작성한 말풍선만 리로딩 되도록 구현을 했다.

     

    그런데!

     

     

    말풍선이 씹힌 화면

    삭제나 전송버튼을 누르면 간헐적으로 사용자들이 남긴 말풍선이 표시되지 않는 문제가 발생했다.

     

    function deleteCommentZone(){
        $('#showComments').load(location.href + ' #showComments'); // id값이 showComments인 부분만 리로드
        $('#comment').load(location.href + ' #comment'); // id값이 comment인 부분만 리로드
        $('#comment').value = null;
    }
    
    
    function reloadArea() {
        
        deleteCommentZone(); // 말풍선부분 삭제하는 함수
        getAllComments(); // 말풍선을 DB에서 다 불러와서 표시하는 함수
        
    }

    이 reloadArea() 함수인데,

     

    localhost:5000 에서는 훨씬 적게 발생하고,

    AWS서버에 업로드 한 곳에서는 상당히 자주 발생했었다.

     

     

    추측하는 원인으로는 서버의 데이터 전송 속도 차이가 발생해서..

    말풍선이 먼저 불러와지고 그다음 다시 리로드되어 표시가 안되는게 아닐까 싶어

    ( .load(location.href + '') 메소드는 웬만하면 안쓰는게 좋은듯 )

     

     

    function reloadArea() {
    
        setInterval(deleteCommentZone(), 200);
        setInterval(getAllComments(), 200);
    }

    setInterval로 약간의 지연을 줘봤는데.

    그래도 AWS서버에서 여전히 문제가 발생하더라..

    지연으로 해결되는것 자체도 임시방편이라 해결법은 아니고. (서버속도가 엄청 느리면 어쩔건데?)

     

    뿐만아니라

    javaScript는 지연이 이상하게 구현되서 지연이 되는건지도 모르겠고...

    (함수 사이사이 지연시간이 생기는게 아니라 그냥 지연부터 생기고 모든 함수가 다실행되버리는듯.;.;)

     

    js는 기본적으로 제공되는 sleep()도 없어서 개인적으로 만들어야 한단다

    응 안해

     

     

     

    그래서

    document.getElementById("showComments").innerHTML= "";

    이 메소드로 댓글공간을 지우고 getAllComments(); 를 호출하니, 해결은 되었으나!

    공간이 비워졌다가 서버에서 데이터를 받고 다시 채워지는데까지의 시간이 너무 길어서 웃기게 구현됨.

     

    (갑자기 왜 뜬금없이 JQuery 아니고 DOM? 이냐 하면, 그것은 또 뒤에 스토리가 있다)

     

     

    순차적으로 saveComments()의 POST호출 후 데이터 받고, getAllComments()의 GET호출 후 데이터 받는 과정

    그래서 서버의 데이터 송수신 시간과 브라우저의 갱신시간을 멍떄리며 보다 해결을 본것이다!!!!!!!!

     

    말풍선 데이터를 먼저 서버에서 받아온 뒤에, 말풍선 공간을 제거하고 말풍선을 표시하면

    중간에 데이터 송수신 과정이 없어서 자연스럽게 구현이됨!!!!!!

     

    (기존)
    1. 댓글 저장 or 삭제 (POST)
    2. 댓글 공간을 싹 지움

    3. DB에서 댓글을 전부 불러옴 (GET)

    4. HTML에 불러온 댓글 표시

     

    (해결 후)

    1. 댓글 저장 or 삭제 (POST)

    2. DB에서 댓글을 전부 불러옴(GET)

    3. 댓글 공간을 싹 지움

    4. HTML에 불러온 댓글 표시

     

     

    기존의 방식은 실제 가시적으로 표현되는 2번 4번 과정 사이에 3번 GET이 포함되어

    필연적으로 서버응답시간 만큼의 지연이 발생! ( 부자연스러움 )

     

    변경된 방식은 실제 가시적으로 표현되는 3번 4번 과정 사이의 지연이 없음!!!!!!! (자연스러움)

     

     

     

     

     

     

     

     

    두번째, 말풍선 불러오기

     

    나에 대해 소개하는 페이지이지만,

    실제 대화하는 형식으로 구현하고 싶어서 

    티키타카

     

    버튼을 눌러야 상대방의 말풍선이 진행되도록 만들었고,

    매번 하나씩 봐야 하거나, 귀찮음 이슈도 있고 해서 스킵버튼도 추가를 했다.

     

    function showNextTalk(){ //말풍선 하나씩 표시
    
        if(cnt >= talkingBundleList.length){
            return 0
        }
        if(check == false){
            check = true;
        }
    
        let tempHtml = ``;
        tempHtml = talkingBundleList[cnt].split("<!!split2>"); // 스플릿으로 쪼개서 말풍선 하나하나 구분
    
        for(let i=0; i < tempHtml.length; i++){
             $('#testd').append(tempHtml[i]);
        }
    
        cnt++;
    
        showCurrentTime(); // 말풍선 옆에 시간 표시
    
        if(cnt == talkingBundleList.length){
            getAllComments();
            checkNextButtonEnd();
        }
    
    }

     

    function showAllTalk(){ // 말풍선 전체 표시 (스킵)
    
         if(cnt >= talkingBundleList.length){
            return 0
        }
    
        let tempHtml = ``;
    
        for(; cnt < talkingBundleList.length; cnt++){
    
            tempHtml = talkingBundleList[cnt].split("<!!split2>");
    
            for (let i = 0; i < tempHtml.length; i++) {
    
                console.log('i = ' + i);
                $('#testd').append(tempHtml[i]);
    
            }
        }
    
        if(check == true){
            showCurrentTime();
        }
    
        // reloadArea();
        getAllComments();
        checkNextButtonEnd();
    
    }

    이제 뭐 대충 이런식이고, 어려운 점이 없었는데, 둘의 차이점은

     

     

    하나씩 출력할 때는 실시간으로 시간을 반영.

    스킵해서 전체를 보여줄 때는 미리 적어둔 과거 시간을 반영.

     

    그렇구나 하고 넘어갈 수도 있는데 여기서 생각해봐야 하는 것은

     

     

    하나씩 출력하다가 중간부터 스킵을 한다면?

    실시간으로 시간이 반영되다가 그 이후 말풍선부터는 갑자기 과거시간이 나와버리게 되어 타임라인이 괴랄해진다!

     

    이렇게!

     

    아주 간단하게 해결할 수 있다

     

    let check = false;

    한번이라도 단일 말풍선 진행을 눌렀는지 체크 할 변수를 만들고,

     

    if(check == false){ // 말풍선을 하나씩출력하는 showNextTalk() 함수 내부의 조건문
        check = true;
    }

    조건에 따라 true false 정하고!

     

     

    if(check == true){ // 말풍선 스킵하는 showAllTalk()함수 내부의 조건문
        showCurrentTime();
    }

    true 라면 (눌렸다면) 미리 적어둔 과거시간을 전부 현재시간으로 체인지!

     

    시간을 표시하는 showCurrnetTime() 함수는 아래에서 설명하겠다

     

     

     

     

     

     

     

    세번째, 시간 표시

     

     

    function showCurrentTime(){
    
        let date = new Date();
        let tempHtml = ``;
        let hour = date.getHours().toString().padStart(2, "0");
        let minute = date.getMinutes().toString().padStart(2, "0");
    
    
        tempHtml = `${hour}:${minute}`;
    
        $(`.currentTime`).text(tempHtml);
    
        if(cnt == 1){
            document.getElementById('time' + (cnt-1)).setAttribute("class", "pastTime");
        }
        document.getElementById('time' + cnt).setAttribute("class", "pastTime");
    
    }

    현재 시간을 구하고, HTML 내용을 변경하도록 조작하는 함수를 구현했는데,

     

     

    $(`.currentTime`).text(tempHtml);

    이 메소드를 보면 알겠지만 currentTime 클래스가 속한 모든 태그의 시간을 갱신한다.

    이미 시간을 기록한 태그들(이미 지나간 말풍선)의 시간이 바뀌면 안되기에

    이미 시간이 기록된 말풍선들은 클래스를 바꿔줘야 하는데

     

     

     

    if(cnt == 1){
        document.getElementById('time' + (cnt-1)).setAttribute("class", "pastTime");
    }
    document.getElementById('time' + cnt).setAttribute("class", "pastTime");

    이부분의 기능에서 애를 먹었다. 

     

    JQuery를 사용하고 있던 터라 .attr() 을 사용하라고 하는데 내 파이참에서는 attr()이 안되는 것이다..정신차려 JQuery

     

    attr() 메소드의 실종..

    그래서 이를 해결하고자 열심히 구글링을 해보았으나

    attr()이 없다는 오류에 대한 것은 찾을수가 없었고..

     

     

     

    $('#time1').setAttribute("class", "pastTime");

    이렇게 setAttribute 메소드를 써보려 했지만 이건 뭐 is not a function 인가 하는 오류가 나서 안되드라..

    이유를 찾아보니 JQuery에 일반 자바스크립트 메소드를 써서 그런거라고..

     

     

     

    document.getElementById('time' + cnt).setAttribute("class", "pastTime");

    그래서 document. 의 메소드로 구현했다.

    진작 이렇게할걸..

     

     

     

     

     

     

    git....

    이번주 최고 빌런 git.. 이건 나중에 다시 정리하자

     

     

     

Designed by Tistory.