μ˜€λŠ˜μ€ 별도 μ»¨ν…μŠ€νŠΈλ₯Ό κ°€μ§„ μƒˆ 창을 λ„μš°λŠ” κ°œλ°œμ„ ν•˜λ©° μ•Œκ²Œλœ λ‚΄μš©μ„ 정리해보렀 ν•©λ‹ˆλ‹€.

 

window.open

 

μ™œ 아직도 window.open이 ν•„μš”ν•œκ°€?

 

μ‹œμž‘μ „μ— νŒμ—…κ³Ό λͺ¨λ‹¬μ˜ 본질적 차이뢀터 μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

νŒμ—…μ°½

  • λΈŒλΌμš°μ €κ°€ μ™„μ „νžˆ λΆ„λ¦¬λœ μƒˆ μ°½(λ˜λŠ” νƒ­)으둜 λ™μž‘
  • λΈŒλΌμš°μ €μ˜ νŒμ—… 차단 κΈ°λŠ₯에 영ν–₯을 λ°›κ³ 
  • λΆ€λͺ¨ νŽ˜μ΄μ§€μ™€ λ³„λ„μ˜ λΈŒλΌμš°μ € μ»¨ν…μŠ€νŠΈλ₯Ό κ°–μŠ΅λ‹ˆλ‹€.
  • 창의 μœ„μΉ˜, 크기, μŠ€ν¬λ‘€λ°” λ“± λ‹€μ–‘ν•œ 속성을 μ œμ–΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • λΆ€λͺ¨ 창이 μƒˆλ‘œκ³ μΉ¨λ˜κ±°λ‚˜ 이동해도 νŒμ—…μ€ μœ μ§€λ©λ‹ˆλ‹€.
  • λΈŒλΌμš°μ € νŒμ—… 차단 κΈ°λŠ₯에 μ˜ν•΄ μ‚¬μš©μžκ°€ νŒμ—…μ„ λͺ» λ³Ό 수 μžˆμœΌλ―€λ‘œ, λ°˜λ“œμ‹œ ν•„μš”ν•œ κ²½μš°μ—λ§Œ μ‚¬μš©ν•˜λŠ”κ²Œ μ’‹μŠ΅λ‹ˆλ‹€. κ·Έ μ™Έμ—λŠ” λͺ¨λ‹¬μ΄ ꢌμž₯λ©λ‹ˆλ‹€.

λͺ¨λ‹¬μ°½

  • κΈ°μ‘΄ νŽ˜μ΄μ§€ μœ„μ— μ˜€λ²„λ ˆμ΄ λ ˆμ΄μ–΄λ‘œ κ΅¬ν˜„
  • λΆ€λͺ¨ νŽ˜μ΄μ§€μ— μ’…μ†λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
  • λΈŒλΌμš°μ €μ˜ νŒμ—… 차단 κΈ°λŠ₯κ³Ό λ¬΄κ΄€ν•©λ‹ˆλ‹€.
  • λΆ€λͺ¨ νŽ˜μ΄μ§€κ°€ 이동 λ˜λŠ” μƒˆλ‘œκ³ μΉ¨λ˜λ©΄ λͺ¨λ‹¬λ„ μ‚¬λΌμ§‘λ‹ˆλ‹€.
  • λ³„λ„μ˜ λΈŒλΌμš°μ € μ»¨ν…μŠ€νŠΈκ°€ μ•„λ‹ˆλ―€λ‘œ, μ™ΈλΆ€ 도메인 νŽ˜μ΄μ§€λ₯Ό 직접 포함할 수 μ—†μŠ΅λ‹ˆλ‹€. μ΄λ•Œ iframe을 μƒκ°ν•˜μ‹€ 수 μžˆλŠ”λ° λ³΄μ•ˆμƒ μ œμ•½μ΄ λ§Žμ•„ λΆˆνŽΈν•©λ‹ˆλ‹€.

 

Reactμ—μ„œλŠ” μƒνƒœ(state)λ₯Ό ν™œμš©ν•œ 쑰건뢀 λ Œλ”λ§μœΌλ‘œ νŒμ—…μ„ κ΅¬ν˜„ν•˜κ±°λ‚˜, Toss의 μ˜€λ²„λ ˆμ΄ ν‚€νŠΈ(Overlay Kit)같은 라이브러리λ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ°λ°λ„ μ—¬μ „νžˆ window.open()이 νŽΈλ¦¬ν•˜κ±°λ‚˜ ν•„μš”ν•œ 상황이 μžˆμŠ΅λ‹ˆλ‹€.

 

  1. μ™ΈλΆ€ λ„λ©”μΈκ³Όμ˜ 연동: OAuth 인증, 결제 μ‹œμŠ€ν…œ 연동 λ“± λ‹€λ₯Έ λ„λ©”μΈμ˜ νŽ˜μ΄μ§€λ₯Ό μ—΄μ–΄μ•Ό ν•  λ•Œ
    • OAuth μΈμ¦μ΄λ‚˜ μ™ΈλΆ€ 결제 μ‹œμŠ€ν…œ 연동 μ‹œ, λ³΄μ•ˆμ΄λ‚˜ μ‚¬μš©μž 인증 ν›„ μ½œλ°±λ“±μ˜ UX 적인 이유둜 별도 창이 ν•„μš”ν•©λ‹ˆλ‹€.
    • μ΄λ•Œ window.open()을 μ‚¬μš©ν•˜λ©΄ λΆ€λͺ¨-μžμ‹ μ°½ κ°„ ν†΅μ‹ μ΄λ‚˜ μ°½ λ‹«νž˜ 감지 λ“±μ˜ μ²˜λ¦¬κ°€ μ‰¬μ›Œμ Έμš”.
    • λͺ¨λ‹¬λ‘œλŠ” μ™ΈλΆ€ 도메인 νŽ˜μ΄μ§€λ₯Ό iframe으둜 λ„μš°λŠ” 것이 CORS, X-Frame-Options λ˜λŠ” Content-Security-Policy λ“±μ˜ λ³΄μ•ˆ μ •μ±…λ“±μ˜ 이유둜 λΆˆνŽΈν•©λ‹ˆλ‹€.
  2. ν”„λ¦°νŠΈ κΈ°λŠ₯: νŠΉμ • μ½˜ν…μΈ λ§Œ ν”„λ¦°νŠΈν•˜κΈ° μœ„ν•œ 별도 창이 ν•„μš”ν•  λ•Œ
    • μƒˆ 창에 ν•΄λ‹Ή μ½˜ν…μΈ λ§Œ λ Œλ”λ§ν•˜κ³  window.print()λ₯Ό ν˜ΈμΆœν•˜λŠ” 방식이 많이 μ‚¬μš©λμŠ΅λ‹ˆλ‹€.
    • λͺ¨λ‹¬μ΄λ‚˜ μ˜€λ²„λ ˆμ΄λ‘œλŠ” 전체 νŽ˜μ΄μ§€μ˜ μΌλΆ€λ§Œ κΉ”λ”ν•˜κ²Œ μΈμ‡„ν•˜λŠ” 인쇄 λ²”μœ„ μ œμ–΄κ°€ μ–΄λ €μ›Œ κΈ°μ‘΄ νŽ˜μ΄μ§€ 전체가 μΈμ‡„λ©λ‹ˆλ‹€.
    • λ”°λΌμ„œ μƒˆ 창이 κ°€μž₯ κ°„λ‹¨ν•˜κ³  ν™•μ‹€ν•œ 방법이라 μƒκ°ν•©λ‹ˆλ‹€.
  3. λ©€ν‹°νƒœμŠ€ν‚Ή UX: μ‚¬μš©μžκ°€ 두 화면을 λ™μ‹œμ— 보며 μž‘μ—…ν•΄μ•Ό ν•  λ•Œ
    • 두 개의 창을 λ™μ‹œμ— 화면에 λ„μ›Œ μƒν˜Έ 비ꡐ μž‘μ—…ν•˜λ €λ©΄ μ°½ 뢄리가 ν•„μš”ν•©λ‹ˆλ‹€.
    • λͺ¨λ‹¬μ€ 항상 λΆ€λͺ¨ μ°½ μœ„μ— λ–  있기 λ•Œλ¬Έμ— 두 화면을 λ™μ‹œμ— λ³Ό 수 μ—†μŠ΅λ‹ˆλ‹€.
    • λ”°λΌμ„œ μƒˆ 창을 λ„μš°λŠ” 것이 μœ μΌν•œ λ°©λ²•μž…λ‹ˆλ‹€.
  4. λ ˆκ±°μ‹œ μ‹œμŠ€ν…œ 톡합: κΈ°μ‘΄ μ‹œμŠ€ν…œκ³Όμ˜ ν˜Έν™˜μ„±μ„ μœ„ν•΄ ν•„μš”ν•œ 경우
    • κΈ°μ‘΄ μ‹œμŠ€ν…œμ—μ„œ νŒμ—… 창을 ν†΅ν•œ 데이터 κ΅ν™˜μ΄λ‚˜ 인증 λ“±μ˜ ꡬ쑰가 이미 window.open()에 맞좰져 μžˆλ‹€λ©΄, 이λ₯Ό λͺ¨λ‹¬λ‘œ λŒ€μ²΄ν•˜λŠ” 경우 ν˜Έν™˜μ„± μ΄μŠˆκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  5. 별도 μœˆλ„μš° κΈ°λŠ₯: λΆ€λͺ¨ 창의 μƒˆλ‘œκ³ μΉ¨μ΄λ‚˜ 이동에도 μœ μ§€λ˜μ–΄μ•Ό ν•˜λŠ” 독립적 κΈ°λŠ₯
    • λͺ¨λ‹¬μ΄λ‚˜ SPA μ»΄ν¬λ„ŒνŠΈλ‘œλŠ” κ΅¬ν˜„μ΄ λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.
    • μƒˆλ‘œμš΄ νŒμ—…μ°½λ§Œμ΄ μ™„μ „νžˆ λ³„λ„μ˜ λΈŒλΌμš°μ € μ»¨ν…μŠ€νŠΈλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

 

이런 κ²½μš°μ—λŠ” window.open()을 μ‚¬μš©ν•΄μ•Ό ν•˜λŠ”λ°, μ•ˆμ „ν•˜κ³  μ˜¬λ°”λ₯Έ 방법을 μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

window.open('javascript:focus()', 'myPopup', 'width=800,height=600');

 

겉보기엔 잘 μž‘λ™ν•  수 μžˆμ§€λ§Œ, 이 방식은 λ³΄μ•ˆμƒ λ¬Έμ œκ°€ 있으며 κ³΅μ‹μ μœΌλ‘œ ꢌμž₯λ˜μ§€ μ•ŠλŠ” λ°©μ‹μž…λ‹ˆλ‹€.

이번 글에선 κ·Έ μ΄μœ μ— λŒ€ν•΄ μ μ–΄λ³΄λ €ν•©λ‹ˆλ‹€! λ˜ν•œ μ–΄λ–€ 방식이 μ•ˆμ „ν•˜κ³  ν‘œμ€€μ— λΆ€ν•©ν•˜λŠ”μ§€λ„ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

 

javascript:focus() λ°©μ‹μ˜ μœ„ν—˜μ„±

이 방식은 javascript: URL μŠ€ν‚΄μ„ μ΄μš©ν•΄ μƒˆ 창을 μ—΄λ©΄μ„œ focus() ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λ €λŠ” μ˜λ„μž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이런 방식은 λ³΄μ•ˆμƒ μ·¨μ•½ν•©λ‹ˆλ‹€.

 

MDN 곡식 λ¬Έμ„œμ—μ„œλŠ” λ‹€μŒκ³Ό 같이 λͺ…ν™•νžˆ κ²½κ³ ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

"Use of javascript: URLs on the web is discouraged as it may lead to execution of arbitrary code, similar to the ramifications of using eval()."

 

λ˜ν•œ, ESLintμ—μ„œλ„ no-script-url κ·œμΉ™μ„ 톡해 javascript: URL μŠ€ν‚΄ μ‚¬μš©μ„ κΈˆμ§€ν•˜κ±°λ‚˜ κ²½κ³ ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ½”λ“œκ°€ μ™ΈλΆ€ μž…λ ₯에 μ˜ν•΄ μ‘°μž‘λ˜κ±°λ‚˜ μ•…μš©λ  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

 

μš”μ•½ν•˜μžλ©΄

  • λ³΄μ•ˆμƒ μœ„ν—˜ (μž„μ˜ μ½”λ“œ μ‹€ν–‰ κ°€λŠ₯μ„±)
  • XSS(크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ…) 곡격의 벑터가 될 수 있음
  • μ΅œμ‹  λΈŒλΌμš°μ € 및 λ¦°ν„° 차단 λŒ€μƒ
  • μœ μ§€λ³΄μˆ˜μ™€ μ˜λ„ νŒŒμ•…μ΄ 어렀움

 

ν‘œμ€€μ μ΄κ³  μ•ˆμ „ν•œ 방법: about:blank λ˜λŠ” 빈 λ¬Έμžμ—΄

νŒμ—…μ„ μ•ˆμ „ν•˜κ²Œ μ—΄κ³  μ‹Άλ‹€λ©΄, ꢌμž₯λ˜λŠ” 방식은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

const popup = window.open('about:blank', 'myPopup', 'width=800,height=600');
if (popup) {
  popup.location.href = '/your-target-page';
  popup.focus(); // ν•„μš” μ‹œ 포컀슀 이동
}

 

λ˜λŠ” μ•„μ˜ˆ 빈 λ¬Έμžμ—΄λ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const popup = window.open('', 'myPopup', 'width=800,height=600');

 

이 방식은 λ‹€μŒκ³Ό 같은 μž₯점이 μžˆμŠ΅λ‹ˆλ‹€.

  • λ³΄μ•ˆμƒ μ•ˆμ „ν•¨
  • ν‘œμ€€ μ›Ή API μ‚¬μš©λ²•μ„ μ€€μˆ˜
  • μ½”λ“œ μ˜λ„κ°€ λͺ…확함
  • 곡식 λ¬Έμ„œ(MDN, W3C λ“±)μ—μ„œλ„ ꢌμž₯ν•˜λŠ” 방식

 

javascript:focus()의 λͺ©μ κ³Ό μ˜€ν•΄

λ§Žμ€ κ°œλ°œμžλ“€μ΄ javascript:focus()λ₯Ό 초기 URL둜 λ„£λŠ” μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • 빈 창을 μ—΄ λ•Œ νŒμ—…μ΄ μ°¨λ‹¨λ˜λŠ” ν˜„μƒμ„ μš°νšŒν•˜λ €κ³ 
  • 창을 μ—° 직후 μžλ™μœΌλ‘œ 포컀슀λ₯Ό μ£Όλ €κ³ 

ν•˜μ§€λ§Œ μ΅œμ‹  λΈŒλΌμš°μ €λŠ” λ‹€μŒκ³Ό 같은 νŠΉμ„±μ΄ μžˆμŠ΅λ‹ˆλ‹€.

  1. μ‚¬μš©μž 클릭 이벀트 λ‚΄λΆ€μ—μ„œ window.open()을 ν˜ΈμΆœν•˜λ©΄ λŒ€λΆ€λΆ„ μ°¨λ‹¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€
  2. ν¬μ»€μŠ€κ°€ ν•„μš”ν•˜λ‹€λ©΄ popup.focus()λ₯Ό λͺ…μ‹œμ μœΌλ‘œ ν˜ΈμΆœν•˜λŠ” 것이 훨씬 더 λͺ…ν™•ν•˜κ³  μ•ˆμ „ν•©λ‹ˆλ‹€
  3. 일뢀 μ΅œμ‹  λΈŒλΌμš°μ €μ—μ„œλŠ” λ³΄μ•ˆ μ •μ±…μœΌλ‘œ 인해 javascript: URL이 μž‘λ™ν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€

즉, javascript:focus()λŠ” κ³Όκ±°μ—λŠ” ν†΅ν–ˆμ„μ§€ λͺ°λΌλ„, ν˜„λŒ€ μ›Ή λ³΄μ•ˆ ν™˜κ²½μ—μ„œλŠ” μ μ ˆν•˜μ§€ μ•Šμ€ λ°©μ‹μž…λ‹ˆλ‹€.

 

URL 객체와 javascript: URL은 μ™„μ „νžˆ λ‹€λ¦…λ‹ˆλ‹€

ν˜Ήμ‹œ URLμ΄λΌλŠ” 단어 λ•Œλ¬Έμ— λ‹€μŒκ³Ό 같은 문법을 λ– μ˜¬λ¦¬μ‹  뢄도 계싀 ν…λ°μš”?!

const url = new URL(window.location.href);
const tag = url.searchParams.get('tag');

 

이건 URL 정보λ₯Ό λΆ„μ„ν•˜κ³  μ‘°μž‘ν•˜κΈ° μœ„ν•œ 객체둜, μ£Όμ†Œ νŒŒμ‹±μ„ μœ„ν•΄ μ•„μ£Ό μœ μš©ν•˜κ²Œ μ“°μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ 쿼리 νŒŒλΌλ―Έν„° μΆ”μΆœ, 경둜 μ‘°μž‘ 등에 자주 μ‚¬μš©λ©λ‹ˆλ‹€.

 

반면 'javascript:...'λŠ” λΈŒλΌμš°μ €μ— μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό 직접 μ‹€ν–‰ν•˜λΌκ³  λͺ…λ Ήν•˜λŠ” μŠ€ν‚΄μ΄κΈ° λ•Œλ¬Έμ—, λͺ©μ λ„ μ“°μž„λ„ μ™„μ „νžˆ λ‹€λ¦…λ‹ˆλ‹€.

 

ν•­λͺ©μ„€λͺ… - μ‚¬μš© μš©λ„

new URL(...) μ£Όμ†Œ νŒŒμ‹±μ„ μœ„ν•œ URL 객체 μ•ˆμ „ν•˜κ³  ν‘œμ€€μ μΈ 방법
'javascript:focus()' μ‹€ν–‰ μ½”λ“œλ₯Ό URL에 λ„£λŠ” 방식 λ³΄μ•ˆμƒ μœ„ν—˜, λΉ„κΆŒμž₯ 방식

 

λΆ€λͺ¨-μžμ‹ μ°½ 관계와 μ œμ–΄

window.open()으둜 μ—΄λ¦° νŒμ—…μ€ λΆ€λͺ¨ νŽ˜μ΄μ§€μ™€ λ°€μ ‘ν•œ 관계λ₯Ό κ°€μ§‘λ‹ˆλ‹€. 이λ₯Ό ν™œμš©ν•˜κ±°λ‚˜ μ£Όμ˜ν•΄μ•Ό ν•  점이 μžˆμŠ΅λ‹ˆλ‹€.

 

λΆ€λͺ¨ νŽ˜μ΄μ§€μ—μ„œ μžμ‹ μ°½ μ œμ–΄ν•˜κΈ°

νŒμ—…μ„ μ—° λΆ€λͺ¨ νŽ˜μ΄μ§€λŠ” λ°˜ν™˜λœ μ°Έμ‘°λ₯Ό 톡해 μžμ‹ 창을 μ™„μ „νžˆ μ œμ–΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const popup = window.open('about:blank', 'myPopup');
// μžμ‹ μ°½ λ‚΄μš© λ³€κ²½
popup.document.body.innerHTML = '<h1>λΆ€λͺ¨κ°€ λ³€κ²½ν•œ λ‚΄μš©</h1>';
// μžμ‹ μ°½ 크기/μœ„μΉ˜ μ‘°μ •
popup.resizeTo(500, 300);
popup.moveTo(100, 100);
// μžμ‹ μ°½ μ’…λ£Œ
popup.close();

 

μžμ‹ μ°½ μ’…λ£Œ μ‹œλ‚˜λ¦¬μ˜€

μ—¬λŸ¬ μƒν™©μ—μ„œ μžμ‹ 창이 μžλ™μœΌλ‘œ μ’…λ£Œλ  수 μžˆμŠ΅λ‹ˆλ‹€.

  1. λΆ€λͺ¨ νŽ˜μ΄μ§€ 이동 λ˜λŠ” μƒˆλ‘œκ³ μΉ¨ μ‹œ
    // νŽ˜μ΄μ§€ 이동 전에 μžμ‹ μ°½ λ‹«κΈ°
    window.addEventListener('beforeunload', () => {
      if (popup && !popup.closed) {
        popup.close();
      }
    });

     

  2. λ‹€λ₯Έ SPA 라우트둜 이동 μ‹œ
     
    // React Router λ“±μ˜ 라우트 λ³€κ²½ μ΄λ²€νŠΈμ— μ—°κ²°
    router.beforeEach((to, from, next) => {
      if (window.myPopup && !window.myPopup.closed) {
        window.myPopup.close();
      }
      next();
    });

 

μžμ‹ 창이 λΆ€λͺ¨ νŽ˜μ΄μ§€ κ°μ§€ν•˜κΈ°

μžμ‹ μ°½μ—μ„œλŠ” λΆ€λͺ¨ 창의 μ‘΄μž¬μ™€ μƒνƒœλ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

// μžμ‹ μ°½μ—μ„œ λΆ€λͺ¨ μ°½ 확인 및 λŒ€μ‘ν•˜κΈ°
if (window.opener && !window.opener.closed) {
  // λΆ€λͺ¨ 창이 μ‘΄μž¬ν•˜κ³  μ—΄λ €μžˆμŒ
  console.log('λΆ€λͺ¨ μ°½ URL:', window.opener.location.href);
} else {
  // λΆ€λͺ¨ 창이 λ‹«ν˜”κ±°λ‚˜ μ—†μŒ
  console.log('λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰ 쀑');
}

 

λΈŒλΌμš°μ € ν˜Έν™˜μ„±κ³Ό μΆ”κ°€ 고렀사항

μ΅œμ‹  λΈŒλΌμš°μ €λ“€μ€ window.open()에 λŒ€ν•΄ 점점 더 μ—„κ²©ν•œ 정책을 μ μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

  • Chrome, Safari: μ‚¬μš©μž 제슀처(클릭 λ“±) 없이 window.open()을 ν˜ΈμΆœν•˜λ©΄ μ°¨λ‹¨λ©λ‹ˆλ‹€
  • Firefox: νŒμ—… 차단 섀정에 따라 λ™μž‘μ΄ λ‹¬λΌμ§‘λ‹ˆλ‹€
  • λͺ¨λ°”일 λΈŒλΌμš°μ €: λ§Žμ€ λͺ¨λ°”일 λΈŒλΌμš°μ €μ—μ„œ νŒμ—… 자체λ₯Ό μ œν•œμ μœΌλ‘œ μ§€μ›ν•©λ‹ˆλ‹€

λ”°λΌμ„œ νŒμ—… λŒ€μ‹  λͺ¨λ‹¬μ΄λ‚˜ 인라인 μ½˜ν…μΈ λ₯Ό κ³ λ €ν•˜λŠ” 것도 쒋은 λŒ€μ•ˆμ΄ 될 수 μžˆμŠ΅λ‹ˆλ‹€:

// νŠΉλ³„ν•œ μ΄μœ κ°€ μ—†λ‹€λ©΄ νŒμ—… λŒ€μ‹  λͺ¨λ‹¬μ„ κ³ λ €ν•΄λ³΄μ„Έμš”
document.getElementById('openModal').addEventListener('click', () => {
  document.getElementById('myModal').style.display = 'block';
});

 

μš”μ•½ 및 κ²°λ‘ 

  • λͺ¨λ˜ ν”„λ ˆμž„μ›Œν¬κ°€ μ£Όλ₯˜μΈ μ§€κΈˆλ„ OAuth, 결제 연동, ν”„λ¦°νŠΈ κΈ°λŠ₯ 등을 μœ„ν•΄ window.open()이 ν•„μš”ν•œ 상황이 μžˆμŠ΅λ‹ˆλ‹€.
  • javascript:focus() 방식은 λ³΄μ•ˆμƒ μœ„ν—˜ν•˜κ³ , MDN 및 ESLintμ—μ„œλ„ μ‚¬μš©μ„ ꢌμž₯ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • νŒμ—…μ„ μ—΄ λ•ŒλŠ” about:blankλ‚˜ 빈 λ¬Έμžμ—΄μ„ μ‚¬μš©ν•˜κ³ , κ·Έ 이후에 popup.location.href와 popup.focus()λ₯Ό μ‚¬μš©ν•˜λŠ” 방식이 κ°€μž₯ ν‘œμ€€μ μ΄κ³  μ•ˆμ „ν•©λ‹ˆλ‹€.
  • λΆ€λͺ¨ νŽ˜μ΄μ§€μ—μ„œλŠ” νŒμ—… 창을 μ™„μ „νžˆ μ œμ–΄ν•  수 있으며, νŽ˜μ΄μ§€ μ „ν™˜ μ‹œ νŒμ—… 창을 적절히 관리(μ’…λ£Œ)ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • React 같은 ν”„λ ˆμž„μ›Œν¬μ—μ„œλŠ” useRef와 useEffectλ₯Ό ν™œμš©ν•΄ νŒμ—…μ˜ 생λͺ…μ£ΌκΈ°λ₯Ό μ»΄ν¬λ„ŒνŠΈμ™€ 연동할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • URL 객체와 javascript: URL은 κ°œλ…μ΄ μ™„μ „νžˆ λ‹€λ₯΄λ―€λ‘œ ν˜Όλ™ν•˜μ§€ λ§ˆμ„Έμš”.

νŠΉμ • μƒν™©μ—μ„œλŠ” window.open이 μ—¬μ „νžˆ μ μ ˆν•œ 선택일 수 μžˆμŠ΅λ‹ˆλ‹€. 이런 κ²½μš°μ—λ„ 더 μ•ˆμ „ν•œ λ°©μ‹μœΌλ‘œ μ½”λ”©ν•΄ λ³΄μ‹œλŠ” 건 μ–΄λ–¨κΉŒμš”?!

κΆκΈˆν•˜μ‹  점이 μžˆλ‹€λ©΄ μ–Έμ œλ“ μ§€ λŒ“κΈ€λ‘œ λ‚¨κ²¨μ£Όμ„Έμš”! 

 

 

πŸ“ƒ μ°Έκ³  λ¬Έν—Œ  
JAVASCRIPT.INFO - Popups and window methods
W3 Schools - Window open()
eslint/no-script-url
MDN Web Docs
Popup or Modal

 

'TIL' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

μ›Ή μ»΄ν¬λ„ŒνŠΈμ˜ 이벀트 처리  (0) 2024.11.25

+ Recent posts