full stack/JavaScript

javascript λ™μ μ΄λ²€νŠΈ, 비동기톡신 ajax (2023.05.04)

Shinjio 2023. 5. 4. 17:19
λ°˜μ‘ν˜•

< 볡슡 >

jQuery : JS λΌμ΄λΈŒλŸ¬λ¦¬

μš”μ†Œ μ ‘κ·Ό → $(cssμ„ νƒμž)
κΈ°λŠ₯ μΆ”κ°€ → .λ©”μ†Œλ“œ()

λ‚΄μš©λ§Œ → .text()
νƒœκ·ΈκΉŒμ§€ → .html()
μŠ€νƒ€μΌμ œμ–΄ → .css()

ν•œμ€„μ”© μž…λ ₯
$('h1').css('속성1','κ°’1')
$('h1').css('속성2','κ°’2')
$('h1').css('속성3','κ°’3')

chain λ°©μ‹
$('h1').css('속성1','κ°’1').css('속성2','κ°’2').css('속성3','κ°’3')

객체 λ°©μ‹
$('h1').css({
    '속성1' : 'κ°’1',
    '속성2' : 'κ°’2',
    '속성3' : 'κ°’3',
})

 

🎈 동적 이벀트 바인딩

πŸ“– 이벀트 바이딩

JSμ½”λ“œμ™€ jQueryμ½”λ“œλŠ” λŒ€λΆ€λΆ„ 이벀트(event)에 μ˜ν•΄ λ™μž‘ν•¨

μ΄λ²€νŠΈλž€ λŒ€ν‘œμ μœΌλ‘œ 클릭, ν‚€λ³΄λ“œ μž…λ ₯ λ“± μ‚¬μš©μžμ˜ μ–΄λ–€ ν–‰μœ„

 

βš™ 이벀트 λ°”μ΄λ”©μ˜ κ³Όμ •

1. 이벀트λ₯Ό λ°›μ•„ 쀄 μš”μ†Œ 선택

2. μ„ νƒν•œ μš”μ†Œκ°€ μ–΄λ–€ μ΄λ²€νŠΈμ— λ°˜μ‘ν• μ§€, μš”μ†Œμ™€ 이벀트λ₯Ό μ—°κ²°ν•΄μ£ΌλŠ” 바인딩 μ§„ν–‰

3. μ΄λ²€νŠΈκ°€ λ°œμƒν–ˆμ„ λ•Œ 싀행될 μ½”λ“œ μž‘μ„±

 

πŸ“– 동적 이벀트 바이딩

λ™μ μœΌλ‘œ μƒμ„±λœ Element(이벀트둜 인핸 μƒμ„±λœ μš”μ†Œ)에 이벀트λ₯Ό λ°”μΈλ”©ν•œλ‹€λŠ” 의미

 

βš™ 일반 μ΄λ²€νŠΈμ™€ 동적 이벀트 차이

 

일반 이벀트λ₯Ό μ‚¬μš©ν–ˆμ„ 경우, μƒμ„±λœ 동적 μš”μ†Œμ—μ„œλŠ” μ΄λ²€νŠΈκ°€ μž‘λ™ν•˜μ§€ μ•ŠμŒ 

반면, 동적 이벀트λ₯Ό μ‚¬μš©ν–ˆμ„ 경우 μƒμ„±λœ 동적 μš”μ†Œμ—μ„œλ„ μ΄λ²€νŠΈκ°€ μž‘λ™ν•¨

 

$(document).on(μ΄λ²€νŠΈνƒ€μž…, μ΄λ²€νŠΈλŒ€μƒ(cssμ„ νƒμž), μ΄λ²€νŠΈν•Έλ“€λŸ¬)

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>dynamic event</title>
    <style>
        button{
            width: 100px;
            height: 60px;
            margin: 5px;
            border: none;
            border-radius: 10px;
            font-weight: 600;
            font-size: 1.7rem;
        }
        .clickBtn{
            background-color: lightpink;
        }
        .onBtn{
            background-color: lightgreen;
        }
    </style>
    <script src="./js/jquery-3.6.4.min.js"></script>
</head>
<body>
    <button class="clickBtn">click</button>
    <button class="onBtn">on</button>
    <br>

    <script>
        // λ™μ μ΄λ²€νŠΈ
        // → λ¬Έμ„œλ₯Ό 가져와야 함
        // $(document).on(μ΄λ²€νŠΈνƒ€μž…, μ΄λ²€νŠΈλŒ€μƒ(cssμ„ νƒμž), μ΄λ²€νŠΈν•Έλ“€λŸ¬)

        // Click λ²„νŠΌ ν΄λ¦­μ‹œ, click λ²„νŠΌ 생성
        $('.clickBtn').click(()=>{
            // body νƒœκ·Έμ— clickBtn 생성
            $('body').append('<button class="clickBtn">click</button>');
        })

        // on λ²„νŠΌ 클릭슀, on λ²„νŠΌ 생성
        $(document).on('click', '.onBtn', ()=>{
            $('body').append('<button class="onBtn">on</button>');
        })
        
    </script>
</body>
</html>

 

🎈 jQuery λ‹€μ–‘ν•œ λ©”μ„œλ“œ

 

// μΆ”κ°€ 제거 κ΄€λ ¨
// attr(좔가할속성, μ†μ„±μ˜κ°’) : 속성 μΆ”κ°€ λ©”μ„œλ“œ
// removeAttr(μ œκ±°ν• μ†μ„±) : 속성 제거 λ©”μ„œλ“œ
// removeClass(ν΄λž˜μŠ€μ΄λ¦„) : 클래슀 속성값 제거 λ©”μ„œλ“œ
// $(A).appen(B) : Bλ₯Ό Aμš”μ†Œ λ§ˆμ§€λ§‰ μœ„μΉ˜μ— μΆ”κ°€ λ©”μ„œλ“œ
// $(A).prepend(B) : Bλ₯Ό Aμš”μ†Œ 첫번째 μœ„μΉ˜μ— μΆ”κ°€ λ©”μ„œλ“œ

// input κ΄€λ ¨ λ©”μ„œλ“œ
// val() : input μž…λ ₯ κ°’ μ ‘κ·Ό (JS : value)
// input μ•ˆμ˜ κ°’ λΉ„μ›Œμ£ΌκΈ° → inputλ°˜ν™˜κ°μ²΄.val('')

// λΆ€λͺ¨ κ΄€λ ¨ λ©”μ„œλ“œ 
// parent() : κ°€μž₯ κ°€κΉŒμš΄ λΆ€λͺ¨ μš”μ†Œ 선택 
// parents() : λͺ¨λ“  λΆ€λͺ¨ μš”μ†Œ 선택
// closest(μ›ν•˜λŠ”μš”μ†Œ) : λͺ¨λ“  λΆ€λͺ¨ μš”μ†Œ λŒ€μƒμœΌλ‘œ μ›ν•˜λŠ” μš”μ†Œ κ²€μƒ‰ν•˜μ—¬ μ ‘κ·Ό

// 1. μ’‹μ•„μš” λ²„νŠΌ ν΄λ¦­μ‹œ 
//      λ²„νŠΌ λ‚΄ λ©”μ‹œμ§€ : μ’‹μ•„μš” → μ’‹μ•„μš” μ·¨μ†Œ 
//      숫자 : 0 → 1
$(document).on('click', '.likeBtn', (e)=>{
    // λ²„νŠΌ λ‚΄μš© λ°”κΎΈκΈ°
    $(e.target).text('μ’‹μ•„μš” μ·¨μ†ŒπŸ˜₯');
    // 숫자 λ°”κΎΈκΈ°
    $('span').text('1');
    // likeBtn 클래슀 제거, dislikeBtn 클래슀 μΆ”κ°€
    // $(e.target).removeClass('likeBtn');
    $(e.target).removeAttr('class');
    $(e.target).attr('class', 'dislikeBtn');
    
})

// 2. μ’‹μ•„μš” μ·¨μ†Œ λ²„νŠΌ ν΄λ¦­μ‹œ
//      μ’‹μ•„μš” μ·¨μ†Œ → μ’‹μ•„μš” 
//      1 → 0 λ³€κ²½
$(document).on('click', '.dislikeBtn', (e)=>{
    $(e.target).text('μ’‹μ•„μš”πŸ˜');
    $('span').text('0');
    // dislikeBtn 클래슀 제거, likeBtn 클래슀 μΆ”κ°€
    $(e.target).removeAttr('class');
    $(e.target).attr('class', 'likeBtn');
})

// 3. λŒ“κΈ€ μž‘μ„± λ²„νŠΌ ν΄λ¦­μ‹œ
//     λŒ“κΈ€ + μ‚­μ œ λ²„νŠΌ 생성
$(document).on('click', '.textBtn', ()=>{
    let textVal = $('input[type=text]').val();
    $('.container').prepend(`
        <p>
            ${textVal}
            <button class="removeBtn">μ‚­μ œ ΰ²₯_ΰ²₯</button>
        </p>
    `)

    // input μ•ˆμ˜ κ°’ λΉ„μ›Œμ£ΌκΈ°
    $('input').val('');
})

// 4. μ‚­μ œ λ²„νŠΌ ν΄λ¦­μ‹œ
//     λŒ“κΈ€ + μ‚­μ œ λ²„νŠΌ 제거 
$(document).on('click', 'button[class=removeBtn]', e=>{
    // $(e.target).parent().remove();
    // $(e.target).parents().remove();
    $(e.target).closest('p').remove();
})

 

β€» μΆ”κ°€ κ΄€λ ¨ λ©”μ„œλ“œ append vs prepend 차이

 

πŸ“– event.target vs this

βš™ $(this)

μΌμ’…μ˜ λ³€μˆ˜, μ„ νƒμžλ‘œ this ν‚€μ›Œλ“œλ₯Ό $() ν•¨μˆ˜μ— μ „λ‹¬ν•˜λ©΄, μ΄λ²€νŠΈκ°€ λ°œμƒν•œ 자기 μžμ‹ μ„ 감지할 수 있음

일반적으둜 λ™μΌν•œ μ†ŒμŠ€κ°€ λ°˜λ³΅λ˜λŠ” 곳에 μ‚¬μš©λ¨

 

호좜된 HTML 객체λ₯Ό μ €μž₯ → ν™”μ‚΄ν‘œ ν•¨μˆ˜μ—μ„œλŠ” μž‘λ™ν•˜μ§€ μ•ŠμŒ. ν•¨μˆ˜ ν‘œν˜„μ‹μ—μ„œ μ‚¬μš© κ°€λŠ₯

 

        $('h1').on('mouseover', function(){
            $(this).css('color', 'red');
            // this : 호좜된 HTML 객체λ₯Ό μ €μž₯
            //  - ν™”μ‚΄ν‘œ ν•¨μˆ˜μ—μ„œλŠ” μž‘λ™ν•˜μ§€ μ•ŠμŒ
        })

 

μœ„μ˜ μ½”λ“œμ—μ„œ thisλŠ” HTML의 <h1>을 μ˜λ―Έν•¨ 

 

βš™ event.target

μ‹€μ œ μ΄λ²€νŠΈκ°€ μ‹œμž‘λœ target μš”μ†Œ

이벀트λ₯Ό μ΄‰λ°œμ‹œν‚¨ μš”μ†Œ

ν™”μ‚΄ν‘œ ν•¨μˆ˜μ—μ„œ μ‚¬μš© κ°€λŠ₯

 

$(document).on('click', '.dislikeBtn', (e)=>{
    $(e.target).text('μ’‹μ•„μš”πŸ˜');
    $('span').text('0');
    // dislikeBtn 클래슀 제거, likeBtn 클래슀 μΆ”κ°€
    $(e.target).removeAttr('class');
    $(e.target).attr('class', 'likeBtn');
})

 

βš™ event.target ν˜Ήμ€ $(this) μ‚¬μš©ν•˜λŠ” 이유

 

 

likeBtn을 HTMLμ—μ„œ 찾은 ν›„ μ‹€ν–‰λ¬Έμ—μ„œ 또 λ‹€μ‹œ HTMLμ—μ„œ likeBtn을 μ°Ύμ•„μ„œ μ‹€ν–‰ → λΉ„νš¨μœ¨μ 

νƒ€κ²Ÿ ν˜Ήμ€ this ν™œμš©ν•˜μ—¬ λ°”λ‘œ μ ‘κ·Όν•  수 μžˆλ„λ‘!!

 

🎈 ajax λΉ„동기톡신방식

πŸ“– 동기톡신 vs 비동기톡신

βš™ 비동기(Asynchronous) 톡신

μ„œλ²„μ— μš”μ²­(request)λ₯Ό λ³΄λƒˆμ„ λ•Œ 응닡(response) μƒνƒœμ™€ 상관없이 λ‹€μŒ μš”μ²­(request)을 μˆ˜ν–‰ν•  수 μžˆλŠ” 톡신 방법

 

βš™ 동기(Synchronous) 톡신

μ„œλ²„μ— μš”μ²­(request)λ₯Ό λ³΄λƒˆμ„ λ•Œ 응닡(response)이 λŒμ•„μ™€μ•Ό λ‹€μŒ μš”μ²­(request)을 μˆ˜ν–‰ν•  수 μžˆλŠ” 톡신 방법

 

πŸ“– AJAX (Asynchronous JavaScript and XML)

ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„κ°„ 비동기적 정보 κ΅ν™˜μ΄ κ°€λŠ₯ν•œ 톡신 κΈ°λŠ₯ 

** ν™”λ©΄ μ „ν™˜ 없이

 

데이터λ₯Ό μ΄λ™ν•˜κ³  화면을 κ΅¬μ„±ν•˜λŠ”λ° μžˆμ–΄μ„œ μ›Ή 화면을 κ°±μ‹ ν•˜μ§€ μ•Šκ³  ν•„μš”ν•œ 데이터λ₯Ό μ„œλ²„λ‘œ 보내고 κ°€μ Έμ˜€λŠ” 방법

ν™”λ©΄ 갱신이 μ—†μ–΄μ„œ μ‚¬μš©μž μž…μž₯μ—μ„œ 맀우 νŽΈλ¦¬ν•˜κ³  λΉ λ₯΄κ²Œ μž‘μ—…μ„ μ²˜λ¦¬ν•˜λŠ” κ²ƒμ²˜λŸΌ λŠκ»΄μ§€κ²Œ 함

ν•˜μ§€λ§Œ, λ™μ μœΌλ‘œ 화면을 κ΅¬μ„±ν•˜λŠ” 만큼 개발자의 κ΅¬ν˜„μ€ λ³΅μž‘ν•΄μ§

 

πŸ“– 데이터 ν˜•μ‹

데이터λ₯Ό μ „μ†‘ν•˜λŠ” 전솑 ν˜•μ‹

 

βš™ CSV (Comma - Seperated Values)

μ‰Όν‘œλ₯Ό κΈ°μ€€μœΌλ‘œ ν•­λͺ©μ„ κ΅¬λΆ„ν•˜μ—¬ μ €μž₯ν•œ 데이터

 

 

βš™ XML(eXtensible Markup Language)

λ‹€λͺ©μ  λ§ˆν¬μ—… μ–Έμ–΄λ‘œ νƒœκ·Έ 등을 μ΄μš©ν•˜μ—¬ λ°μ΄ν„°μ˜ ꡬ쑰λ₯Ό μž‘μ„±ν•˜λŠ” 기술

ν•΄λ‹Ήν•˜λŠ” κ°’ μ–‘μͺ½μ— νƒœκ·Έλ‘œ λ¬Άμ–΄μ„œ κ΄€λ¦¬ν•˜λ―€λ‘œ 가독성이 μ’‹μ•„ 데이터 νŒλ³„μ΄ 쉬움

 

 

βš™ JSON(JavaScript Object Notation)

'ν‚€, κ°’' 쌍으둜 이루어진 데이터 였브젝트λ₯Ό μ „λ‹¬ν•˜κΈ° μœ„ν•œ κ°œλ°©ν˜• ν‘œμ€€ 포맷

→ json μžλ°”μŠ€ν¬λ¦½νŠΈ κ°μ²΄ν˜•νƒœ

λ°˜λ³΅λ˜λŠ”  νƒœκ·Έ ꡬ쑰λ₯Ό 쀄일 수 μžˆμ–΄μ„œ μš©λŸ‰μ΄ μž‘λ‹€ (XML에 λΉ„ν•΄)

AJAX 비동기톡신 ν‘œμ€€λ°μ΄ν„°λ‘œ JSON μ‚¬μš©

 

 

πŸ“– Ajax둜 api κ°€μ Έμ˜€κΈ°

 

AjaxλŠ” 제이쿼리둜 μ ‘κ·Όν•˜μ§€ μ•ŠμœΌλ©΄ μ½”λ“œκ°€ λ„ˆλ¬΄ λ³΅μž‘ν•΄μ§€κΈ° λ•Œλ¬Έμ— 제이쿼리둜 μ‚¬μš©

API(application programming interface, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν”„λ‘œκ·Έλž˜λ° μΈν„°νŽ˜μ΄μŠ€)
μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ μ„œλ‘œ λ‹€λ₯Έ μ†Œν”„νŠΈμ›¨μ–΄ ꡬ성 μš”μ†Œλ₯Ό μ—°κ²°ν•˜μ—¬ μƒν˜Έμž‘μš©ν•  수 μžˆλ„λ‘ ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° μΈν„°νŽ˜μ΄μŠ€. APIλŠ” 일반적으둜 μ„œλ‘œ λ‹€λ₯Έ μ‹œμŠ€ν…œ, ν”Œλž«νΌ λ˜λŠ” μ–Έμ–΄ κ°„μ˜ 톡신을 κ°€λŠ₯ν•˜κ²Œ ν•˜λ©°, μ›Ή APIλŠ” μ›Ή κΈ°μˆ μ„ μ‚¬μš©ν•˜μ—¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°„μ˜ μƒν˜Έμž‘μš©μ„ μš©μ΄ν•˜κ²Œ 함. 예λ₯Όλ“€μ–΄, 페이슀뢁 APIλ₯Ό μ‚¬μš©ν•˜λ©΄ κ°œλ°œμžλŠ” 페이슀뢁 데이터λ₯Ό λ‹€λ₯Έ μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ μ‚¬μš©ν•  수 있음. λ˜ν•œ, ꡬ글 지도 APIλ₯Ό μ‚¬μš©ν•˜λ©΄ λ‹€λ₯Έ μ›Ήμ‚¬μ΄νŠΈμ—μ„œ Google 지도λ₯Ό μ‰½κ²Œ 톡합할 수 있음. 
οΌƒ μΈν„°νŽ˜μ΄μŠ€(Interface) : μ„œλ‘œ λ‹€λ₯Έ 두 λŒ€μƒμ΄ μƒν˜Έμž‘μš©ν•  수 μžˆλ„λ‘ μ€‘κ°„μ—μ„œ μ—°κ²°ν•΄μ£ΌλŠ” 연결고리

 

// ajax -> 비동기톡신 방법

// j쿼리에 μ ‘κ·Ό -> $.
// ajax λ©”μ†Œλ“œ μ‚¬μš© -> ajax()
// λ°μ΄ν„°λŠ” JSON ν˜•νƒœλ‘œ -> {key:value, ~}

let movieUrl = 'http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt=20230501';

const getAPI = ()=>{
    $.ajax({
        // μ–΄λŠ 데이터λ₯Ό κ°€μ Έμ˜¬ 건지
        url : movieUrl,
        // μ–΄λ–€ λ°©μ‹μœΌλ‘œ 톡신할 건지
        type : 'get',
        // 톡신 성곡 μ‹œ μ‹€ν–‰ 둜직
        success : (response)=>{
            // alert('톡신 성곡!')
            // μˆœμœ„ -> rank
            // μ˜ν™”μ œλͺ© -> movieNm
            // κ°œλ΄‰μΌ -> openDt

            let movieList = response.boxOfficeResult.dailyBoxOfficeList;

            // ν…Œμ΄λΈ”μ΄ 좜λ ₯될 곡간인 container에 보내쀄 μ½”λ“œλ₯Ό λˆ„μ ν•΄μ„œ μž‘μ„±ν•΄μ€€ λ‹€μŒ λ§ˆμ§€λ§‰μ— λ„£μ–΄μ£Όμž!
            
            let tableFoam = `
            <table>
                <tr>
                    <th>μˆœμœ„</td>
                    <th>μ˜ν™”μ œλͺ©</td>
                    <th>κ°œλ΄‰μΌ</td>
                </tr>
            `;

            for(let i of movieList){
            tableFoam += `
                <tr>
                    <td>${i.rank}</td>
                    <td>${i.movieNm}</td>
                    <td>${i.openDt}</td>
                </tr>`
            }

            tableFoam += `
            </table>
            `;

            $('.container').html(tableFoam);

        },

        // 톡신 μ‹€νŒ¨ μ‹œ μ‹€ν–‰ 둜직
        error : ()=>{
            alert('톡신 μ‹€νŒ¨!');
        }
    })
}

 

βš™ API Url κ°€μ Έμ˜€κΈ°

 

λ°˜μ‘ν˜•