today_is

[ javascript - AJAX ] 본문

front

[ javascript - AJAX ]

ye_rang 2024. 2. 20. 13:06

오늘의 목표

다른 웹서버에 있는 데이터를 이용하여 원하는 형식대로 데이터를 출력해보기

 

script 코드는 vscode 로 작성해보자

 


 이미지 출력해보기 

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        #root {
            max-width: 1200px;
            display: flex;
            flex-flow: wrap;
            margin: 20px auto;
        }
        .item {
            width: 45%;
            display: flex;
            border: 1px solid black;
            margin: 10px;
            padding: 10px;
        }
        .item img {
            margin-right: 10px;
        }

    </style>

  </head>
  <body>
    <h1>AJAX 화면 구현</h1>
    <hr>

    <div id="root"></div>

    <script>
      //  fetch(콜백형태, 함수 내부에)

      const url = "https://jsonplaceholder.typicode.com/photos";
      
      
      fetch(url)     //  주소로 요청한다
        .then(resp => resp.json())     //  요청에 따른 응답이 오면, 응답을 json 으로 변환   
        .then(json => {                //  json 을 이용하여 다음 내용을 수행
         
          
         
          console.log(json);

          const arr = json.slice(0, 50).map(e => {
            delete e.url
            return e
          })

          console.log(arr)

          const root = document.getElementById('root')

          arr.forEach(dto => {
            let tag = ''
            tag += `<div class="item">`
            tag += `    <div class="thumbnailUrl"><img src="${dto.thumbnailUrl}"></div>`
            tag += `    <div>`
            tag += `        <div class="title">${dto.title}</div>`
            tag += `        <div class="id">${dto.id}</div>`
            tag += `        <div class="albumId>${dto.albumId}</div>`
            tag += `    </div>`
            tag += `</div>`

            root.innerHTML += tag
          })

          //    fetch.then() 함수의 콜백에는 반환을 수행하지 않는다
          //    만약, async / await 를 사용하면 반환을 수행할 수 있다 

        });



    </script>
  </body>
</html>

 

 

style 에는 .item 에 width 를 이용하여, 한줄에 나오는 요소 개수를 정할 수 있다

 


 

 전체 목록 출력하기 + (페이징) 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        a {
            color: inherit;
            text-decoration: none;
        }
        a:hover {
            text-decoration: underline;
        }
        table {
            border-collapse: collapse;
            margin: auto;
        }
        thead {
            background-color: grey;
            color: white;
        }
        tr {
            border-bottom: 1px solid grey;
        }
        td,th {
            padding: 5px 10px;
        }


    </style>
</head>
<body>
    
    <h1>posts</h1>
    <hr>


    <div id="root">
        <table>
            <thead>
                <tr>
                    <th>번호</th>
                    <th>제목</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
    </div>


    <!--
        HTTP 요청 메서드
        
        GET           : select     요청할때 메서드를 지정하지 않으면 기본값은 get       
        POST          : insert
        PUT/PATCH     : update 
        DELETE        : delete

    -->


    <script>
    	 //  다른 서버에있는 데이터를 가져오기 위해 주소를 넣음 
        const url = 'https://jsonplaceholder.typicode.com/posts'   

        fetch(url)
            .then(resp => resp.json()) 
            .then(json => {

                //  console.log(json)   항상 fetch 하고 나서 출력해보기!! 
                //  (내가 가져온 데이터가 무엇인지 알아야 다듬을 수 있음 )
                //  tbody 에 innerHTML 넣어주는 것이 정석임
                const tbody = document.querySelector('#root > table > tbody')  
                const arr = json.toSorted((a, b) => b.id - a.id)    //  정수반환으로 정렬하기 
                                        .slice(0, 20)               //  slice 로 페이징 
                
                arr.forEach(dto => {
                        let tag = ''
                        tag += `<tr>`
                        tag += `    <td>${dto.id}</td>`
                        
                        //	12_post.html?id=${dto.id} : 이때 id 를 같이 넘긴다
                        tag += `    <td><a href="12_post.html?id=${dto.id}">${dto.title}</a></td>`
                        tag += `</tr>`
                        
                        tbody.innerHTML += tag
                })
            })

    </script>
</body>
</html>

 

 

전체 목록 (11_posts.html)

 

 


 

 개별 보여주기 

 

전체 목록 중에서 하나를 선택하면 (a 태그를 이용하여 페이지 이동) 

이때, id 를 받아와서 개별 출력 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
<style>
    table {
        border: 2px solid black;
        border-collapse: collapse;
        margin: 10px 0;
    }
    td, th {
        padding: 5px 10px;
    }
    tr {
        border-bottom: 1px solid grey;
    }

</style>

</head>
<body>
    

    <h1>post.html</h1>
    <hr>


    <table>
        <tr>
            <td class="id"></td>
            <td class="title"></td>
        </tr>
        <tr>
            <td class="userId" colspan="2"></td>
        </tr>
        <tr>
           <td colspan="2"><pre class="body"></pre></td>
        </tr>
    </table>

    <div style="display: flex; justify-content: space-between;">
        <div>
            <a href="11_post.html"><button>목록</button></a>
        </div>
        <div></div>
    </div>


    <script>
        //   자바스크립트에서 쿼리스트링 가져오기
        const id = new URLSearchParams(location.search).get('id')       //  위에서 생성한 id 를 
        const url = `https://jsonplaceholder.typicode.com/posts/${id}`  //  쿼리스트링 자리에 넣기 
        //  console.log(url)


        //  async / await 를 활용하여 json 을 반환값으로 받기
        //  비동기 함수를 정의할때 async        
        //  비동기 함수를 호출할때 await   :   주소로 요청을 하고 응답을 받으면 그 응답을 json 객체로 바꿈 (콘솔로그가 안뜬다)
        //  단, await 호출은    javascript 코드의 top-level 에서 호출할 수 없음(그래서, loadHandler() 를 만든 이유) 
        async function loadHandler() {
            const json = await fetch(url)
                        .then(resp => resp.json())
            console.log(json)


        //  json 객체의 변수(필드) 이름과 
        //  HTML element 의 클래스 이름을 맞춰두고 하나씩 대입
            for(let key in json) {      //  key 는 index 역할, index에 접근하려면 for 문의 in 을 사용 
                console.log(key)
                const value = json[key]
                const element = document.querySelector('.' + key)       //  앞에 . 붙이면 class로 불러옴 
                element.innerText = value

            }


        //  불러온 json 객체에서 userId 를 불러와서 username을 작성자 위치에 덮어쓰기
            const username = await fetch('https://jsonplaceholder.typicode.com/users/' + json.userId)
                        .then(resp => resp.json())
                        .then(json => json.username)
        
            document.querySelector('.userId').innerText = username
        }
        window.onload = loadHandler
    </script>
</body>
</html>

 

 

98번 데이터를 클릭하였을때 나오는 화면 (12_post.html)

 

 

 

 

목록을 누르면 다시 전체 목록으로 돌아감

 

 

 


 

 

study_review

처음 비동기함수 작성할때

 

작성법이 조금 생소해서 어렵게 느껴졌었는데,

 

모든 코딩 키워드들은 영단어의 뜻대로 기능한다는 점을 유의하며

커닝없이 혼자 기억을 더듬으면서 써봤더니 구조가 조금은 익숙해졌다

 

 

그리고 가장 어이없는 실수로는 

자꾸 innerHTML 에 변수 내용을 추가해주는 것을 까먹게 된다 ㅜㅜ

 

잊지말자 tbody.innerHTML += tag

'front' 카테고리의 다른 글

[ javascript ] hidden 을 이용한 다중필터  (0) 2024.02.21
[ js ] json 파일로 화면 구현  (0) 2024.02.19
[ javascript ] 검색필터  (0) 2024.01.26
[ javascript ] 클릭이벤트  (0) 2024.01.24
[ javascript ] 정렬  (0) 2024.01.22