• 티스토리 홈
  • 프로필사진
    Song hyun
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
Song hyun
  • 프로필사진
    Song hyun
    • 분류 전체보기 (780)
      • 영어 (2)
        • Diary (0)
        • Toast Masters (2)
      • 메모 (13)
      • 설치 메뉴얼 (30)
      • Java (178)
      • MySQL (60)
      • JSP (67)
      • Springboot (46)
      • HTML,CSS, JS (71)
        • HTML (8)
        • CSS (12)
        • JavaScript (37)
        • HTML&CSS 스터디 (13)
      • C++ (7)
      • Linux (7)
      • JPA (34)
      • Kotlin (2)
      • Flutter (42)
      • Error Note (39)
      • 디자인 패턴 (12)
      • 디지털논리회로 (4)
      • 데이터베이스 시스템 (8)
      • 알고리즘 (7)
      • 운영체제 (3)
      • 이산수학 (3)
      • 인공지능 (1)
      • 자료 구조 (14)
        • 기본 개념 (14)
        • 자료구조 스터디 (0)
      • 💡My project (76)
        • 팩맨 : Java Swing 게임 제작 프로젝트 (6)
        • 네이트톡 : Java 소켓 통신 프로젝트 (4)
        • 포켓옥션 : HikariCP&JDBC CRUD 프.. (3)
        • 이지 부산 : BDIA-Devton 2024 프로.. (20)
        • 그린 유니버시티 : JSP를 사용한 학사관리 프로.. (1)
        • 애드 포커 : 웹 소켓과 Spring을 사용한 카.. (1)
        • 셸위 : 게임 친구 매칭 사이트 (21)
        • 다모아 : 개발자 중개 플랫폼 (20)
      • 📗스터디 (13)
        • CNN : 웹개발 스터디 (10)
        • Node&React로 유튜브 사이트 만들기 (3)
      • 📙독서 및 강연 기록 (36)
        • 강연 (14)
        • 독서 (22)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [JavaScript] 29. JavaScript를 사용한 글쓰기 기능 만들기
        2024년 08월 28일
        • Song hyun
        • 작성자
        • 2024.08.28.:09
        728x90
        반응형

        [JavaScript] 29. JavaScript를 사용한 글쓰기 기능 만들기

         

         

         

        1. boardList.js

        // 샘플 데이터 입력
        const sampleBoardList = [
            {
              id: 1,
              title: "첫번째 게시글",
              content: "첫번째 게시글에 내용 입니다.",
              username: "홍길동",
              today: "2024.08.25",
              count: 5,
            },
            {
              id: 2,
              title: "두번째 게시글",
              content: "두번째 게시글에 내용 입니다.",
              username: "이몽룡",
              today: "2024.08.25",
              count: 5,
            },
            {
              id: 3,
              title: "세번째 게시글",
              content: "세번째 게시글에 내용 입니다.",
              username: "성춘향",
              today: "2024.08.25",
              count: 14,
            },
            {
              id: 4,
              title: "네번째 게시글",
              content: "네번째 게시글에 내용 입니다.",
              username: "변학도",
              today: "2024.08.25",
              count: 21,
            },
            {
              id: 5,
              title: "다번째 게시글",
              content: "다번째 게시글에 내용 입니다.",
              username: "심청",
              today: "2024.08.25",
              count: 51,
            },
          ];
          //localStorage.setItem('boardList', JSON.stringify(sampleBoardList));
          
          document.addEventListener("DOMContentLoaded", function () {
            // DOM 접근
            const boardContainer = document.querySelector(".board-content-box"); // 컨텐트를 넣을 Element 선택
            const writeButton = document.querySelector(".btn"); // 글쓰기 버튼 Element 선택
            const paginationContainer = document.querySelector(".num-box");
          
            // 로컬 스토리지에서 게시글 목록 가져오기
            const storedBoardList = JSON.parse(localStorage.getItem("boardList"));
            // 게시글 목록을 내림차수능로 정렬하기
            if (storedBoardList) {
              storedBoardList.reverse();
            }
          
            // 페이징 처리 필요한 변수
            let currentPage = 0;
            const limit = 2; // 한 페이지당 게시글 수
          
            loadPosts(currentPage);
          
            // 게시글을 로드 하는 함수
            function loadPosts(page) {
              const offset = page * limit;
              const end = offset + limit;
          
              let postElements = ""; // 게시긁 HTML 요소을 저장할 변수
          
              // 방어적 코드 작성
              if (storedBoardList != null && storedBoardList.length > 0) {
                // 반복문을 사용 ()
                for (let i = offset; i < end && i < storedBoardList.length; i++) {
                  postElements += `<div class="board" data-id=${storedBoardList[i].id}>
                          <div class="board-1">${i + 1}</div>
                          <div class="board-2">${storedBoardList[i].title}</div>
                          <div class="board-3">${storedBoardList[i].username}</div>
                          <div class="board-4">${storedBoardList[i].today}</div>
                          <div class="board-5">${storedBoardList[i].count}</div>
                        </div>`;
                }
          
                boardContainer.innerHTML = postElements; // 게시글 컨테이너에 HTML 추가
          
                // 페이지 네이션 생성 하기
                createPagination(storedBoardList, page);
              } else {
                // 게시글이 없는 경우 메세지 표시
                boardContainer.innerHTML = '<div class="no-list"  style="text-align:center; margin-top:20px"> 조회된 게시글이 없습니다 </div>';
              }
            }
          
            // 페이지 네이션 생성 함수 선언
            function createPagination(boardList, currentPage) {
              // 전체 게시글 수 , 한 페이장 보여질 게시글 수
              const totalPosts = boardList.length; // 전체 게시글 수
              const totalPages = Math.ceil(totalPosts / limit); // 전체 페이지 수
              // 페이지 번호 HTML 저장할 변수
              let paginationHTML = "";
              for (let i = 0; i < totalPages; i++) {
                paginationHTML += `<span class="num" data-page="${i}">${i + 1}</span>`;
              }
              
              paginationContainer.innerHTML = paginationHTML;
          
              // 생성된 페이지 번호의 요소 접근 (동적 할당)
              const pageNumbers = document.querySelectorAll('.num');
              
              // 현재 페이지 번호에 스타일 적용 
              pageNumbers[currentPage].style.backgroundColor = 'grey';
              pageNumbers[currentPage].style.fontWeight = 600;
          
              pageNumbers.forEach( (pageNumber) => {
                  pageNumber.addEventListener('click', (event) => {
                      // console.log('event', event);
                      // console.log('event.target', event.target);
                      // console.log('event.target.dataset', event.target.dataset);
                      // console.log('event.target.dataset.page', event.target.dataset.page);
                      // 해당하는 번호를 가지고 와서 다시 렌더링 
                      const targetPageNumber =  parseInt(event.target.dataset.page); // 문자열 --> number 변환 
                      loadPosts(targetPageNumber);
                  })
              }); 
            }
        
              // 하나의 게시글 클릭 시 상세보기 화면 이동 처리
              function postClickListeners(){
                
              }
              
              // 글쓰기 버튼 눌렀을 경우 -> 글쓰기 페이지 이동 처리 
              writeButton.onclick = function() {
                location.href = "board-write.html";
            }
          });

         

        2. board-write.html

        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>글쓰기</title>
            <link rel="stylesheet" href="../css/common.css" />
            <link rel="stylesheet" href="../css/header.css" />
            <link rel="stylesheet" href="../css/boardWrite.css" />
        </head>
        <body>
             <!-- 헤더 섹션과 네비 영역 -->
             <header>
                <nav class="nav-container">
                  <div class="nav-item">
                    <span class="menu-link" id="board">게시판</span>
                  </div>
                  <div class="nav-item" id="authLinks">
                    <span class="menu-link" id="signIn">로그인</span>
                    <span class="menu-link" id="signUp">회원가입</span>
                  </div>
                </nav>
              </header>
        
              <main class="content-wrapper">
                <section class="form-title">
                    <h1>글쓰기 by JS</h1>
                </section>
        
                <section>
                    <table>
                        <tr>
                            <th>제목</th>
                            <td>
                                <input type="text" class="inputs title">
                            </td>
                        </tr>
                        <tr>
                            <th>작성자</th>
                            <td>
                                <input type="text" class="inputs username" readonly>
                            </td>
                        </tr>
                        <tr>
                            <th>첨부파일</th>
                            <td>
                                <input type="file" class="file" accept="image/*">
                            </td>
                        </tr>
                        <tr>
                            <th>내용</th>
                            <td>
                                <div class="img-box" >이미지 미리보기</div>
                                <textarea name="" id="" class="content"></textarea>
                            </td>
                        </tr>
                    </table>
        
                    <div class="btn-area">
                        <button type="button" class="btn">글쓰기</button>
                    </div>
        
                </section>
              
            </main>
              
              <script src="../js/header.js"></script>
              <script src="../js/boardWrite.js"></script>
        </body>
        </html>

         

        3. boardWrite.css

        .content {
            width: 95%;
            height: 300px;
            font-size: 18px;
            border: none;
            resize: none;
            margin-top: 5px;
        }
        
        .img-box {
            width: 100%;
            display: flex;
            justify-content: center;
        }
        
        .img-box img {
            width: 100%; 
            max-width: 300px;
        }

         

        4. boardWrite.js

        // 로그인 상태 여부 
        redirectToPageIfNotLoggedIn('sign-in');
        
        document.addEventListener('DOMContentLoaded', function() {
            
            // 사용 할 요소에 접근 
            const title = document.querySelector('.title');
            const username = document.querySelector('.username');
            const fileInput = document.querySelector('.file');
            const imgViewBox = document.querySelector('.img-box');
            const content = document.querySelector('.content');
            const button = document.querySelector('button');
            const day = new Date(); 
        
            // 사용자 선택한 이미지를 저장할 공간이 필요 
            let imageData = null; 
            // 사용자 정보 가져 오기 
            const getUser = JSON.parse(localStorage.getItem('user'));
            username.value = getUser.username;
        
            // 파일 미리보기 기능 만들기
            function fileUpload(event) {
                
                const file = event.target.files[0];
                //console.log('file', file);
                // 파일 크기 유효성 검사 
                // 1024 * 1024  * 5 =  (5MB) 이하만 허용 
                if(file.size >= 5242880) { 
                    alert('첨부 파일은 5MB 이하만 가능 합니다');
                    event.target.value = "";
                    return; 
                }
                // 파일 타입 유효성 검사 
                const validFileTypes = ['image/jpeg', 'image/png', 'image/gif'];
                if(!validFileTypes.includes(file.type))   {
                    alert('유효한 파일 타입이 아닙니다.(jpeg, png, gif만 허용');
                    return; 
                } 
        
                // 파일 미리보기 기능 
                const reader = new FileReader();
                reader.readAsDataURL(file); // Base64 인코딩 바이트 단위 데이터를 -- 64개 문자로 표현하는 인코딩 방식
                reader.onload = function (e) {
                    console.log('Base64', e.target.result);
                    imgViewBox.innerHTML = `<img src="${e.target.result}" alt="Upload Image">`;
                    // 글 저장시에 로컬스토리지에 바이너리 데이터를 -- 64 인코딩 저장 
                    imageData = reader.result;
                }
            }
        
            // 글 저장하는 기능 만들기 
            function saveBoard() {
                // 유효성 검사 
                if(title.value === "") {
                    alert('제목을 입력하시오');
                    return;
                }
                
                if(content.value === "") {
                    alert('내용을 입력하시오');
                    return;
                }
        
                // 로컬 스토리지에 게시글 전체 목록 가져오기 
                let boardList = JSON.parse(localStorage.getItem('boardList') || '[]' );
        
                // 고유 ID 생성 
                const newId = generateUniqueId(boardList);
        
                // 객체 리터럴 표기법 사용 
                const board = {
                    id: newId, 
                    title : title.value,
                    content : content.value, 
                    username: username.value, 
                    today:  `${day.getFullYear()}.${day.getMonth() + 1}.${day.getDate()}`,
                    count: 0, 
                    imgData: imageData
                };
                
                // 배열에다가 생성한 객체 추가 
                boardList.push(board);
        
                // 로컬 스토리지에 저장 (배열 전체)
                localStorage.setItem("boardList", JSON.stringify(boardList));
                // 페이지 이동 처리 
                location.href = 'board-list.html';
            }
        
            // 고유 아이디 생성 함수 
            function generateUniqueId(boardList) {
                return boardList.length > 0  ? boardList[boardList.length - 1].id + 1 :  1 ;
            }
            
            // 이벤트 리스너 등록 처리 - file change 
            fileInput.addEventListener('change', fileUpload);
            button.addEventListener('click', saveBoard);
        });
        728x90
        반응형

        'HTML,CSS, JS > JavaScript' 카테고리의 다른 글

        [JavaScript] 31. JavaScript를 사용한 게시글 상세보기 기능 만들기(2)  (0) 2024.08.29
        [JavaScript] 30. JavaScript를 사용한 게시글 상세보기 기능 만들기(1)  (0) 2024.08.28
        [JavaScript] 28. JavaScript를 사용한 목록 페이지 만들기(3)  (0) 2024.08.26
        [JavaScript] 27. JavaScript를 사용한 목록 페이지 만들기(1)  (0) 2024.08.26
        [JavaScript] 26. JavaScript를 사용한 헤더 만들기  (0) 2024.08.26
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바