투케이2K

520. (javaScript) [간단 소스] 자바스크립트 동적 스크립트 작성 및 window.open 시 window.opener.postMessage 부모에서 자식 데이터 전송 본문

JavaScript

520. (javaScript) [간단 소스] 자바스크립트 동적 스크립트 작성 및 window.open 시 window.opener.postMessage 부모에서 자식 데이터 전송

투케이2K 2026. 4. 1. 19:32
728x90
반응형

[개발 환경 설정]

개발 툴 : Edit++ / Vscode

개발 언어 : JavaScript

 

[소스 코드]

 

-----------------------------------------------------------------------------------------
[사전 설명 및 설정 사항]
-----------------------------------------------------------------------------------------

- 개발 환경 : Web


- 개발 기술 : JavaScript (자바스크립트) / 동적 html / 동적 Script / window open


- 사전) 👉 window.open 기능 간편 설명 : 

  >> window.open() 은 브라우저에서 새 창이나 새 탭을 열거나, 기존에 이름 붙인 창을 재사용할 때 사용하는 함수입니다

  >> window.open() 은 주로 외부 링크를 새 탭으로 열거나, 팝업(작은 창) 형태로 보조 UI를 띄울 때 사용됩니다

  >> window.open() target 주요 인자 값 : 

    - '_blank': 새 탭/창

    - '_self': 현재 창(일반 링크와 동일)

    - '_parent', '_top': 프레임/아이프레임 계층에 영향

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[소스 코드]
-----------------------------------------------------------------------------------------

<!DOCTYPE HTML>
<html lang="ko">
<head>
    <title>javaScriptTest</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">


    <!-- 반응형 구조 만들기 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">


    <!-- 내부 CSS 스타일 지정 -->
    <style>

        html, body {
          width: 100%;
          height: 100%;
          margin : 0 auto;
          padding : 0;
          border : none;
          background-color: #666;
        }



        
        .toast-full {
          width: 100% !important;
          max-width: 100% !important;   /* ✅ 핵심: 기본 max-width 제거 */
          left: 0 !important;
          transform: none !important;
          border-radius: 0 !important;
        }


    </style>





    <!-- [CDN 주소 설정] -->    
    <script src="https://code.jquery.com/jquery-latest.min.js"></script>






    <!-- [자바스크립트 코드 지정] -->
    <script type="module">
        
      window.onload = async function() {
        console.log("[window onload] : [html 최초 로드 및 이벤트 상시 대기 실시] : [start]");

        try {         
          
          // -----------------------------------------------
          // 1) window open 시 화면 사이즈 및 옵션 정의 수행
          // -----------------------------------------------

          const w = window.screen.availWidth; // 가용 화면 크기 구하기
          const h = window.screen.availHeight; // 가용 화면 크기 구하기

          //const w = 100; // 고정 사이즈 지정
          //const h = 100; // 고정 사이즈 지정

          const features = [ // features 구성
            `width=${w}`,
            `height=${h}`,
            'left=0',
            'top=0',
            'toolbar=no',
            'menubar=no',
            'location=no',
            'status=no',
            'resizable=no',
            'scrollbars=no',
            // 'noopener', // ✅ window.postMessag 사용 시 주석 처리
            // 'noreferrer', // ✅ window.postMessag 사용 시 주석 처리
          ].join(',');


          // -----------------------------------------------
          // 2) 스크립트 시퀀스를 깨서 HTML 파서가 조기 종료하지 않도록 보호 함수 정의
          // -----------------------------------------------
          function protectClosingScriptTag(code) {
            return String(code).replace(/<\/script/gi, '<\\/script');
          }


          // -----------------------------------------------
          // 3) 엔티티 (&lt; &gt;) → 실제 문자(< >) 로 디코드 함수 정의
          // -----------------------------------------------
          function decodeHtmlEntities(str) {
            const div = document.createElement('div');
            div.innerHTML = str;
            return div.textContent; // 또는 div.innerText
          }


          // -----------------------------------------------
          // 4) 주입할 스크립트 코드 작성 (필요 시 자유롭게 수정)
          // -----------------------------------------------        
          const scriptCode = `
            window.onload = function() {
              console.log('window open success');

              try { 
                  
                // ✅ [부모가 전달한 window.opener.postMessage 를 받기 위한 이벤트 리스너 등록]
                window.addEventListener('message', (event) => {                  
                  console.warn("window.addEventListener(message) : receive : ", JSON.stringify(event));
                  console.warn('[event.data] : ', event.data, ' / [event.origin] : ', event.origin);


                  // ✅ TWOK_POPUP_CLOSE : Window 팝업창 닫기 명령 수신
                  if (event.data.type !== null && event.data.type !== undefined && event.data.type !== '' && event.data.type == 'TWOK_POPUP_CLOSE'){
                    console.log('window.open : TWOK_POPUP_CLOSE : success');
                    
                    window.close(); // ✅ open 된 팝업창 닫기 처리
                  }

                });
              } 
              catch(err) { 
                console.error('chile window onload : exception : ', err); 
              }

            };
          `;


          // -----------------------------------------------
          // 5) 엔티티 상태의 HTML 뼈대 작성

          // -----------------------------------------------
          /*
          <!doctype html>
          <html>
          <head>
          <meta charset="utf-8">
          <title>twok2kDynamicScript</title>                            
          <style>
              body {
                  margin: 0; 
                  height: 100vh; 
                  display: flex; 
                  justify-content: center; 
                  align-items: center; 
                  font-size: 40px; 
                  background-color: #000; 
                  color: #fff;
              }
          </style>
          </head>
          <body>
          </body>
          </html>
          */
          // -----------------------------------------------
          const htmlBaseEntities = `
            &lt;!doctype html&gt;
            &lt;html&gt;
            &lt;head&gt;
              &lt;meta charset=&quot;utf-8&quot;&gt;
              &lt;title&gt; twok2kDynamicScript &lt;/title&gt;
              &lt;style&gt;
                body { 
                  margin: 0; 
                  height: 100vh; 
                  display: flex; 
                  justify-content: center; 
                  align-items: center; 
                  font-size: 40px; 
                  background-color: #000; 
                  color: #fff; 
                } 
              &lt;/style&gt;
            &lt;/head&gt;
            &lt;body&gt;
            &lt;/body&gt;
            &lt;/html&gt;`;


          // -----------------------------------------------  
          // 6) 엔티티 상태의 </body>를 찾아 <script> 를 삽입 (여기선 엔티티 상태 유지)
          // -----------------------------------------------
          const composedEntities = htmlBaseEntities.replace(
            /&lt;\/body&gt;/i,
            `&lt;script&gt;${protectClosingScriptTag(scriptCode)}&lt;/script&gt;&lt;/body&gt;`
          );


          // -----------------------------------------------
          // 7) 최종 문자열을 실제 HTML로 디코드
          // -----------------------------------------------
          const finalHtml = decodeHtmlEntities(composedEntities);


          // -----------------------------------------------
          // 8) Blob URL 생성
          // -----------------------------------------------
          const blob = new Blob([finalHtml], { type: 'text/html;charset=utf-8' });
          const url = URL.createObjectURL(blob);

          console.log('blob url : ', url);


          // -----------------------------------------------
          // 9) window open 팝업 열기 
          // -----------------------------------------------
          const popup = window.open(url, '_blank', features);


          // -----------------------------------------------
          // 10) ✅ 부모에서 자식 >> window.opener.postMessage 명령 전송
          // -----------------------------------------------
          setTimeout(() => {
                        
            console.log('setTimeout : window.opener.postMessage : send');

            popup.postMessage(
              { type: 'TWOK_POPUP_CLOSE' },  // 보낼 데이터
              '*' // targetOrigin (실서비스에서는 도메인 지정!)
            );

          }, 2000); // 2초뒤에 전송

        }
        catch (exception) {
          console.error("[window onload] : [Exception] : 예외 상황 발생 : ", exception);

        }

      };

    </script>


</head>


<body>

</body>

</html>

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[참고 사이트]
-----------------------------------------------------------------------------------------

[간단 소스] 자바스크립트 window.open 사용해 새창 팝업창 열기 후 window.opener.postMessage 메시지 전달 수행

https://kkh0977.tistory.com/8668

https://blog.naver.com/kkh0977/224202970329


[간단 소스] 자바스크립트 동적 html 코드 작성, new Blob 및 URL.createObjectURL 사용해 window.open 새창 열기

https://kkh0977.tistory.com/8452

https://blog.naver.com/kkh0977/224097132149


[자바스크립트 브라우저 사이즈, 해상도 구하기 및 window open 윈도우 창 열기 실시]

https://kkh0977.tistory.com/847

https://blog.naver.com/kkh0977/222392594793?trackingCode=blog_bloghome_searchlist


[자바스크립트 window open close 사용해 현재 브라우저 창 닫기 수행 - 브라우저 종료]

https://blog.naver.com/kkh0977/223203344998?trackingCode=blog_bloghome_searchlist


[모바일] 내부 window open 상태 감지 및 새로운 웹뷰 작업 로직 수행 방법

https://blog.naver.com/kkh0977/222609480598?trackingCode=blog_bloghome_searchlist

-----------------------------------------------------------------------------------------
 
728x90
반응형
Comments