윈도우 팝업 샘플
window.open 기반 팝업입니다. 호출은 공통함수 fnPopup(), 팝업 화면은 .popuptiles(comn.fw.popLayout)를 씁니다.
📌 신규 팝업은 '모달' 이 원칙입니다. 윈도우 팝업은 아래 예외 5가지에만 씁니다.
내부 화면은 모달이 더 낫습니다 — 반응형이고, 접근성(focus trap)이 되고, 부모-자식 통신이 그냥 함수 호출이 되어
내부 화면은 모달이 더 낫습니다 — 반응형이고, 접근성(focus trap)이 되고, 부모-자식 통신이 그냥 함수 호출이 되어
opener 방어코드가 사라집니다.
모달 샘플 보기 ↗
판단 기준 — 모달로 갈까, 창으로 갈까
| 상황 | 선택 | 이유 |
|---|---|---|
우리 화면(.do) 조회·선택·입력 | 모달 | 같은 페이지라 값 주고받기가 함수 호출. 반응형·접근성도 확보 |
| 외부 도메인 kosis · k-stat · KDCA 등 | 창 | 마크업 제어 불가. iframe 도 X-Frame-Options 로 막힐 수 있음 |
| 인쇄 전용 화면 | 창 | 팝업에서 window.print(). 모달이면 부모 페이지가 같이 인쇄됨 |
| 파일 업로더(dext · innorix) | 창 | 업로더가 별창·플러그인을 전제로 하는 경우가 있음 |
| 여러 개를 나란히 놓고 비교 | 창 | 창은 병렬로 여러 개, 모달은 위로만 쌓임 |
| 외부 프로토콜/에이전트 실행 RAS 원격접근 등 | 창 | 창 자체가 실행 컨텍스트 |
1. 호출 — fnPopup()
⚠️ 인자 순서 주의 : 높이가 너비보다 먼저입니다.
fnPopup(url, 창이름, 높이, 너비, 스크롤, 리사이즈)
// 예) 높이 520 · 너비 640
fnPopup(contextPath + '/sample/popupChild.do', 'smpPopup', 520, 640, 'yes', 'yes');
부모창이 받은 값 : (아직 없음)
2. 팝업 화면(자식) 표준 구조
자식 JSP 는 tiles 조각입니다. 스킨은 comn.fw.popLayout.jsp 의 <style> 에 있고
.pop-wrap 이하 클래스에만 걸립니다.
<%-- ⚠️ <html>·<head>·<body> 를 쓰지 않는다 (레이아웃이 그린다) --%>
<div class="pop-wrap">
<div class="pop-head">
<h2>제목</h2>
<button type="button" class="pop-x" onclick="window.close();">닫기</button>
</div>
<div class="pop-body"> 본문 </div>
<div class="pop-btns">
<button type="button" class="pop-btn primary" onclick="fnOk();">확인</button>
<button type="button" class="pop-btn line" onclick="window.close();">닫기</button>
</div>
</div>
컨트롤러는 return "sample/popupChild.popuptiles"; 처럼 .popuptiles 를 반환합니다.
🎨 버튼 클래스 = 퍼블 버튼 스펙을 그대로 복제한 것
팝업 레이아웃은 퍼블 CSS 를 로드하지 않아
.pop-btn.primary = 퍼블 button-fill01(채움, #0b59e5) ·
.pop-btn.line = 퍼블 button-frame02(테두리, #0e2b5e) ·
클래스 없으면 기본(회색 테두리).팝업 레이아웃은 퍼블 CSS 를 로드하지 않아
button-fill01 을 그대로 쓸 수 없습니다
(이름만 있고 스타일이 없는 상태가 되어 더 혼란). 그래서 토큰값을 실측해 리터럴로 옮긴 팝업 전용 클래스를 씁니다 —
min-width 100px · padding clamp(10,1.22vw,15) clamp(10,1.46vw,20) · radius 4px · line-height:18px · font-weight:500 까지 동일.
🚨 퍼블 CSS 가 없다는 사실이 만드는 함정 4가지
(2026.08.12 통합코드 팝업에서 전부 겪음)
· 클래스 이름에
·
· 체크박스·라디오는 popLayout 이 native 를
· 모달 안 iframe 으로 띄웠다면 CSS 를 고쳐도 새로고침으로는 안 바뀝니다. 여는 시점에 POST 로 그리므로 팝업을 닫았다 다시 열어야 합니다.
· 클래스 이름에
-tbl 을 넣지 마세요. 퍼블은 없는데 앱 css/common.css:667~801 의
옛 표 엔진이 [class*="-tbl"] 로 걸려 table{border-top:2px solid var(--gray-90)} 등이 덧씌워집니다.
증상 = 표 위에 굵은 검은 선이 생기고, 스크롤하면 그 선만 사라짐(선이 <table> 에 걸려 있어서).
→ .pop-grid 처럼 -tbl 을 피한 이름으로. 모달에서는 정반대로 일부러 넣어 퍼블 스킨을 탑니다.·
<caption> 은 직접 감춰야 합니다. 퍼블·앱 base.css 가 감추지만
이 레이아웃은 둘 다 안 불러옵니다(normalize/popup/style.css 뿐) —
캡션 글자가 표 위에 그대로 그려집니다.· 체크박스·라디오는 popLayout 이 native 를
!important 로 강제합니다(옛 앱 CSS 가 감추는 것 대응).
퍼블 룩으로 바꾸려면 더 좁은 스코프 + !important 로 되돌려야 합니다.
⚠그때 transition:all 을 쓰면 배경 이미지 위치까지 전환되어 체크표시가 슬라이드합니다 — 색만 전환할 것.· 모달 안 iframe 으로 띄웠다면 CSS 를 고쳐도 새로고침으로는 안 바뀝니다. 여는 시점에 POST 로 그리므로 팝업을 닫았다 다시 열어야 합니다.
목록(표)을 넣는다면 — 별도 표준
스크롤·머리글 고정·가로 스크롤·체크박스 열은 팝업 안 그리드(표) 샘플 에 정리해 두었습니다. 모달용과 윈도우 팝업용을 나눠서 적어 두었으니 환경에 맞는 쪽을 보세요 — 위 함정처럼 같은 코드가 두 환경에서 정반대로 동작하는 지점이 있습니다.
3. 부모로 값 넘기기
부모 DOM 을 직접 만지지 말고 부모에 약속된 콜백을 호출합니다.
opener 는 null 일 수 있으니 반드시 확인하세요(주소 직접 입력·부모창 닫힘).
// 자식
if (!window.opener || window.opener.closed) { alert('부모 창을 찾을 수 없습니다.'); return; }
if (typeof window.opener.fnSmpPopupCallback === 'function') {
window.opener.fnSmpPopupCallback(val);
}
window.close();
// 부모
function fnSmpPopupCallback(val) { $('#smpPopupResult').text(val); }
⚠️ 기존 팝업 10개는 아직 이 표준이 아닙니다 (2026.07.30 전수조사)
마크업이 3갈래로 갈려 있습니다 — ①자체
그래서 스킨을 신규 클래스(
기존 팝업은 그 화면을 작업할 때 (a) 모달로 전환하거나 (b) 이 표준 구조로 갈아끼웁니다. 일괄 전환은 하지 않습니다.
마크업이 3갈래로 갈려 있습니다 — ①자체
<head>/<body> 를 가진 독립문서형 4개
②순수 tiles 조각 4개 ③<body> 만 중복 2개. 제목 태그도 4종(._layerHeader>h2 / 맨 h2 / h2 여러개 / h1).그래서 스킨을 신규 클래스(
.pop-wrap)에만 걸었습니다 — 기존 10개는 그 클래스가 없어 영향이 없습니다(회귀 위험 0).기존 팝업은 그 화면을 작업할 때 (a) 모달로 전환하거나 (b) 이 표준 구조로 갈아끼웁니다. 일괄 전환은 하지 않습니다.