Recent Posts
Recent Comments
Link
11-24 00:01
Today
Total
관리 메뉴

삶 가운데 남긴 기록 AACII.TISTORY.COM

Web application 에서 popup window의 대안 본문

DEV&OPS/Javascript

Web application 에서 popup window의 대안

ALEPH.GEM 2024. 5. 8. 20:34

popup은 차단이 기본 값

popup은 보안 문제가 있어서 대부분의 브라우저에서 차단하는 것이 기본 값으로 되어있습니다.

그렇지만 web application을 만들다 보면 popup 기능이 필요할 때가 있습니다.

popup 윈도우의 대안으로 iframe, modal, overlay 등을 생각해 볼 수 있습니다.

 

 

IFRAME

iframe의 경우에도 popup고 마찬가지로 보안 문제 때문에, 정책상으로 https으로만 접근이 가능하도록 하는 것이 일반적입니다.

https으로 서버를 구축하려면 CA(인증 기관)으로부터 발급된 SSL 인증서가 필요합니다. 

인터넷과 단절된 폐쇄된 내부 인트라넷 환경에서 HTTPS를 사용할 때는 내부 CA와 자체 서명 인증서를 이용해서 https를 구축할 수 있습니다.

  1. 내부 CA(인증 기관) 생성과 자체 서명 인증서: 대부분의 내부 네트워크에서는 자체 CA를 설정하고 이 CA에 의해 서명된 인증서를 내부 서버에 사용함으로써 HTTPS를 구현합니다. 이 방식은 내부 네트워크에만 적용되며, 이 CA의 루트 인증서를 네트워크 내 모든 클라이언트 기기에 설치해야 합니다.
  2. 외부 CA 인증서: 폐쇄된 네트워크라 하더라도, 네트워크에 접속하기 전에 외부 인터넷에 일시적으로 접속하여 공식 CA(예: Let's Encrypt, VeriSign 등)로부터 발급받은 인증서를 설치할 수 있습니다. 이 경우, 인증서의 유효 기간 동안은 인터넷 접속 없이도 인증서가 유효함을 유지할 수 있습니다. 그러나 인증서 갱신 시에는 외부 인터넷 접근이 필요합니다. 

 

MODAL

현실적으로 popup의 가장 손쉬운 대안은 modal 을 사용하는 것입니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
		.modal {
			display: none;
			position: fixed;
			z-index: 1;
			left: 0;
			top: 0;
			width: 100%;
			height: 100%;
			overflow: auto;
			background-color: rgba(0,0,0,0.4);
		}

		.modal-content {
			background-color: #fefefe;
			margin: 10% auto;
			padding: 20px;
			border: 1px solid #888;
			width: 50%;
			height: 25%;
		}

		.close {
			color: #aaa;
			float: right;
			font-size: 28px;
			font-weight: bold;
		}
    </style>
    <script>
		function openModal() {
			document.getElementById('myModal').style.display = 'block';
		}

		function closeModal() {
			document.getElementById('myModal').style.display = 'none';
		}
    </script>
</head>
<body>
<div>
	<p>
		본문 내용~~~~.<br>
	</p>
	<span>Label <input type="text" />&nbsp;<button onclick="openModal()">Open Modal</button></span><br>
</div>
<div id="myModal" class="modal">

    <div class="modal-content">
        <span class="close" onclick="closeModal()">&times;</span>
		<br>
		<p>
		모달 내용~~~~
		</p>
    </div>
</div>

</body>
</html>

 

하지만 modal은 open 되었을 때 부모 요소에 접근을 할 수 없게 되어있어서 popup을 완전히 대체할 수는 없습니다.

 

 

INLINE OVERLAY

인라인 오버레이를 사용하여 메시지 창이나 팝업 창을 구현 할 수 있습니다.

JavaScript 함수를 사용하여 오버레이를 표시하고 숨기는 기능을 구현합니다.

JavaScript를 사용하여 여러 폼을 미리 저장하고, 이를 div 태그에 동적으로 주입하는 것이 가능합니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
	# overlay {
	  position: fixed; /* 페이지 전체에 고정 */
	  top: 0;
	  left: 0;
	  width: 100%; /* 전체 너비 */
	  height: 100%; /* 전체 높이 */
	  background-color: rgba(0,0,0,0.5); /* 반투명 검은색 배경 */
	  display: flex;
	  justify-content: center; /* 중앙 정렬 */
	  align-items: center; /* 중앙 정렬 */
	}

	# overlay-content {
	  padding: 20px;
	  background-color: white; /* 백그라운드 색상 */
	  border-radius: 5px; /* 모서리 둥글게 */
	}
    </style>
    <script>
	// 오버레이 표시
	function showOverlay() {
	  document.getElementById('overlay').style.display = 'flex';
	}

	// 오버레이 숨기기
	function hideOverlay() {
	  document.getElementById('overlay').style.display = 'none';
	}
	
	//자바스크립트로 폼 정의
	const forms = {
	  form1: `
		<form id="form1">
		  <label for="name">이름:</label>
		  <input type="text" id="name" name="name"><br><br>
		  <input type="submit" value="제출">
		</form>
	  `,
	  form2: `
		<form id="form2">
		  <label for="email">이메일:</label>
		  <input type="email" id="email" name="email"><br><br>
		  <input type="submit" value="제출">
		</form>
	  `
	};

	function injectForm(formId) {
	  document.getElementById('formContainer').innerHTML = forms[formId];
	}
    </script>
</head>
<body>
<p>
<button onclick="showOverlay()">메시지 보기</button>
</p>
<!-- 오버레이 컨테이너 -->
<div id="overlay" style="display:none;">
  <!-- 오버레이 콘텐츠 -->
  <div id="overlay-content">
    <p>메시지 예제 입니다.</p>
    <button onclick="hideOverlay()">닫기</button>
  </div>
</div>
<p>
<div id="formContainer"></div> <!-- 폼이 주입될 컨테이너 -->
</p>
<p>
<button onclick="injectForm('form1')">폼 1 주입</button>
</p>
<p>
<button onclick="injectForm('form2')">폼 2 주입</button>
</p>
</body>
</html>

이 예제는 매우 기본적인 인라인 오버레이 구현 방법을 보여줍니다.

  • forms 객체에 두 개의 폼(form1, form2)을 HTML 문자열 형태로 저장합니다.
  • injectForm 함수는 인자로 받은 formId에 해당하는 폼을 forms 객체에서 찾아, formContainer라는 ID를 가진 div에 해당 폼의 HTML을 주입합니다.
  • 버튼 클릭 시 injectForm 함수가 호출되어, 사용자가 선택한 폼이 화면에 표시됩니다.

이 방식을 사용하면, JavaScript를 통해 동적으로 다양한 폼을 페이지에 추가하고, 사용자와의 상호작용을 통해 콘텐츠를 변경할 수 있습니다.

 

 

 

POPUP element

마지막으로 popup을 윈도우 창으로 열지 않고 <div> 태그로 구현하는 방법을 소개합니다. 

이러한 <div>태그를 블록 레벨 요소로 만들어서 javascript로 보여줬다 숨겼다 하는 방식으로 구현합니다.

 

CSS속성 중에 display: block;은 해당 요소를 블록 레벨 요소로 지정해줍니다. 

블록 레벨 요소는 기본적으로 한 줄을 차지하며 해당 요소는 한 줄에 하나의 블록이 되어 수직으로 쌓입니다.

블록 레벨 요소의 너비는 부모 요소의 전체 너비를 차지합니다.

블록 레벨 요소는 기본적으로 자동으로 줄 바꿈이 되어, 다음 블록 요소는 새로운 줄에 시작하게 됩니다.
블록 레벨 요소는 width와 height 속성을 사용하여 너비와 높이를 직접 설정할 수 있습니다.
블록 레벨 요소는 위아래에 자동으로 여백(margin)이 추가됩니다.
블록 레벨 요소는 상자 모델(Box Model)을 따라 content, padding, border, margin의 구조로 구성됩니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        #popup {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
			width: 600px;
			height: 400px;
            padding: 1px;
            background-color: #fff;
            border: 1px solid #ccc;
            z-index: 999;
			cursor: grab;
        }
		#popupTitle{
			padding: 0px;
			margin: 0px;
			background-color: #ccc;
			cursor: grab;
			height: 2rem;
		}
		.close {
			color: #333;
			float: right;
			font-size: 28px;
			font-weight: bold;
		}
    </style>
    <script>
		var isDragging = false;
        var offsetX, offsetY;
        
		function openPopup() {
            //Find Parent Elements Before Opening a Popup
            var parentElement = document.getElementById('parentElement');
            var popup = document.getElementById('popup');
			var popupTitle = document.getElementById('popupTitle');
            popup.style.display = 'block';

            //Example of changing the parent element style
            if (parentElement) {
                parentElement.style.backgroundColor = '#f0f0f0';
            }
			
			//Add drag event for popup title
            popupTitle.addEventListener('mousedown', startDrag);
            window.addEventListener('mouseup', stopDrag);
            window.addEventListener('mousemove', drag);
        }

        function closePopup() {
            var popup = document.getElementById('popup');
            popup.style.display = 'none';

            //Example of changing the parent element style (restoring to the original style)
            var parentElement = document.getElementById('parentElement');
            if (parentElement) {
                parentElement.style.backgroundColor = 'transparent';
            }
			
			// remove drag event
            window.removeEventListener('mousedown', startDrag);
            window.removeEventListener('mouseup', stopDrag);
            window.removeEventListener('mousemove', drag);
        }
		
		function startDrag(e) {
            isDragging = true;
            offsetX = e.clientX - parseInt(window.getComputedStyle(document.getElementById('popup')).left);
            offsetY = e.clientY - parseInt(window.getComputedStyle(document.getElementById('popup')).top);
        }

        function stopDrag() {
            isDragging = false;
        }

        function drag(e) {
            if (isDragging) {
                var popup = document.getElementById('popup');
                popup.style.left = (e.clientX - offsetX) + 'px';
                popup.style.top = (e.clientY - offsetY) + 'px';
            }
        }
    </script>
</head>
<body>
<!-- popup element -->
<div id="popup">
	<div id="popupTitle">
    <span>This is a popup title!</span><span class="close" onclick="closePopup()">&times;</span>
	</div>
	<p>&nbsp;<textarea>popup example</textarea>&nbsp;</p>
    <button onclick="closePopup()">Close</button>
</div>

<!-- parent element -->
<div id="parentElement" style="background-color: transparent; padding: 20px;">
	<span>Label <input type="text" />&nbsp;<button onclick="openPopup()">Open Popup</button></span><br>
	<div>
	<p>
	<span>This is contents of parent element.<br> The popup elements is not modal.<br> So that. You can access the parent element while the pop-up element is open.</span>
	</p>
	</div>
</div>

</body>
</html>

 

이렇게 구현하면 팝업 윈도우 처럼 드래그 앤 드랍으로 위치 이동이 가능하며, 모달이 아니라서 부모 요소와도 상호작용을 할 수 있어서 마치 popup윈도우 처럼 동작하도록 할 수 있습니다.

 

 

 

 

 

 

 

 

728x90

'DEV&OPS > Javascript' 카테고리의 다른 글

주요 HTTP status 정리  (0) 2023.01.26
Javascript 코딩 컨벤션  (0) 2022.10.21
javascript 우클릭, 더블클릭선택, 드래그 방지  (0) 2022.04.19
웹페이지 뒤로가기 방지 방법  (0) 2022.04.19
HTML5 canvas finger print  (0) 2022.04.19