배열, 객체의 call by value, call by reference에 대해 공부하다가 깊은 복사를 단순하게라도 구현해보고 싶은 마음이 생겼다.

 

1. 객체 깊은 복사 코드

function objectDeep(origin){
        const target = {};
        Object.keys(origin).forEach((k)=>{
            if(Array.isArray(origin[k])){
                target[k] = arrayDeep(origin[k]);
            }else if(typeof origin[k] === 'object'){
                target[k] = objectDeep(origin[k]);
            }else{
                target[k] = origin[k];
            }
        });
        return target;
    }

2. 배열 깊은 복사 코드

    function arrayDeep(origin){
        const target = [];
        origin.forEach((v)=>{
            if(Array.isArray(v)){
                target.push(arrayDeep(v));
            }else if(typeof v === 'object'){
                target.push(objectDeep(v));
            }else{
                target.push(v);
            }
        });
        return target;
    }

 

두 함수는 각각 객체 깊은 복사함수(1번), 배열 깊은 복사함수(2번)이다.

두 함수의 생김새나 하는 역할은 매우 유사한 것을 확인할 수 있다.

 

objectDeep을 위주로 설명해보자면 

1. 재귀함수 개념을 사용하였다.

2. 해당 키 또는 인덱스에 있는 값이 배열이면 arrayDeep을 호출한다.

3. 해당 키 또는 인덱스에 있는 값이 객체이면 objectDeep을 호출한다.

4. 2번, 3번에 해당하지 않으면 원시값으로 판단하고 그대로 대입하여 복사한다.

 

↓ 3번은 객체안의 객체값이 해당한다고 생각하면 된다.

const obj = {
 inner: {
  text: '객체안의 객체',
 },
}

 

원시값이면 복사할 배열(target)에 바로 값을 대입하지만 객체이거나 배열이라면 그대로 값을 대입해버리면 참조값만 대입되어 얉은 복사가 되므로 주의해야 한다.

 

3. 테스트

더미데이터

const array = [1,2,3,4,5,[6,7,8,[9,10,11]],12,13,14, {a:1,b:2}];
const target = arrayDeep(array); //array의 데이터를 깊은 복사한 배열

테스트 케이스

array.push(15);
target[9].a=55;
target[5][0] = 77777;
target[5][3][0] = 99999;

결과

테스트1. 원본 데이터 변경

array.push(15)

원본인 array의 끝에 15라는 값을 추가했지만 복사본인 target에는 추가되지 않은 것을 확인할 수 있다.

 

테스트2. 복사본 데이터 변경

target[9].a=55;

복사본(target)의 9번 인덱스에 위치한 객체의 a를 55로 바꾸었지만 원본(array)의 9번 인덱스에 위치한 객체는 변경되지 않은 것을 확인할 수 있다.

 

테스트3. 복사본 데이터 변경2

target[5][0] = 77777;

설명이 필요없다. 테스트2번의 경우와 똑같다.

 

아래도 마찬가지

target[5][3][0] = 99999;

이렇게 원본 또는 복사본에 있는 원시값이 아닌 객체들을 변경해도 서로 메모리가 공유되어 있지 않으니 각각 적용이 되는 것을 볼 수 있었다.

개발을 하다보면 배열에 있는 값을 랜덤으로 섞어서 다른 배열을 만들어야할 때가 있다.

 

 

그때그때 짜기 보다는 그냥 하나 만들어두고 복붙하는게 좋을거같아서 끄적여본다 ㅎㅎ.

    const origin = [1,2,3,4,5,6,7,8,9];
    const shuffle = shuffleFunc(origin);

    function shuffleFunc(origin){
        const shuffle = [];    
        const dummy = origin.slice();
        
        while(dummy.length > 0){
            const index = Math.floor(Math.random() * dummy.length); // 0 <= x < length
            shuffle.push(dummy[index]);
            dummy.splice(index,1); //버려준다.
        }
        return shuffle;
    }

 

[설명]

1. 변수 설명

const shuffle 배열은 무작위하게 섞인 항목들이 들어갈 배열이 된다.
const dummy 배열은 해당 함수가 splice를 사용하여 구현되기 때문에 원본배열을 손상시키지 않기 위해서 
원본배열의 참조값을 가지고 있는 배열일 뿐이다.

 

2. 주요 로직

[ 무작위 값 선택 ] 

주의할 점은 배열의 범위를 넘어서는 index를 선택하면 안된다.

Math.random() 은 무작위로 0 <= x < 1의 값을 반환한다.

우리는 dummy 배열의 인덱스를 무작위로 추출해야하므로 dummy배열의 length를 활용한다.

 

Math.random() * dummy.length 의 반환값은 아래와 같을 것이다.

0 <= x < dummy.length 즉, 위의 예시에서는 0 <= x < 9 (0~8까지)

해당 식의 반환값은 현재 dummy 길이를 초과하지 않는 index값이 반환될 것이고, shuffle에 해당 index의 값을 넣어주기만 하면된다.

 

[ 후처리 ]

index하나를 무작위로 선택하여 결과 배열(shuffle)에 넣었으니 선택된 index는 다시 선택되지 않도록 처리해줘야한다.

 

그것을 splice로 처리하고 있다.

 

splice(i, N)  하면 i번째 부터 N개까지 추출하여 배열로 반환하는 메소드이며, 해당 메소드는 대상이 되는 원본배열을 수정해버리기 때문에 주의해야한다. (slice와 다름 주의!!) 

 

결과적으로 splice(index, 1)을 하게되면 해당 index의 항목이 빠지게 되는 효과를 볼 수 있다.

 

[ 정리 ]

const index = Math.floor(Math.random() * dummy.length); ===> 4가 나왔다고 가정

 

 

shuffle.push(dummy[index]);

 


           

dummy.splice(index,1);

 

 

 

 

 


1. 문제점

노트북을 사용하는데 커스텀 드라이버 또는 OEM드라이버를 설치해서 잘 사용하고 있다가 갑자기 블루스크린이 떠서 골치가 아팠다..
원인을 검색해보았는데 드라이버 문제일 가능성이 높다고 한다. 확인해보니 그래픽카드 드라이버가 자동으로 다른 버전이 설치되어 있었다. 윈도우가 자동으로 새로운 버전의 드라이버를 검색해서 설치한 것이다.

2. 해결방법

윈도우의 자동 드라이버 업데이트 기능을 끄면 된다.

2-1-가 자동 업데이트 기능 끄기

1. '내 컴퓨터-속성' 으로 들어간다.

2. 빨간색으로 표시된 '고급 시스템 설정'을 클릭한다.


3. '하드웨어 탭'의 '장치 설치 설정'으로 들어간다.


4. '아니요'를 체크한 후 변경 내용을 저장한다.


2-1-나 자동 업데이트 기능 끄기(Windows10 Pro 이상만 가능)

1. 실행창에 gpedit.msc 라고 입력한 후 엔터


2. '관리 템플릿' - 'Windows 구성 요소' - 'Windows 업데이트' 에 빨간색으로 표시된 'Windows 업데이트에 드라이버를 포함하지 않음' 정책을 편집한다.





3. '사용'을 체크한 후 확인을 누른다.


여기까지 하면 자동으로 드라이버가 업데이트 되는 기능을 동작하지 않을 것이다. 만약 이미 Windows 업데이트에 드라이버 업데이트가 포함 되었다면 아래의 방식으로 업데이트를 제거할 수 있다.



2-1-다 이미 업데이트에 포함된 드라이버 업데이트 제거

1. 아래의 링크에서 'wushowhide' 프로그램을 다운로드 한다. (혹시 몰라서 첨부파일에도 올려놓았다.)

wushowhide.diagcab


https://www.techtantri.com/tantri/wp-content/uploads/files/wushowhide.diagcab



2. 메뉴 설명

Hide updates 

 업데이트를 숨기는 메뉴

Show hidden updates

 숨겨진 업데이트를 보는 메뉴

우리는 업데이트를 숨겨야 하니 1번 메뉴인 'Hide updates'를 클릭한다.



3. 숨길 업데이트를 체크한 후 다음을 클릭한다. (여기서는 그래픽카드 드라이버인 'NVDIA - Display'만 체크)



4. 결과 확인 후 '문제 해결사 닫기' 클릭

P.S 1번으로 돌아가서 2번 메뉴인 'Show hidden~' 메뉴를 선택하여 숨겨진 업데이트를 다시 확인 할 수 있다.






'TEMP' 카테고리의 다른 글

HTML 레이아웃 - 고정 레이아웃  (0) 2022.10.21

JSP 공부를 해볼려고 동빈나님 동영상 강의를 보다가 '이 부분은 이렇게 했으면 좋겠다' 싶어서 블로그에 글을 올리게 되었습니다.


마음에 들지 않았던 부분

1강~5강까지 진행하면서 마음에 들지 않았던 부분은 총 3가지 입니다.

  1. 회원가입 등록버튼을 눌렀을 때 회원가입 양식에 값이 들어가 있지 않으면 servelet에서 새로운 회원가입 창을 redirect 시키므로 사용자가 입력했던 모든 값이 사라진다.
  2. 아이디 중복확인 버튼이 있지만, 아이디 중복확인을 하지 않고 회원등록 버튼을 누를 수 있다.
  3. 비밀번호가 서로 다르더라도 회원 등록버튼을 누를 수 있다.


해결방안

해결방안은 공통적으로 JavaScript를 이용하기로 하였습니다.
  1. submit 전에 return finalCheck(); 를 통해 예외처리를 실행한다.
  2. <div>태그 안에 hidden값으로 flag를 숨겨놓는다. flag 값에 따라서 중복체크를 했는지 안했는지 판단한다. -> 중복체크를 한 후에 사용자가 아이디값을 바꾼다면 flag값을 초기화 한다.
  3. submit 전에 비밀번호가 다르면 action이 작동하지 않게한다. (1번과 같음)

코드

1. 먼저 회원가입 양식부분의 form에 onSubmit="return finalCheck();" 를 추가하여 submit 버튼을 눌렀을 때 submit이 되기 전에 finalCheck() 라는 JavaScript를 실행하도록 하였습니다.
<form method="post" action="./userRegister" onSubmit="return finalCheck();">

finalCheck() 부분은 다음과 같습니다. 정규식을 사용하여 패스워드 조건, 이름 조건 등을 추가하였습니다.
만약에 각 양식의 조건에 맞지 않으면 만들어놓은 modal 창에 그 이유를 표시하고 return false를 통해 submit이 되지 않도록 하였습니다.
//submit전에 모든 예외처리를 확인하는 함수
		function finalCheck(){
			var idCheck = $('#idCheck').val();     //ID중복체크 여부
			var userPassword1 = $('#userPassword1').val(); //Password 같은지 여부
			var userPassword2 = $('#userPassword2').val();
			var userName = $('#userName').val();   //사용자 이름
			var userEmail = $('#userEmail').val(); //사용자 이메일
			var password_pattern = /^(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9])(?=.*[0-9]).{8,20}$/; //비밀번호 조건
			var blank_pattern = /[\s]/g; //공백인 것들 정규식
			var email_pattern = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/;
			
			//ID 중복체크를 하였는지 검사
			if(idCheck!="1"){
				$('#checkMessage').html('아이디 중복확인을 해주세요');
				$('#checkType').attr('class','modal-content panel-warning');
				$('#checkModal').modal("show");
				return false;
			}
			if(userPassword1 != userPassword2 || !(password_pattern.test(userPassword1))){
				$('#checkMessage').html('비밀번호를 확인해주세요');
				$('#checkType').attr('class','modal-content panel-warning');
				$('#checkModal').modal("show");
				return false;
			}
			if(!userName || blank_pattern.test(userName)){
				$('#checkMessage').html('이름에 공백을 포함되어 있거나, 입력하지 않았습니다.');
				$('#checkType').attr('class','modal-content panel-warning');
				$('#checkModal').modal("show");
				return false;
			}
			if(!email_pattern.test(userEmail)){
				$('#checkMessage').html('이메일 형식에 맞게 입력해주세요.');
				$('#checkType').attr('class','modal-content panel-warning');
				$('#checkModal').modal("show");
				return false;
			}
		}

2. 다음은 id중복체크 부분입니다. 회원가입 양식의 '아이디' 부분에 'idCheck'라는 hidden값을 추가한 후 중복확인 버튼을 누르면 'idCheck'의 value값이 1로 바뀌도록 구성해보았습니다.  또한 중복체크를 성공한 후에 사용자가 id를 변경할 수도 있으니 'userID'값에 onkeyup을 통해 사용자가 입력을 하는 순간 'idCheck'값을 초기화(0)하도록 하였습니다.

회원가입 양식의 hidden값, onkeyup 추가

<h5>아이디</h5>

<input onkeyup="init_idCheck();" class="form-control" type="text" id="userID" name="userID" maxlength="20" placeholder="20자 이하의 숫자, 알파벳">

<button class="btn btn-primary" onclick="registerCheckFuntion();" type="button">중복체크</button>

<input type="hidden" name="idCheck" id="idCheck" value="0">


실제로 'idCheck'값을 변경하는 부분입니다. ajax를 통해서 ID사용가능 여부를 받아오고, 사용가능하면 'idCheck' value를 1로 바꿔줍니다.

//ID중복확인하는 함수
		function registerCheckFuntion(){
			var userID = $('#userID').val(); //사용자가 input태그에 넣은 값중 id가 userID인 것을 가져온다.

			//ID예외처리
			//20자 이하, 숫자, 알파벳만 포함가능 (공백도 같이 걸러진다.)
			var userID_pattern=/^[a-zA-Z0-9]{1,20}$/;
			if(!userID_pattern.test(userID)){
				$('#checkMessage').html('아이디는 숫자와 알파벳 포함, 1~20자 이내여야 사용할 수 있습니다.');
				$('#checkType').attr('class','modal-content panel-warning');
				document.getElementById("idCheck").value="0"; //중복확인을 하지 않았다는 flag
				$('#checkModal').modal("show");
				return ;
			}
			
			$.ajax({
				type : 'POST',
				url  : './UserRegisterCheck',
				data: {userID: userID}, //{parameterName, data} 형식
				success: function(result){
					if(result==1){
						$('#checkMessage').html('사용할 수 있는 아이디입니다.');
						$('#checkType').attr('class','modal-content panel-success');
						document.getElementById("idCheck").value="1"; //중복확인을 했다는 flag
					}else{
						$('#checkMessage').html('사용할 수 없는 아이디입니다.');
						$('#checkType').attr('class','modal-content panel-warning');
					}
					$('#checkModal').modal("show");
					
				}
			});
		}


이 부분은 onkeyup을 통해 실행되는 'idCheck'를 초기화해주는 부분입니다.

//idCheck flag를 초기화 해주는 함수
		function init_idCheck(){
			document.getElementById("idCheck").value="0";
		}


3가지를 모두 예외처리 해보았는데요. 여기까지 join.jsp 전체코드 입니다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/bootstrap.css"> <link rel="stylesheet" href="css/custom.css"> <title>실시간 채팅 서비스</title> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <!--Ajax를 위해서 공식사이트 에서 제공하는 jquery를 가져온다. --> <script src="js/bootstrap.js"></script> <script type="text/javascript"> //ID중복확인하는 함수 function registerCheckFuntion(){ var userID = $('#userID').val(); //사용자가 input태그에 넣은 값중 id가 userID인 것을 가져온다. //ID예외처리 //20자 이하, 숫자, 알파벳만 포함가능 (공백도 같이 걸러진다.) var userID_pattern=/^[a-zA-Z0-9]{1,20}$/; if(!userID_pattern.test(userID)){ $('#checkMessage').html('아이디는 숫자와 알파벳 포함, 1~20자 이내여야 사용할 수 있습니다.'); $('#checkType').attr('class','modal-content panel-warning'); document.getElementById("idCheck").value="0"; //중복확인을 하지 않았다는 flag $('#checkModal').modal("show"); return ; } $.ajax({ type : 'POST', url : './UserRegisterCheck', data: {userID: userID}, //{parameterName, data} 형식 success: function(result){ if(result==1){ $('#checkMessage').html('사용할 수 있는 아이디입니다.'); $('#checkType').attr('class','modal-content panel-success'); document.getElementById("idCheck").value="1"; //중복확인을 했다는 flag }else{ $('#checkMessage').html('사용할 수 없는 아이디입니다.'); $('#checkType').attr('class','modal-content panel-warning'); //document.getElementById("idCheck").value="0"; //중복확인을 하지 않았다는 flag } $('#checkModal').modal("show"); } }); } //idCheck flag를 초기화 해주는 함수 function init_idCheck(){ document.getElementById("idCheck").value="0"; } //password가 서로같은지, 조건에 맞는지 확인하여 passwordCheckMessage에 에러 메시지 출력 function passwordCheckFunction(){ var userPassword1 = $('#userPassword1').val(); var userPassword2 = $('#userPassword2').val(); var password_pattern = /^(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9])(?=.*[0-9]).{8,20}$/; //password 조건 확인 if(!password_pattern.test(userPassword1)){ $('#passwordCheckMessage').html('비밀번호는 알파벳,숫자,특수문자 포함 8-20자 여야합니다.'); return ; }else{ $('#passwordCheckMessage').html(''); //password서로 일치하는지 확인 if(userPassword1 != userPassword2){ $('#passwordCheckMessage').html('비밀번호가 서로 일치하지 않습니다.'); }else{ $('#passwordCheckMessage').html(''); } } } //submit전에 모든 예외처리를 확인하는 함수 function finalCheck(){ var idCheck = $('#idCheck').val(); //ID중복체크 여부 var userPassword1 = $('#userPassword1').val(); //Password 같은지 여부 var userPassword2 = $('#userPassword2').val(); var userName = $('#userName').val(); //사용자 이름 var userEmail = $('#userEmail').val(); //사용자 이메일 var password_pattern = /^(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9])(?=.*[0-9]).{8,20}$/; //비밀번호 조건 var blank_pattern = /[\s]/g; //공백인 것들 정규식 var email_pattern = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/; //ID 중복체크를 하였는지 검사 if(idCheck!="1"){ $('#checkMessage').html('아이디 중복확인을 해주세요'); $('#checkType').attr('class','modal-content panel-warning'); $('#checkModal').modal("show"); return false; } if(userPassword1 != userPassword2 || !(password_pattern.test(userPassword1))){ $('#checkMessage').html('비밀번호를 확인해주세요'); $('#checkType').attr('class','modal-content panel-warning'); $('#checkModal').modal("show"); return false; } if(!userName || blank_pattern.test(userName)){ $('#checkMessage').html('이름에 공백을 포함되어 있거나, 입력하지 않았습니다.'); $('#checkType').attr('class','modal-content panel-warning'); $('#checkModal').modal("show"); return false; } if(!email_pattern.test(userEmail)){ $('#checkMessage').html('이메일 형식에 맞게 입력해주세요.'); $('#checkType').attr('class','modal-content panel-warning'); $('#checkModal').modal("show"); return false; } } </script> </head> <body> <% //SESSION 작업 String userID = null; if(session.getAttribute("userID") != null){ userID = (String)session.getAttribute("userID"); } %> <nav class="navbar navbar-default"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <!--햄버거 메뉴바(오른쪽)를 위해 3개(하나를 없애보면 뭔지 알수있음)--> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <!--옆에(왼쪽) 로고 또는 사이트 이름이 표시되게--> <a class="navbar-brand" href="index.jsp">실시간 채팅 서비스</a> </div> <div class="collapse navbar" id="bs-example-navbar-collapse-1"></div> <ul class="nav navbar-nav"> <li class="active"><a href="index.jsp">메인</a> </ul> <% if(userID==null){ %> <ul class="nav navbar-nav navbar-right"> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">접속하기<span class="caret"></span> </a> <ul class ="dropdown-menu"> <li><a href="login.jsp">로그인</a></li> <li><a href="join.jsp">회원가입</a></li> </ul> </li> </ul> <% }else { %> <ul class="nav navbar-nav navbar-right"> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">회원관리<span class="caret"></span> </a> </li> </ul> <% } %> </nav> <!-- 회원가입 양식 --> <div class="container"> <form method="post" action="./userRegister" onSubmit="return finalCheck();"> <table class="table table-bordered table-hover" style="text-align: center; border: 1px solid #dddddd"> <thead> <tr> <th colspan="3"><h4>회원가입</h4></th> </tr> </thead> <tbody> <tr> <td style="width: 110px;"><h5>아이디</h5></td> <td><input onkeyup="init_idCheck();" class="form-control" type="text" id="userID" name="userID" maxlength="20" placeholder="20자 이하의 숫자, 알파벳"></td> <td style="width: 110px;"><button class="btn btn-primary" onclick="registerCheckFuntion();" type="button">중복체크</button> <input type="hidden" name="idCheck" id="idCheck" value="0"/></td> </tr> <tr> <td style="width: 110px;"><h5>비밀번호</h5></td> <td colspan="2"><input onkeyup="passwordCheckFunction();" class="form-control" type="password" id="userPassword1" name="userPassword1" maxlength="20" placeholder="알파벳,숫자,특수문자 포함 8-20자"></td> </tr> <tr> <td style="width: 110px;"><h5>비밀번호 확인</h5></td> <td colspan="2"><input onkeyup="passwordCheckFunction();" class="form-control" type="password" id="userPassword2" name="userPassword2" maxlength="20" placeholder="비밀번호 확인을 입력해주세요"></td> </tr> <tr> <td style="width: 110px;"><h5>이름</h5></td> <td colspan="2"><input class="form-control" type="text" id="userName" name="userName" maxlength="20" placeholder="이름을 입력해주세요"></td> </tr> <tr> <td style="width: 110px;"><h5>나이</h5></td> <td colspan="2"><input class="form-control" type="number" id="userAge" name="userAge" maxlength="20" placeholder="나이를 입력해주세요"></td> </tr> <tr> <td style="width: 110px;"><h5>성별</h5></td> <td colspan="2"> <div class="form-group" style="text-align: center; margin:0 auto;"> <div class="btn-group" data-toggle="buttons"> <label class="btn btn-primary active"> <input type="radio" name="userGender" autocomplete="off" value="남자" checked>남자 </label> <label class="btn btn-primary"> <input type="radio" name="userGender" autocomplete="off" value="여자">여자 </label> </div> </div> </td> </tr> <tr> <td style="width: 110px;"><h5>이메일</h5></td> <td colspan="2"><input class="form-control" type="email" id="userEmail" name="userEmail" maxlength="20" placeholder="이메일을 입력해주세요"></td> </tr> <tr> <td style="text-align: left;" colspan="3"><h5 style="color: red;" id="passwordCheckMessage"></h5><input class="btn btn-primary pull-right" type="submit" value="등록"></td> </tr> </tbody> </table> </form> </div> <!-- 회원가입 결과에 따라 성공메시지, 오류메시지 모달창을 띄우는 부분 --> <% String messageContent = null; if(session.getAttribute("messageContent") != null){ messageContent = (String)session.getAttribute("messageContent"); } String messageType = null; if(session.getAttribute("messageType") != null){ messageType = (String)session.getAttribute("messageType"); } if(messageContent != null){ %> <div class="modal fade" id="messageModal" tabindex="-1" role="dialog" aria-hidden="true"> <div class="vertical-alignment-helper"> <div class="modal-dialog vertical-align-center"> <div class="modal-content <% if(messageType.equals("오류메시지")) out.println("panel-warning"); else out.println("panel-success"); %>"> <div class="modal-header panel-heading"> <button type="button" class="close" data-dismiss="modal"> <span aria-hidden="true">&times</span> <span class="sr-only">Close</span> </button> <h4 class="modal-title"> <%= messageType %> </h4> </div> <div class="modal-body"> <%= messageContent %> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" data-dismiss="modal">확인</button> </div> </div> </div> </div> </div> <script> //위의 div의 id="messageModal"를 실행시키는 스크립트 $('#messageModal').modal("show"); </script> <% //모달창이 띄워진 후에는 세션을 파괴해서 중복되지 않도록한다. (단 한번만 사용자에게 보여짐) session.removeAttribute("messageContent"); session.removeAttribute("messageType"); } %> <!-- head부분의 javaScript에서 실행되고, 아이디 사용 유무의 결과를 보여준다. --> <div class="modal fade" id="checkModal" tabindex="-1" role="dialog" aria-hidden="true"> <div class="vertical-alignment-helper"> <div class="modal-dialog vertical-align-center"> <div id="checkType" class="modal-content panel-info"> <div class="modal-header panel-heading"> <button type="button" class="close" data-dismiss="modal"> <span aria-hidden="true">&times</span> <span class="sr-only">Close</span> </button> <h4 class="modal-title"> 확인 메시지 </h4> </div> <div id="checkMessage" class="modal-body"> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" data-dismiss="modal">확인</button> </div> </div> </div> </div> </div> </body> </html>





원본 동영상 : https://youtu.be/bETgFGtnpzQ


+ Recent posts