์ ํ์(Selectors), DOM ํ์/์กฐ์, attr vs prop, ์ด๋ฒคํธ ์์(.on), ์ฌ๋ผ์ด๋/ํ์ด๋ ์ ๋๋ฉ์ด์
, Ajax ํต์ (serialize/Promise), ์ ํธ๋ฆฌํฐ ๋ฐ Vanilla JS ๋์ฒด ๋น๊ต ํต ๋ ํผ๋ฐ์ค
## 1. jQuery ๋์
& ์์ (CDN & Ready)
์ต์ jQuery 3.7.x ๋ฒ์ ์ CDN ๋๋ ๋ชจ๋ ๋ฒ๋ค๋ฌ๋ก ํ๋ก์ ํธ์ ํฌํจํ๊ณ DOM ์ค๋น ์๋ฃ ์์ ์ ์์ ํ๊ฒ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค.
```html
<!-- ๐ [1] ๊ณต์ CDN ํฌํจ (HTML <head> ๋๋ <body> ํ๋จ์ ์ถ๊ฐ) -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- ๊ตฌ๊ธ CDN (์์ ์ , ๋น ๋ฅธ ์บ์ ๊ณต์ ) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
```
```javascript
// โก [2] DOM ์ค๋น ์๋ฃ(Document Ready) ํ์ค ๋ฌธ๋ฒ
// DOM ํธ๋ฆฌ๊ฐ ์์ฑ๋๋ฉด ์คํ (์ด๋ฏธ์ง ๋ฑ ์ ์ฒด ๋ฆฌ์์ค ๋ก๋๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์์)
$(function() {
console.log("DOM ๋ก๋ ์๋ฃ! jQuery ์ค๋น๋จ.");
});
// ์ ํต์ ์ธ ์ ์ฒด ๋ฌธ๋ฒ (๋์ผ ๋์)
$(document).ready(function() {
// ์ด๊ธฐํ ์ฝ๋
});
// ๐ผ๏ธ [3] ๋ชจ๋ ์ด๋ฏธ์ง, ํ๋ ์ ๋ฑ ์ ์ฒด ๋ฆฌ์์ค ๋ก๋ ์๋ฃ ๊ฐ์ง
$(window).on('load', function() {
console.log("๋ชจ๋ ์์
(์ด๋ฏธ์ง ๋ฑ) ๋ก๋ ์๋ฃ");
});
// ๐ก๏ธ [4] ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ $ ์ถฉ๋ ๋ฐฉ์ง (noConflict)
var $jq = jQuery.noConflict();
$jq(function() {
$jq('#title').text("์ถฉ๋ ์์ด ์คํ!");
});
```
## 2. ์ ํ์ ์๋ฒฝ ์ ๋ฆฌ (Selectors)
CSS3 ์ ํ์ ๋ฌธ๋ฒ์ ์๋ฒฝํ ์ง์ํ๋ฉฐ, jQuery ์ ์ฉ ๊ฐ๋ ฅํ ํํฐ ์ ํ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
```javascript
// ๐ฏ [1] ๊ธฐ๋ณธ ์ ํ์
$('div') // ํ๊ทธ ์ ํ
$('#userId') // ID ์ ํ (๋จ์ผ)
$('.active-item') // ํด๋์ค ์ ํ
$('h1, h2, p.intro') // ๋ณต์(๋ค์ค) ์ ํ
$('*') // ๋ฌธ์ ์ ์ฒด ์๋ฆฌ๋จผํธ
// ๐ฒ [2] ๊ณ์ธต ์ ํ์
$('ul li') // ์์ ์ ํ์ (๋ชจ๋ ํ์ li)
$('ul > li') // ์์ ์ ํ์ (์ง๊ณ ์์ li๋ง)
$('label + input') // ์ธ์ ํ์ (label ๋ฐ๋ก ๋ค์ ์ค๋ input 1๊ฐ)
$('h2 ~ p') // ์ผ๋ฐ ํ์ (h2 ๋ค์ ๋ํ๋๋ ๋ชจ๋ ํ์ p)
// ๐ท๏ธ [3] ์์ฑ(Attribute) ์ ํ์
$('input[type="text"]') // ์์ฑ ์ ํํ ์ผ์น
$('a[href^="https://"]') // ์์ฑ ์์๊ฐ ์ผ์น (^=)
$('img[src$=".png"]') // ์์ฑ ์ข
๋ฃ๊ฐ ์ผ์น ($=)
$('a[href*="google"]') // ์์ฑ ๋ถ๋ถ ํฌํจ (*=)
$('input[type!="hidden"]') // ์์ฑ ๋ถ์ผ์น (!=)
// ๐ [4] ์์น ๋ฐ ์ํ ํํฐ ์ ํ์
$('li:first') // ์ฒซ ๋ฒ์งธ ์์ (.first()์ ๋์ผ)
$('li:last') // ๋ง์ง๋ง ์์ (.last()์ ๋์ผ)
$('li:eq(2)') // ์ธ๋ฑ์ค 2๋ฒ ์์ (0๋ถํฐ ์์, ์ฆ 3๋ฒ์งธ)
$('li:gt(2)') // ์ธ๋ฑ์ค 2 ์ด๊ณผ (3๋ฒ์งธ ์ดํ)
$('li:lt(2)') // ์ธ๋ฑ์ค 2 ๋ฏธ๋ง (0, 1๋ฒ์งธ)
$('tr:even') // ์ง์ ์ธ๋ฑ์ค (0, 2, 4...)
$('tr:odd') // ํ์ ์ธ๋ฑ์ค (1, 3, 5...)
$(':header') // ๋ชจ๋ ํค๋ฉ(h1 ~ h6)
// ๐ [5] ํผ(Form) ์ ์ฉ ์ ํ์
$(':input') // input, textarea, select, button ์ ์ฒด
$(':text') // type="text"
$(':checkbox') // type="checkbox"
$(':radio') // type="radio"
$(':checked') // ์ฒดํฌ๋ ์ฒดํฌ๋ฐ์ค/๋ผ๋์ค
$(':selected') // select ๋๋กญ๋ค์ด์์ ์ ํ๋ <option>
$(':disabled') // ๋นํ์ฑํ๋ ์
๋ ฅ์ฐฝ
$(':enabled') // ํ์ฑํ๋ ์
๋ ฅ์ฐฝ
```
## 3. DOM ํธ๋ฆฌ ํ์ (Traversing)
์ ํํ ์์๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถ๋ชจ, ์์, ํ์ ์์๋ก ์ด๋ํฉ๋๋ค.
```javascript
// โฌ๏ธ [1] ๋ถ๋ชจ / ์กฐ์ ํ์
$('#myInput').parent(); // ๋ฐ๋ก ์ ์ง๊ณ ๋ถ๋ชจ 1๋จ๊ณ
$('#myInput').parents('div.form-group'); // ์์ ์กฐ์ ์ค ์กฐ๊ฑด์ ๋ง๋ ์์๋ค
$('#myInput').closest('.card'); // โ
๊ฐ์ฅ ๊ฐ๊น์ด ์์ ์กฐ์ ํ์ (์ด๋ฒคํธ ์์ ํ์)
$('#myInput').parentsUntil('body'); // body ์ ๊น์ง์ ๋ชจ๋ ์กฐ์
// โฌ๏ธ [2] ์์ / ์์ ํ์
$('#menuList').children(); // ์ง๊ณ ์์ ์๋ฆฌ๋จผํธ๋ค
$('#menuList').children('li.active');// ์ง๊ณ ์์ ์ค active ํด๋์ค๋ง
$('#menuList').find('.sub-link'); // โ
๋ชจ๋ ํ์ ๊น์ ์์ ๊ฒ์ (๋๋จํ ๋น ๋ฆ)
// โ๏ธ [3] ํ์ (Sibling) ํ์
$('.current').siblings(); // ๋๋ฅผ ์ ์ธํ ๋ชจ๋ ํ์ ์์
$('.current').next(); // ๋ฐ๋ก ๋ค์ ํ์ 1๊ฐ
$('.current').nextAll(); // ๋ค์ ๋์ค๋ ๋ชจ๋ ํ์
$('.current').prev(); // ๋ฐ๋ก ์ด์ ํ์ 1๊ฐ
$('.current').prevAll(); // ์์ ์์นํ ๋ชจ๋ ํ์
// ๐ฏ [4] ํํฐ๋ง & ์ฒด์ด๋
$('li').first(); // ๋ชฉ๋ก์ ์ฒซ ๋ฒ์งธ li
$('li').last(); // ๋ชฉ๋ก์ ๋ง์ง๋ง li
$('li').eq(3); // 4๋ฒ์งธ li ์ ํ
$('li').filter('.special'); // ์กฐ๊ฑด์ ๋ง๋ ๊ฒ๋ง ๋จ๊ธฐ๊ธฐ
$('li').not('.disabled'); // ์กฐ๊ฑด์ ๋ง๋ ๊ฒ ์ ์ธํ๊ธฐ
$('div').has('p'); // p ํ๊ทธ๋ฅผ ์์์ผ๋ก ๊ฐ์ง div๋ง ํํฐ
```
## 4. DOM ์กฐ์ ๋ฐ ์์ ์ฝ์
/์ญ์ (Manipulation)
์ฝํ
์ธ ํ
์คํธ, HTML, ์์ฑ ์ ์ด ๋ฐ ์์๋ฅผ ๋์ ์ผ๋ก ์ถ๊ฐ/์ญ์ ํฉ๋๋ค.
```javascript
// ๐ [1] ํ
์คํธ, HTML, Input Value ์ ์ด
$('#msg').text(); // ํ
์คํธ ์กฐํ
$('#msg').text('์๋ก์ด ์ผ๋ฐ ํ
์คํธ'); // ํ
์คํธ ๋ณ๊ฒฝ (HTML ํ๊ทธ ์ด์ค์ผ์ดํ)
$('#box').html(); // ๋ด๋ถ HTML ์กฐํ
$('#box').html('<strong>๊ฐ์กฐ</strong>'); // HTML ๋ ๋๋ง ๋ณ๊ฒฝ
$('#username').val(); // input/select ์
๋ ฅ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
$('#username').val('lucky'); // input ์
๋ ฅ๊ฐ ์ค์
// ๐ท๏ธ [2] ์์ฑ(Attribute) vs ํ๋กํผํฐ(Property) โ
์ฃผ์!
// .attr() : HTML ์์ค์ ์์ฑ๋ ์๋ณธ ์์ฑ ๋ฌธ์์ด
// .prop() : ๋ธ๋ผ์ฐ์ ๊ฐ ๊ด๋ฆฌํ๋ ์ค์๊ฐ ๋ถ๋ฆฌ์ธ ์ํ (checked, disabled, selected)
$('#chkAgree').prop('checked'); // true / false ๋ฐํ (๊ถ์ฅ!)
$('#chkAgree').prop('checked', true);// ์ฒดํฌ ํ์ฑํ
$('#btnSubmit').prop('disabled', true); // ๋ฒํผ ๋นํ์ฑํ
$('#myLink').attr('href', 'https://example.com');
$('#myLink').removeAttr('target');
// ๐พ [3] HTML5 data-* ์์ฑ ๋ค๋ฃจ๊ธฐ
$('#item').data('role', 'admin'); // ๋ฉ๋ชจ๋ฆฌ ์์ data-role ๋ฐ์ธ๋ฉ
const role = $('#item').data('role');// 'admin' ์กฐํ
// โ [4] ์์ ์ถ๊ฐ (๋ด๋ถ / ์ธ๋ถ ์ฝ์
)
// ๋ด๋ถ(Inside) ์ถ๊ฐ
$('#list').append('<li>๋ง์ง๋ง ์์์ผ๋ก ์ถ๊ฐ</li>');
$('#list').prepend('<li>์ฒซ ๋ฒ์งธ ์์์ผ๋ก ์ถ๊ฐ</li>');
$('<li>์ ํญ๋ชฉ</li>').appendTo('#list'); // ์ฃผ์ด-๋ชฉ์ ์ด ๋ฐ๋ ๊ตฌ๋ฌธ
// ์ธ๋ถ(Outside) ์ถ๊ฐ
$('#target').after('<div class="note">ํ๊ฒ ๋ฐ๋ก ๋ค(ํ์ ) ์ถ๊ฐ</div>');
$('#target').before('<div class="note">ํ๊ฒ ๋ฐ๋ก ์(ํ์ ) ์ถ๊ฐ</div>');
// ๐๏ธ [5] ์์ ์ญ์ ๋ฐ ๋น์ฐ๊ธฐ
$('#modal').empty(); // ๋ด๋ถ ์์ ์์๋ค๋ง ์ ๋ถ ์ญ์ (๋ฐ์ค๋ ์ ์ง)
$('#tempItem').remove(); // ์์ ์์ฒด๋ฅผ DOM์์ ์์ ํ ์ญ์
$('#cachedItem').detach(); // DOM์์๋ ๋นผ์ง๋ง ์ด๋ฒคํธ/๋ฐ์ดํฐ๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ง
$('#item').clone(true); // ์ด๋ฒคํธ ํธ๋ค๋ฌ๊น์ง ๋ณต์ (true ์ต์
)
```
## 5. CSS ์คํ์ผ & ํด๋์ค ์กฐ์
์คํ์ผ์ํธ ํด๋์ค๋ฅผ ํ ๊ธํ๊ฑฐ๋ ์ธ๋ผ์ธ ์คํ์ผ, ์์์ ์ขํ์ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํฉ๋๋ค.
```javascript
// ๐จ [1] ํด๋์ค(Class) ์กฐ์ (๊ฐ์ฅ ๊ถ์ฅ๋๋ UI ๋ณ๊ฒฝ ๋ฐฉ์)
$('#btn').addClass('active'); // ํด๋์ค ์ถ๊ฐ (๊ณต๋ฐฑ ๊ตฌ๋ถ ๋ค์ค ์ถ๊ฐ ๊ฐ๋ฅ)
$('#btn').removeClass('active'); // ํด๋์ค ์ ๊ฑฐ
$('#btn').toggleClass('dark-mode'); // ์์ผ๋ฉด ์ถ๊ฐ, ์์ผ๋ฉด ์ ๊ฑฐ
$('#btn').hasClass('active'); // ํด๋์ค ๋ณด์ ์ฌ๋ถ (true / false)
// ๐๏ธ [2] ์ธ๋ผ์ธ CSS ์คํ์ผ ์กฐ์
$('#alert').css('color', '#ff4d4f'); // ๋จ์ผ ์คํ์ผ ๋ณ๊ฒฝ
$('#alert').css({ // ๊ฐ์ฒด๋ก ๋ค์ค ์คํ์ผ ์ผ๊ด ๋ณ๊ฒฝ
backgroundColor: '#fff1f0',
border: '1px solid #ffa39e',
fontSize: '14px',
display: 'block'
});
// ๐ [3] ํฌ๊ธฐ(Width & Height) ๊ณ์ฐ
const w1 = $('#box').width(); // ์์ ์ปจํ
์ธ ๋๋น
const w2 = $('#box').innerWidth(); // ์ปจํ
์ธ + padding ๋๋น
const w3 = $('#box').outerWidth(); // ์ปจํ
์ธ + padding + border ๋๋น
const w4 = $('#box').outerWidth(true); // ์ปจํ
์ธ + padding + border + margin ๋๋น
// ๐ [4] ์คํฌ๋กค ๋ฐ ์์น ์ขํ
const offset = $('#box').offset(); // document(๋ฌธ์ ์ ์ฒด) ๊ธฐ์ค { top, left } ์ขํ
const pos = $('#box').position(); // ๋ถ๋ชจ ์ปจํ
์ด๋ ๊ธฐ์ค { top, left } ์๋ ์ขํ
$(window).scrollTop(); // ํ์ฌ ์์ง ์คํฌ๋กค ๋ฐ ์์น
$('html, body').animate({ scrollTop: 0 }, 300); // ๋ถ๋๋ฝ๊ฒ ํ์ด์ง ๋งจ ์๋ก ์คํฌ๋กค
```
## 6. ์ด๋ฒคํธ ํธ๋ค๋ง & ์ด๋ฒคํธ ์์ (.on)
๋ชจ๋ ์น ๊ฐ๋ฐ์์ ๋์ ์ผ๋ก ์์ฑ๋๋ ์๋ฆฌ๋จผํธ๊น์ง ์ฒ๋ฆฌํ๊ธฐ ์ํด `.on()`์ ์ฌ์ฉํฉ๋๋ค.
```javascript
// โก [1] ํ์ค ์ด๋ฒคํธ ๋ฆฌ์ค๋ (.on)
$('#myBtn').on('click', function(e) {
e.preventDefault(); // ๊ธฐ๋ณธ ํผ ์ ์ถ ๋๋ ๋งํฌ ์ด๋ ์ทจ์
e.stopPropagation(); // ๋ถ๋ชจ ์์๋ก์ ์ด๋ฒคํธ ๋ฒ๋ธ๋ง ์ฐจ๋จ
alert('๋ฒํผ ํด๋ฆญ๋จ!');
});
// ๐ฏ [2] ์ด๋ฒคํธ ์์(Event Delegation) โ
๋๋จํ ์ค์!
// ํ์ด์ง ๋ก๋ ํ ๋์ ์ผ๋ก append๋ .dynamic-btn๋ ์ ์ ์๋ํ๋๋ก ์์ ๋ถ๋ชจ์ ๋ฐ์ธ๋ฉ
$(document).on('click', '.dynamic-btn', function() {
const itemId = $(this).data('id');
console.log('๋์ ๋ฒํผ ํด๋ฆญ! ID:', itemId);
});
// ๐ [3] ์ฌ๋ฌ ์ด๋ฒคํธ ๋์ ๋ฐ์ธ๋ฉ
$('#search').on({
focus: function() { $(this).addClass('focused'); },
blur: function() { $(this).removeClass('focused'); },
keydown: function(e) {
if (e.key === 'Enter') {
console.log('์ํฐํค ๊ฐ์ง:', $(this).val());
}
}
});
// 1๏ธโฃ [4] ๋จ 1ํ๋ง ์คํ๋๋ ์ด๋ฒคํธ (.one)
$('#buyBtn').one('click', function() {
console.log('๊ฒฐ์ ์์ฒญ์ ๋จ 1๋ฒ๋ง ๋ฐ์ก๋ฉ๋๋ค.');
});
// ๐ซ [5] ์ด๋ฒคํธ ํด์ (.off)
$('#myBtn').off('click'); // click ์ด๋ฒคํธ ๋ฆฌ์ค๋ ํด์
// ๐ข [6] ์๋ ์ด๋ฒคํธ ํธ๋ฆฌ๊ฑฐ (.trigger)
$('form#login').trigger('submit'); // ๊ฐ์ ๋ก submit ์ด๋ฒคํธ ๋ฐ์
$('#btnRefresh').trigger('click'); // ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ํด๋ฆญ ์คํ
```
## 7. ํจ๊ณผ & ์ ๋๋ฉ์ด์
(Effects & Animation)
๊ฐ๋จํ ์ ๋๋ฉ์ด์
์ผ๋ก ๋ชจ๋ฌ ์ฐฝ, ๋๋กญ๋ค์ด ์์ฝ๋์ธ ๋ฉ๋ด๋ฅผ ๊ตฌํํฉ๋๋ค.
```javascript
// ๐๏ธ [1] ๊ธฐ๋ณธ ํ์/์จ๊น (Display None <-> Block)
$('#menu').show(300); // 0.3์ด ๋์ ํผ์ณ์ง๋ฉฐ ํ์
$('#menu').hide('fast'); // ๋น ๋ฅด๊ฒ ์จ๊น ('slow', 'fast', ๋ฐ๋ฆฌ์ด)
$('#menu').toggle(); // ์ํ ๋ฐ์
// ๐ซ๏ธ [2] ํ์ด๋(Fade) ํจ๊ณผ (ํฌ๋ช
๋ opacity ์กฐ์ )
$('#popup').fadeIn(400); // ์์ํ ๋ํ๋จ
$('#popup').fadeOut(400); // ์์ํ ์ฌ๋ผ์ง
$('#popup').fadeToggle(); // ํ์ด๋ ํ ๊ธ
$('#banner').fadeTo('slow', 0.5); // ํน์ ํฌ๋ช
๋(0.5)๋ก ๋ณ๊ฒฝ
// ๐ [3] ์ฌ๋ผ์ด๋(Slide) ํจ๊ณผ (์์ฝ๋์ธ, ๋๋กญ๋ค์ด ํ์)
$('#accordion-body').slideDown(); // ์๋๋ก ํผ์น๊ธฐ
$('#accordion-body').slideUp(); // ์๋ก ์ ๊ธฐ
$('#faq-answer').slideToggle(200); // ์ฌ๋ผ์ด๋ ์ด๋ฆผ/๋ซํ ํ ๊ธ
// ๐ฌ [4] ์ปค์คํ
์ ๋๋ฉ์ด์
(.animate)
$('#box').animate({
left: '+=200px',
opacity: 0.8,
height: '250px'
}, 500, function() {
console.log('์ ๋๋ฉ์ด์
์ข
๋ฃ ์ฝ๋ฐฑ ์คํ');
});
// ๐ [5] ์ ๋๋ฉ์ด์
ํ ์ ์ด (๋ฒํผ ์ฐํ ๋ฒ๊ทธ ๋ฐฉ์ง โ
)
// .stop(clearQueue, jumpToEnd)
$('#dropdown').stop(true, true).slideToggle(200); // ํ๋ฅผ ๋น์ฐ๊ณ ์ฆ์ ์ต์ ์ํ๋ก ํ ๊ธ
```
## 8. Ajax ๋น๋๊ธฐ HTTP ํต์ (jQuery.ajax)
REST API ์๋ฒ์ JSON ํต์ ์ ์ฒ๋ฆฌํ๋ ํ์ค ๋ฐฉ์์
๋๋ค.
```javascript
// ๐ [1] ํ์ค $.ajax() ์ ์ฒด ์ต์
๊ตฌ์กฐ (Promise ์คํ์ผ)
$.ajax({
url: '/api/users',
type: 'POST', // HTTP ๋ฉ์๋ (GET, POST, PUT, DELETE)
dataType: 'json', // ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ๋ฐ์ดํฐ ํ์ (json, text, html)
contentType: 'application/json; charset=utf-8', // ์์ฒญ ํค๋
data: JSON.stringify({ name: 'Lucky', email: 'lucky@example.com' }),
timeout: 5000, // 5์ด ํ์์์
})
.done(function(response, textStatus, jqXHR) {
console.log('์์ฒญ ์ฑ๊ณต:', response);
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.error('์๋ฌ ๋ฐ์ ์ฝ๋:', jqXHR.status, '๋ฉ์์ง:', errorThrown);
})
.always(function() {
console.log('์ฑ๊ณต/์คํจ ์ฌ๋ถ์ ๊ด๊ณ์์ด ์๋ฃ ํ ํญ์ ์คํ (๋ก๋ฉ ์คํผ๋ ์ข
๋ฃ)');
});
// โก [2] ๊ฐํธ ๋จ์ถ ๋ฉ์๋ (GET & POST)
$.get('/api/users?page=1', function(data) {
console.log('์ฌ์ฉ์ ๋ชฉ๋ก:', data);
});
$.post('/api/logout', { userId: 10 }, function(res) {
console.log('๋ก๊ทธ์์ ์๋ฃ');
});
// ๐ [3] Form ๋ฐ์ดํฐ ์ง๋ ฌํ (Serialization)
// ์ฟผ๋ฆฌ์คํธ๋ง ํํ ์ง๋ ฌํ: "name=Lucky&email=test%40test.com"
const queryString = $('#registerForm').serialize();
// ๊ฐ์ฒด ๋ฐฐ์ด ์ง๋ ฌํ: [{ name: 'username', value: 'Lucky' }, ...]
const formArray = $('#registerForm').serializeArray();
// ๐ [4] ํ์ผ ์
๋ก๋(FormData) Ajax ์ ์ก ์ ํ์ ์ต์
const formData = new FormData($('#uploadForm')[0]);
$.ajax({
url: '/api/upload',
type: 'POST',
data: formData,
processData: false, // โ
jQuery๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฟผ๋ฆฌ์คํธ๋ง์ผ๋ก ๋ณํํ์ง ์๋๋ก ์ค์
contentType: false, // โ
multipart/form-data ํค๋ ์๋ ์ค์ ํ์ฉ
success: function(res) { alert('์
๋ก๋ ์ฑ๊ณต!'); }
});
// ๐ [5] ์ ์ญ Ajax ๋ก๋ฉ ์ธ๋์ผ์ดํฐ
$(document).ajaxStart(function() { $('#globalSpinner').show(); });
$(document).ajaxStop(function() { $('#globalSpinner').hide(); });
```
## 9. ์ ํธ๋ฆฌํฐ ํจ์ (Utility Functions)
๋ฐฐ์ด/๊ฐ์ฒด ๊ฐ๊ณต ๋ฐ ํ์
๊ฒ์ฆ์ ์ํ ํฌํผ ํจ์๋ค์
๋๋ค.
```javascript
// ๐ [1] $.each: ๋ฐฐ์ด ๋ฐ ๊ฐ์ฒด ๋ฐ๋ณต ์ํ
const users = ['Alice', 'Bob', 'Charlie'];
$.each(users, function(index, name) {
console.log(`์ธ๋ฑ์ค: ${index}, ์ด๋ฆ: ${name}`);
});
const config = { host: 'localhost', port: 8080 };
$.each(config, function(key, value) {
console.log(`${key} => ${value}`);
});
// ๐บ๏ธ [2] $.map & $.grep (๋ฐฐ์ด ๋ณํ & ํํฐ๋ง)
const numbers = [1, 2, 3, 4, 5];
const doubled = $.map(numbers, (num) => num * 2); // [2, 4, 6, 8, 10]
const evens = $.grep(numbers, (num) => num % 2 === 0); // [2, 4]
// ๐ [3] $.inArray: ๋ฐฐ์ด ๋ด๋ถ ๊ฒ์ (indexOf ๋์ฒด, ์์ผ๋ฉด -1)
const idx = $.inArray('Bob', users); // 1
// ๐งฉ [4] $.extend: ๊ฐ์ฒด ๋ณํฉ (Object.assign ๋ฐ ๋ฅ์นดํผ ๋์ฒด)
const defaults = { theme: 'light', debug: false };
const options = { debug: true, lang: 'ko' };
// ์ฒซ ๋ฒ์งธ ์ธ์์ true๋ฅผ ์ ๋ฌํ๋ฉด ๋ฅ ์นดํผ(Deep Copy) ์ํ
const merged = $.extend(true, {}, defaults, options);
// ๐ท๏ธ [5] ํ์
๊ฒ์ฌ ํจ์๋ค
$.isArray([1, 2, 3]); // true
$.isEmptyObject({}); // true
$.isNumeric('123.45'); // true
$.trim(' hello world '); // "hello world"
```
## 10. ๋ฐ๋๋ผ ์๋ฐ์คํฌ๋ฆฝํธ(Native JS) 1:1 ๋์ฒด ๊ฐ์ด๋
๋ชจ๋ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ jQuery ์์ด ์์ Vanilla JS๋ก ์์ฑํ ๋์ 1:1 ๋์ํ์
๋๋ค.
```javascript
// ๐ [1] ์์ ์ ํ
// jQuery: const el = $('#myId');
// Vanilla: const el = document.getElementById('myId'); (๋๋ document.querySelector('#myId'))
// jQuery: const list = $('.item');
// Vanilla: const list = document.querySelectorAll('.item');
// ๐จ [2] ํด๋์ค ์กฐ์
// jQuery: $el.addClass('active');
// Vanilla: el.classList.add('active');
// jQuery: $el.removeClass('active');
// Vanilla: el.classList.remove('active');
// jQuery: $el.toggleClass('active');
// Vanilla: el.classList.toggle('active');
// ๐ [3] ํ
์คํธ & ๊ฐ ์กฐ์
// jQuery: $el.text('Hello'); -> Vanilla: el.textContent = 'Hello';
// jQuery: $el.html('<b>Hi</b>'); -> Vanilla: el.innerHTML = '<b>Hi</b>';
// jQuery: $input.val('Lucky'); -> Vanilla: input.value = 'Lucky';
// โ [4] ์์ ์ถ๊ฐ ๋ฐ ์ญ์
// jQuery: $parent.append($child);
// Vanilla: parent.append(child); (๋๋ parent.insertAdjacentHTML('beforeend', '<div>๋ด์ฉ</div>');)
// jQuery: $el.remove();
// Vanilla: el.remove();
// โก [5] ์ด๋ฒคํธ ๋ฆฌ์ค๋
// jQuery: $btn.on('click', handler);
// Vanilla: btn.addEventListener('click', handler);
// ๐ [6] Ajax ํต์
// jQuery: $.getJSON('/api/data').done(callback);
// Vanilla: fetch('/api/data').then(res => res.json()).then(callback);
```
์๊ฒฌ ๋ฐ ์ง๋ฌธ
0์์ง ๋ฑ๋ก๋ ์๊ฒฌ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋๊ธ์ ๋จ๊ฒจ๋ณด์ธ์!
๋๊ธ ์์
๋๊ธ ์ญ์