๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Frontend/JavaScript

[ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ(JavaScript) ] ์ด๋ฏธ์ง€ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ

by YWTechIT 2022. 1. 4.
728x90

๐Ÿ“ drag and drop ๊ตฌํ˜„ํ•˜๊ธฐ

์ด๊ฑฐ ๋จน์–ด๋ด„? ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉด์„œ ์‚ฌ์ง„์„ ์„œ๋ฒ„์— ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด๋ณผ๊นŒ ํ•˜๋‹ค๊ฐ€ ํ‰์†Œ ์šฐ๋ฆฌ๊ฐ€ ์›น์‚ฌ์ดํŠธ์— ์ž์ฃผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ธ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๋ ค๋ฉด ๋“œ๋ž˜๊ทธํ•˜๊ฑฐ๋‚˜ ํด๋ฆญํ•˜์„ธ์š”๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๋‹ค. ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ๊ตฌ๊ธ€๋ง ํ•ด๋ณด๋‹ˆ๊นŒ drag-drop์ด๋ผ๋Š” npm ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์žˆ์—ˆ์ง€๋งŒ, ๊ตณ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ MDN์—์„œ ์ œ๊ณตํ•˜๋Š” HTML ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ API์„ ํ†ตํ•ด์„œ๋„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๊ณ  ์ง์ ‘ ๋ฐ”๋‹๋ผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค. ํ•˜๋‹จ์˜ gif๋ฅผ ํ†ตํ•ด ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. codePen์˜ ์˜ˆ์ œ์—์„œ๋Š” ํŒŒ์ผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ•จ์ˆ˜ ์ฝ”๋“œ๋Š” ์ œ๊ฑฐํ–ˆ๋‹ค.

 

 

See the Pen image-drag-and-drop by an (@YWTechIT) on CodePen.

 


728x90

๐Ÿค– ์ž์„ธํ•œ ์ฝ”๋“œ๋Š” ๊นƒํ—ˆ๋ธŒ ์ฐธ๊ณ 

 

์šฐ์„ , ํด๋ฆญํ•˜์—ฌ ํŒŒ์ผ์„ ์—…๋กœ๋“œ๋ฅผ ํ•  ๋•Œ๋Š” drag์ด๋ฒคํŠธ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  inputํƒœ๊ทธ์— addEventListener('change', handleUpdate)๋ฅผ ๋ถ™์—ฌ์„œ ๊ตฌํ˜„ํ–ˆ๋‹ค. ์ด๋•Œ input ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ–ˆ๋‹ค. ๊ฐ attribute๋ณ„๋กœ ์–ด๋–ค ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”์ง€ ์‚ดํŽด๋ณด์ž. accept๋Š” ํŒŒ์ผ ์œ ํ˜•์„ ์˜๋ฏธํ•˜๊ณ  type์€ ํŒŒ์ผ์„, required๋Š” form ์–‘์‹์—์„œ ๊ผญ ํ•„์š”ํ•œ ๊ฐ’์„ ์˜๋ฏธํ•˜๊ณ , multiple์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค. hidden์€ label์„ ์—ฐ๊ฒฐํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด true๋กœ ๋„ฃ์–ด ๊ฒ‰์œผ๋กœ ๋ณด์ด์ง€ ์•Š๊ฒŒ ์„ค์ •ํ–ˆ๋‹ค.

<input id="input" class="input" accept="image/*" type="file" required="true" multiple="true" hidden="true">

์—ฌ๊ธฐ์„œ ์ž ๊น ์งš๊ณ  ๋„˜์–ด๊ฐˆ ๊ฒƒ์ด accept๋ฅผ image/*๋กœ ์„ค์ •ํ–ˆ๋‹ค๊ณ  ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ์ง€ ํŒŒ์ผ๋งŒ ์˜ฌ๋ฆฐ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํฐ ์˜ค์‚ฐ์ด๋‹ค. MDN์—์„œ๋„ input accept ์œ ํ˜•์€ ์„ ํƒํ•œ ํŒŒ์ผ ์œ ํ˜•์„ ๊ฒ€์ฆํ•˜์ง€๋Š” ์•Š์œผ๋ฉฐ, ๋‹จ์ˆœํžˆ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ํŒŒ์ผ ์œ ํ˜•์œผ๋กœ ์œ ๋„ํ•˜๋„๋ก ํžŒํŠธ๋ฅผ ์ œ๊ณตํ•  ๋ฟ์ด๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์˜ต์…˜์„ ๋ฐ”๊พธ๋ฉด ๋‹ค๋ฅธ ํ˜•ํƒœ์˜ ํŒŒ์ผ๋„ ๊ฒŒ์‹œํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์„œ๋ฒ„์‚ฌ์ด๋“œ์—์„œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ํ†ตํ•ด accept ํŠน์„ฑ์„ ๋ณด์กฐํ•ด์•ผ ํ•œ๋‹ค๋ผ๊ณ  ๋ช…์‹œ๋˜์–ด์žˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ๋‚˜๋Š” ํ”„๋ก ํŠธ๋‹จ์—์„œ ํ•„ํ„ฐ ์—ญํ• ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํŒŒ์ผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์คฌ๋‹ค. isValidType์™€ isValidSize์ธ ํ•จ์ˆ˜๋ฅผ ํ†ต๊ณผํ•œ ํŒŒ์ผ์— ๋Œ€ํ•ด์„œ๋งŒ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค์ •ํ–ˆ๋‹ค.

 

์—ฌ๋Ÿฌ ๊ฐœ์˜ drag event (drag, dragend, dragenter, dragexit, dragleave, dragover, dragstart, drop) ์ค‘ dragenter์™€ dragleave ์ด๋ฒคํŠธ๋กœ ํ•ด๋‹น label์— ๋“œ๋ž˜๊ทธํ•˜๋ฉด์„œ ๋“ค์–ด์™”์„ ๋•Œ์™€ ๋‚˜๊ฐ”์„ ๋•Œ๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ hover๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ๊ณ , drop ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์„ label์— ๋“œ๋กญํ–ˆ์„ ๋•Œ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.

 

๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DataTransfer ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, event.dataTransfer?.files๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์ „์†ก์— ํ•„์š”ํ•œ ํŒŒ์ผ์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š” ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  ์ด ๊ฐ’์„ ํ† ๋Œ€๋กœ forEach๋ฌธ์„ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ ํŒŒ์ผ ๋‚ด์šฉ์— ๊ฐ๊ฐ ์ ‘๊ทผํ•˜์—ฌ fileReader๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ด๋ฏธ์ง€์˜ src๋ฅผ ์ฝ๊ณ (์ด๋•Œ src๋Š” base-64 ํ˜•ํƒœ) ๋นˆ imgํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค์–ด ์—ฌ๊ธฐ์— src๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉด ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€ ํƒœ๊ทธ๊ฐ€ ๋œ๋‹ค. ์ดํ›„์— ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ํƒœ๊ทธ์— append ํ•ด์ฃผ๋ฉด drag and drop๊ธฐ๋Šฅ์€ ๋์ด ๋‚œ๋‹ค.

 

reference

  1. MDN: HTML ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ API
  2. MDN: DataTransfer
  3. MDN: FileReader
  4. example: jsfiddle.net
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€