typeof 는 js에서 타입을 반환하는 연산자(operator)로써 변수의 타입을 확인할 때 사용한다.

 

typeof 로 아래와 같이 number, string, object, boolean, function 타입을 확인 할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
console.log(typeof 123);              //number
console.log(typeof "str");             //string
console.log(typeof new Object());      //object
console.log(typeof {test : "test"});   //object
console.log(typeof true);              //boolean
console.log(typeof Symbol());          //symbol
console.log(typeof function(){});      //function
 
console.log(typeof 123 === 'number');               //true
console.log(typeof "str" === 'string');             //true
console.log(typeof new Object() === 'object');      //true
console.log(typeof {test : "test"=== 'object');   //true
console.log(typeof true === 'boolean');             //true
console.log(typeof Symbol() === 'symbol');          //true
console.log(typeof function(){} === 'function');    //true
cs

 

다음과 같은 타입은 주의하여 사용하자.

1
2
3
4
5
6
7
8
console.log(typeof null);                    //object
console.log(typeof new Object(123));        //object
console.log(typeof new Object("123"));        //object
        
console.log(typeof null === 'undefined');                //false
console.log(typeof new Object(123=== 'object');        //true
console.log(typeof new Object(123=== 'number');        //false
console.log(typeof new Object("123"=== 'string');        //false
cs

1. null 은 object (null 은 != null 과 같이 체크 할 것)

2. Object에 담긴 number/string 는 object

 

undefined : 선언은 되어있으나 아무 값도 저장되어 있지 않은 경우

undeclared : 변수 선언 자체가 되어 있지 않은 경우

* undefined , undeclared 모두 typeof 시 undefined로 반환

 

 

참고 : 

typeof document

정리가 잘 되어있는 글 (영어)

정리가 매우 잘 되어있는 글(한글)

반응형

javascript 에서 함수는 1급객체이다.

javascript 에서 함수는 아래와 같은 특징을 지닌다.

 

1. 익명함수로 작성 가능

2. 리턴값으로 사용 가능

3. 매개변수로 사용 가능

4. 변수, 자료구조로 저장 가능

 

위와 같은 특징으로 인해 callback 함수 같은 개..념이 존재.

 

[함수 선언식 vs 함수 표현식]

함수 선언식 : function func(){}

함수 표현식 : var func = function(){}

 

함수선언식으로 소스를 작성해도, 해당 소스 구동시 js 엔진 내에서 함수선언식을 함수표현식으로 바꾼다.

반응형

유저가 페이지를 벗어날 때마다, 특정 처리를 해줘야 하는 상황엔 beforeunload 를 사용.

유저가 페이지를 벗어날 때 처리해 줄 코드와 함께 beforeunload event를 리스너에 등록하여 사용.

※ 뒤로가기, refresh 뿐만 아닌 submit, 브라우저 close 경우에도 beforeunload 리스너가 동작하게 되므로 주의.

 

[ Sample ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(window).on("beforeunload", callback);
 
function callback(){
    console.log("beforeunload callback !");
    //do something
    return "changes will be lost!";
}
 
function off(){
    console.log("beforeunload turn off !");
    $(window).off("beforeunload");
}
 
<button type="button" onclick="javascript:off();">리스너끄기</button>
cs

 

submit 을 제외한 모든 페이지 전환에 특정 함수를 실행시키고 싶은 경우 :

.off("~") 를 사용하여 submit 시엔 beforeunload 이벤트 핸들러를 제거.

 

[ Example ]

1
2
3
4
5
6
7
8
9
10
11
12
$(document).ready(function () {
    // Warning
    $(window).on('beforeunload'function(){
        //do something
        return "Any changes will be lost";
    });
    // Form Submit
    $(document).on("submit""form"function(event){
        // disable warning
        $(window).off('beforeunload');
    });
}
cs

 

 

반응형

1. 유저가 올린 파일의 이름을 그대로 사용하는 경우 (파일명을 바꿔줄 필요가 없는 경우)

1
formData.append('userpic', myFileInput.files[0]);
cs

2. 유저가 올린 파일의 이름을 바꿔서 파일명 중복을 회피하여 사용해야 하는 경우 (파일명을 바꿔줘야 하는 경우)

3번째 인자로 바꿀 파일명을 넣어준다.

1
formData.append('userpic', myFileInput.files[0], 'changeFileNm.jpg');
cs

참고 : https://developer.mozilla.org/ko/docs/Web/API/FormData/append

 

[ UUID 생성 함수 ]

UUID.확장자 형태로 리턴

1
2
3
4
5
6
function makeUUID(file_nm){
   function s4() {
     return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
   }
   return s4() + s4() + s4() + s4() + s4() + s4() + s4() + s4() + file_nm.substr(file_nm.indexOf("."), file_nm.length-1);
}
cs

위 함수를 아래와 같이 사용.

1
formData.append('userpic', myFileInput.files[0], makeUUID(myFileInput.files[0].name));
cs

 

※ http FIleupload 는 여기를 참고

 

반응형

file upload하기 : $.ajax, XMLHttpRequest() 사용

 

$.ajax 및 XMLHttpRequest 를 사용하여 파일업로드를 할 수 있습니다. 

$.ajax 는 jQuery 라이브러리로 내부적으로 javascript 의 XMLHttpRequest 객체를 사용합니다.

XMLHttpRequest를 사용하기 편하게 구현해 놓은게 $.ajax 라고 보시면 될 듯 합니다.

 

파일 업로드 form 이 존재하며 파일 업로드 function을 호출 하는 jsp와

파일 업로드 function 이 분리되어 있는 fileupload.js 로 크게 두 파일로 소스를 분리했습니다.

 

jQuery version 은 3.1.1 이며,  jQuery 버전이 다른 경우 제대로 동작하지 않을 수 있습니다. 

 

 

[fileupload.js]

jQuery lib 사용시 $.ajax 사용하여 파일업로드를 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 
var httpFileUpload = {
    uploadStart : function(fileElement, callback){
        const file = fileElement[0];
        if(!file){
            throw new Error("file not exists");
        } else {
            const uploadFile = file.files[0];
            if(!uploadFile || !uploadFile.size || !uploadFile.name || uploadFile.size === 0){
                throw new Error("upload file is required");
            } else {
                    const url = "http://uploadurl";
                    const form = new FormData();
                    form.append('file', file.files[0]);
                    var returnObj = new Object();
                    
                    $.ajax({
                        type    : 'post',
                        url        : url,
                        data     : form,
                        cache : false,
                        enctype : 'multipart/form-data',
                        contentType : false,
                        processData : false,
                        timeout : 600000
                    })
                    .done(function (data, textStatus, xhr) {
                        var tmp = null;
                        switch(xhr.status){
                            case 201:
                                console.log("uploaded!");
                                returnObj.result_cd = "1";
                                break;
                            case 404:
                                console.log("404");
                                returnObj.result_cd = "404";
                                break;
                            default:
                                console.log("not 201 404");
                                returnObj.result_cd = "0";
                                break;
                        }
                        callback(returnObj);
                    })
                    .fail(function(data, textStatus, errorThrown){
                        console.log("http upload fail : "+errorThrown);
                        returnObj.result_cd = "0";
                        callback(returnObj);
                    });
            }
        }
    }    
}
cs

$.ajax 의 .done .fail 의 callback param은 여기를 참고

 

 

[fileupload.js]

javascript 로 파일업로드를 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var httpFileUpload = {
    
    uploadStart : function(fileElement, callback){
        const file = fileElement[0];
 
        if(!file){
            alert("file not exists");
            throw new Error("file not exists");
        }
 
        const url = "http://uploadurl";
 
        const form = new FormData();
        form.append('file', file.files[0]);
 
        const returnObj = new Object();
        
        const request = new XMLHttpRequest();
        
        request.onload = function(e){
            if(request.status == 201){
                console.log("uploaded!");
                returnObj.result_cd = "1";
            } else if(request.status == 404){
                console.log("404");
                returnObj.result_cd = "404";
                callback(returnObj);
            } else {
                console.log("not 201 404");
                callback(returnObj);
                returnObj.result_cd = "0";
            }
            callback(returnObj);
        };
        request.open('POST', url);
        request.send(form);
    }
}
 
cs

 

[위 모듈(fileupload.js)을 사용하는 jsp]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>                       
<script type="text/javascript" src="${rquest.getContextPath()}/resources/js/jquery-3.1.1.min.js"></script>
<script>
function uploadStartFront(){
    httpFileUpload.uploadStart($("#file"), function(returnData){
        if(returnData.result_cd == "1"){
            alert("업로드 성공");
        } else {
            if(typeof returnData.result_msg !== "undefined"){
                alert("업로드 실패 " + "[" + returnData.result_cd + "]");
            } else {
                alert("업로드 실패 " + "[" + returnData.result_cd + ":" + returnData.result_msg +"]");
            }
        }
        console.log(returnData);
    });
}
</script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
 
<body>
    <div class="inner_wrap" style="padding-left : 350px;">
    <form id ="frm" class="form-horizontal" method="post" action="" enctype="multipart/form-data">
        <input type="file" class="form-control1" id="file" name="file" style="border:0px solid black;"/>
        <button type="button" class="btn_s" onclick="javascript:uploadStartFront();">업로드시작</button>
        <button type="button" class="btn_s">취소</button>
    </form>
    </div>
</body>
 
<script type="text/javascript" src="${rquest.getContextPath()}/resources/js/fileupload.js"></script>
 
</html>
cs

 

파일을 내부 was 로 송신할 때나, 외부 서버로 송신할 때나 목적지 주소(위 코드에서 url)를 제외하곤 코드가 다를게 없지만, 외부 서버로 파일을 송신하는 경우 CORS 및 mixed contents 문제를 유의해야 합니다.

 

CORS 및 mixed contents 에 대한 내용은 추후 공부 및 정리하여 포스팅 하겠습니다.

반응형

$.ajax .done .fail ajax .done .fail 사용시 response data 가져오기

 

$.ajax 호출시 success, error 혹은 done, fail 을 사용하여 서버 통신 결과를 콜백 처리 할 수 있다.

 

그 중 done, fail 을 사용시 어떤 값들을 뽑아 낼 수 있는지 알아보았다.

jQuery document 를 읽어보니 아래와 같은 부분을 찾을 수 있었다.

.done 의 경우 순서대로 data, textStatus, jqXHR 을 리턴해주고 있었다.

 

 

[Example]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
var httpFileUpload = {
    
    getAddr : function(fileElement, callback){
        
        const file = fileElement[0];
        if(!file){
            throw new Error("file Element is required");
        } else {    
            const uploadFile = file.files[0];
            
            if(!uploadFile || !uploadFile.size || !uploadFile.name || uploadFile.size === 0){
                throw new Error("upload file is required");
            } else {
                console.log("file size : " + uploadFile.size+"\nfile name : " + uploadFile.name);
                 
                var params = {
                        filename : uploadFile.name,
                        filesize : uploadFile.size,
                        provider : "TEST"
                    };
                
                $.ajax({
                    type    : "POST",
                    url        : "/sample.do",
                    contentType: "application/json",
                    dataType:"json",
                    data     : JSON.stringify(params)    
                })
                .done(function (data, textStatus, xhr) {
                    console.log(xhr);
                    if(data.result_cd == "1"){
                        alert("success!");
                    } else {
                        alert("에러발생["+data.result_cd+"]");
                        console.log(data.result_msg);
                        callback(data);
                    }
                })
                .fail(function(data, textStatus, errorThrown){
                    console.log("fail in get addr");
                    callback(data);
                });
            }
        }
    }
}
cs

30 번 라인에서 xhr 을 console log 로 찍어보았다.

(console.log 는 브라우저의 개발자도구(크롬기준 F12) -> console 탭에서 확인이 가능하다)

위와 같은 데이터들이 xhr 내에 담겨있음을 확인 할 수 있다.

 

그렇다면 http Status code 를 기준으로 분기처리를 하고 싶다면 어떻게 해야할까?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//생략
.done(function (data, textStatus, xhr) {
    //alert("data : " + data + "\nstatus : " +status +  "\nxhr" + xhr.status);
    switch(xhr.status){
        case 201:
            cp_funcs.alert('uploaded!');
            callback(data);
            break;
        case 404:
            cp_funcs.close();
            cp_funcs.alert('not found');
            callback(data);
            break;
        default:
            cp_funcs.close();
            cp_funcs.alert('Error');
            callback(data);
            break;
    }
});
//생략
cs

위(4~18 line)처럼 xhr내의 status를 뽑아 내면 된다.

반응형

setInterval , setTimeout

 

setInterval

일정 시간 간격을 두고 특정 함수를 실행시키고자 할 때 사용.

특정서버와의 통신을 N 회까지 retry(재시도) 시키는 기능, 타이머 기능(초시계 등) 등의 기능 개발시 사용

 

[실행]

1
var loopInterval = setInterval("loopFunc.checkLooping()"1*2000);
cs

: 2초 뒤 loopFunc.checkLooping() 함수 실행

 

[중단]

1
2
3
if(loopInterval){ 
    clearInterval(loopInterval); 
}
cs

: loopInterval 이 defined 이면(인터벌이 정의되어있으면) 인터벌을 제거.

 

※ 사용시 주의사항

setInterval은 실행시 "시간간격 > 실행 > 시간간격 > 실행 ~" 과 같은 순서로 실행된다.

(위에서 예를 든 코드는 2초뒤에 loopFunc.checkLooping() 함수를 최초로 실행한다)

따라서 "실행 > 시간간격 > 실행 > 시간간격 ~" 과 같이 함수 실행을 우선적으로 시킨 후 시간간격을 두고 싶다면,

1
2
loopFunc.checkLooping();
var loopInterval = setInterval("loopFunc.checkLooping()"1*2000);
cs

위와 같이 setInterval함수를 호출하기 앞서 함수를 강제로 한 번 호출해주면 된다.

 

 

 

setTimeout

일정 시간 후에 특정 함수를 1회 실행시키고자 할 때 사용

강제로 시간 텀을 두어 함수를 실행시켜야 할 때, java 에서의 Thread.sleep(~); 과 같이 시간 텀을 강제로 줄 필요가 있는 경우(딜레이) 사용

 

[실행]

1
setTimeout(function(){sample()}, 1000);
cs

: 1초 뒤 sample() 함수 실행

 

 

 

 

 

 

 

반응형

https://github.com/ParkSB/javascript-style-guide

반응형

팝업 확장 및 구현하기 : Customized PopUp (alert, confirm, loading)

 

 

자바스크립트 내장 함수인 alert, confirm 대화상자를 사용하여 유저에게 알림팝업을 띄우거나, 동의를 구하는 팝업을 띄울 수 있다. 

하지만 팝업 UI를 개발자 마음대로 바꾸는게 불가하며 좀 더 다양한 기능(로딩 팝업 등)을 목적으로 한다면 alert confirm prompt 등의 팝업만으로의 개발에는 한계가 있다.

 

아래와 같이 총 세개의 팝업을 만들어 보자.

alert : 단순알림팝업

comfirm : 확인 및 취소 옵션을 사용자가 선택 할 수 있는 팝업

loading : 로딩(ajax 등의 서버 통신 처리 등)을 하는 동안 떠있는 팝업

 

1. HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<div class="popup_bg popup_custom_bg" style="display: none;"></div>
<div class="loadingPopup" style="display: none; text-align:center; padding:20px 10px 10px 10px; width:300px; height:250px;">    
    <span class="msg"></span>
    <div class="popup_cnt" style="padding:30px 0px 0px 0px;">
        <img src = "/resources/img/loading_large.gif" style="width:60px;">    <!-- 로딩 이미지 -->
        <div class="button_wrap">
            <button type="button" class="btn btn_function btn_border btn_popup_ok"><span>대기중단</span></button>
        </div>
    </div>
</div>            
 
<div class="alertPopup" style="display: none; text-align:center; padding:40px 10px 10px; width:300px; height:200px;">    
    <span class="msg"></span>
    <div class="popup_cnt" style="padding:30px 0px 0px 0px;">
        <div class="button_wrap f_r">
            <button type="button" class="btn btn_function btn_border btn_popup_ok"><span>확인</span></button>
        </div>
    </div>
</div>        
 
<div class="confirmPopup" style="display: none; text-align:center; padding:40px 10px 10px; width:300px; height:200px;">    
    <span class="msg"></span>
    <div class="popup_cnt" style="padding:30px 0px 0px 0px;">
        <div class="button_wrap">
            <button type="button" class="btn btn_function btn_red btn_popup_ok"><span>확인</span></button>
            <button type="button" class="btn btn_function btn_border btn_popup_cancel"><span>취소</span></button>
        </div>
    </div>
</div>       
cs

1 Line : 팝업 영역을 제외한 영역에 dim 처리(불투명)를 하기 위한 태그

2~10 Line: loadingPopup

12~19 Line: alertPopup

21~29 Line: confirmPopup 

3, 13, 22 Line : 팝업 내 메시지 출력 영역

5 Line : 로딩팝업 내 로딩이미지 출력 영역

 

 

2. Javascript(jQuery)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
var customPopup = {
 
    open : function(target, mode, msg){
        customPopup.close();
        
        var enterMsg = msg.replace(/\r?\n/g, '<br>');    //엔터 처리
 
        $(target).css("display""block");
        $(target).find(".msg").html(enterMsg);
        
        $(".popup_custom_bg").css("display""block");
    },
    
    close : function(){
        //팝업 전체 지우기
        $(".popup_custom_bg").css("display""none");
        $(".alertPopup").css("display""none");
        $(".confirmPopup").css("display""none");
        $(".loadingPopup").css("display""none");
    },
    
    alert : function(msg, callback){
        //alert 팝업
        $(".alertPopup .btn_popup_ok").unbind("click");
        
        customPopup.open($(".alertPopup"), "alert", msg);
        
        $(".alertPopup .btn_popup_ok").click(function(e){
            customPopup.close();
        });
    },
 
    confirm : function(msg, callback){
        //confirm 팝업
        $(".confirmPopup .btn_popup_ok").unbind("click");
        $(".confirmPopup .btn_popup_cancel").unbind("click");
        
        customPopup.open($(".confirmPopup"), "confirm", msg);
        
        $(".confirmPopup .btn_popup_ok").click(function(e){
            customPopup.close();            
            if(typeof callback != 'undefined' && callback){
                if(typeof callback == 'function'){
                    callback();
                } else {
                    if( callback ) {
                        eval( callback );
                    }
                }
            }
        });
 
        $(".confirmPopup .btn_popup_cancel").click(function(e){
            customPopup.close();
        });
        
    },
 
    loading : function(msg, callback){
        //로딩 팝업
        $(".loadingPopup .btn_popup_ok").unbind("click");
        
        customPopup.open($(".loadingPopup"), "loading", msg);
        
        $(".loadingPopup .btn_popup_ok").click(function(e){        
            if(xhr && xhr.readyState != 4){
                xhr.abort(); //ajax 호출 중단
            }
            customPopup.close();
            if(typeof callback != 'undefined' && callback){
                if(typeof callback == 'function'){
                    callback();
                } else {
                    if( callback ) {
                        eval( callback );
                    }
                }
            }
        });
    }
}
cs

3~12Line : 팝업 띄우기(display block)

14~20Line : 팝업 숨기기(display none) - 특정 팝업이 호출되었을 때(기존에 떠있는 팝업을 지우기 위해), 팝업 내에서 확인/취소/대기중단 버튼이 눌려 팝업이 닫혀야 할 때 마다 호출되는 함수

22~31Line : 알림 팝업

33~51Line : 컨펌 팝업 - 알림팝업과 다르게 확인버튼에 따른 특정 처리가 필요하므로 callback 함수 필요

59~80Line : 로딩 팝업 - 버튼을 누를 경우 ajax.abort(); 로 ajax 처리를 중단한다. ajax 객체를 담고있는 xhr 변수는 전역변수로 선언.

 

 

3. 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function loadingSample(){
    customPopup.loading("로딩 중..."function(){
        //대기 중단
        location.href="/main.do";
    });
}
 
function alertSample(){
    customPopup.alert("성공!");
}
 
function confirmSample(){
    customPopup.confirm("조회하시겠습니까?"function(){
        //ajax 통신
    });
}
 
 
function sample(){
 
    var key = $.trim($("#key").val());
        
    customPopup.confirm("진행하시겠습니까?"function(){
 
        customPopup.loading("처리중입니다."function(){});
                
        var params = {
                said : said
            };
    
        xhr = $.ajax({
            type    : "post",
            url        : "/sample.do",
            contentType: "application/json",
            dataType:"json",
            data     : JSON.stringify(params),    
            success    : function (data) {
                if(data){
                    customPopup.alert("성공");
                } else {
                    customPopup.alert("실패");
                }
            },
            error : function (data, status, err) {
                customPopup.alert("실패");
            }
        });
    });
}
cs

 

※ css 파일은 따로 빠져있고, 관련 부분만 따로 발췌하기 힘들어 대충 인라인 태그에 작성하여 올렸습니다.

 

참고 : https://zzznara2.tistory.com/693

위에 기재한 고수 선배님의 소스를 참고하여 작성하였으며,

위 소스가 복잡하다고 생각하여(제 실력이 미천하여 제겐 너무 어려웠으므로..)

제 수준에 맞게 다시 코딩하였습니다.스크립트 공부는 언제 시작할런지

 

 

※ 위 코드를 조금 더 깔끔하게 수정하였습니다. (20191016)

[script]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<script>
/* 커스텀 팝업 */
var cp_vars = {
    alert : $(".cp_alert"),
    confirm : $(".cp_confirm"),
    loading : $(".cp_loading"),
    bg : $(".cp_bg")    
}
var cp_funcs = {
    
    open : function(target, msg){
        if($(target).length < 1){
            throw new Error("there is no target element !");
        }
        cp_funcs.close();
        
        var enterMsg = msg.replace(/\r?\n/g, '<br>');    //엔터 처리
        
        $(target).css("display""block");
        $(target).find(".msg").html(enterMsg);
        
        cp_vars.bg.css("display""block");
    },
    
    close : function(){
        //팝업 전체 지우기
        cp_vars.bg.css("display""none");
        cp_vars.alert.css("display""none");
        cp_vars.confirm.css("display""none");
        cp_vars.loading.css("display""none");
    },
    
    alert : function(msg, callback){
        //alert 팝업
        cp_vars.alert.find(".btn_popup_ok").unbind("click");
        //$(".cp_alert .btn_popup_ok").unbind("click");
        
        cp_funcs.open(cp_vars.alert, msg);
        
        $(".cp_alert .btn_popup_ok").click(function(e){
            cp_funcs.close();
            if(typeof callback != 'undefined' && callback){
                if(typeof callback == 'function'){
                    callback();
                } else {
                    if( callback ) {
                         eval( callback );
                    }
                }
            } 
        });
    },
 
    confirm : function(msg, callback, callback2){
        //confirm 팝업
        cp_vars.confirm.find(".btn_popup_ok").unbind("click");
        cp_vars.confirm.find(".btn_popup_cancel").unbind("click");
        
        cp_funcs.open(cp_vars.confirm, msg);
        
        $(".cp_confirm .btn_popup_ok").click(function(e){
            cp_funcs.close();            
            if(typeof callback != 'undefined' && callback){
                if(typeof callback == 'function'){
                    callback();
                } else {
                    if( callback ) {
                        eval( callback );
                    }
                }
            }
        });
 
        $(".cp_confirm .btn_popup_cancel").click(function(e){
            cp_funcs.close();
            if(typeof callback2 != 'undefined' && callback2){
                if(typeof callback2 == 'function'){
                    callback2();
                } else {
                    if( callback2 ) {
                        eval( callback2 );
                    }
                }
            }
        });
    },
 
    loading : function(msg, callback){
        //로딩 팝업
        $(".cp_loading .btn_popup_ok").unbind("click");
        
        cp_funcs.open(cp_vars.loading, msg);
        
        $(".cp_loading .btn_popup_ok").click(function(e){
            if(typeof loopFunc != 'undefined'){
                loopFunc.stopLooping();    //Loop 중단
            }
            if(typeof xhr != 'undefined'){
                if(xhr.readyState != 4){
                    xhr.abort(); //ajax 호출 중단
                }
            }
            cp_funcs.close();
            if(typeof callback != 'undefined' && callback){
                if(typeof callback == 'function'){
                    callback();
                } else {
                    if( callback ) {
                        eval( callback );
                    }
                }
            }
        });
    }
}
</script>
cs

수정된 위의 코드는 각 팝업의 레이아웃을 잡는 div node를 전역변수로 선언(3~8 line)하여 사용하고 있으므로

script 로드 순서를 주의해야 합니다.

위 script 소스를 아래의 body 태그보다 아래에 두어야 cp_vars.alert, cp_vars.confirm, cp_vars.loading 변수를 읽는 부분에서 undefined 에러가 나지 않습니다. 스크립트 로드 순서에 따른 문제와 이를 해결하기 위한 방법은 따로 공부를 좀 더 한 후 포스팅 하도록 하겠습니다.

 

[html+css]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<body>
    <!-- 커스텀 팝업 노출시 배경 DIM 처리용 -->
    <div class="popup_bg cp_bg" style="display: none;"></div>
    <!-- 로딩 팝업 -->
    <div class="popup small csPopup cp_loading" style="display: none; text-align:center; padding:20px 10px 10px 10px; width:300px; height:250px;">    
        <span class="msg"></span>
         <div class="popup_cnt" style="padding:30px 0px 0px 0px;">
            <img src = "/resources/img/loading_large.gif" style="width:60px;">    <!-- 로딩 이미지 -->
            <div class="button_wrap">
                 <button type="button" class="btn btn_function btn_border btn_popup_ok"><span>대기중단</span></button>
             </div>
        </div>
    </div>            
    <!-- 알림 팝업 -->
    <div class="popup small csPopup cp_alert" style="display: none; text-align:center; padding:40px 10px 10px; width:300px; height:230px;">    
        <span class="msg"></span>
         <div class="popup_cnt" style="padding:30px 0px 0px 0px;">
            <div class="button_wrap f_r">
                 <button type="button" class="btn btn_function btn_border btn_popup_ok"><span>확인</span></button>
             </div>
        </div>
    </div>        
    <!-- 확인 팝업 -->
    <div class="popup small csPopup cp_confirm" style="display: none; text-align:center; padding:40px 10px 10px; width:300px; height:200px;">    
        <span class="msg"></span>
         <div class="popup_cnt" style="padding:30px 0px 0px 0px;">
            <div class="button_wrap">
                 <button type="button" class="btn btn_function btn_red btn_popup_ok"><span>확인</span></button>
                 <button type="button" class="btn btn_function btn_border btn_popup_cancel"><span>취소</span></button>
             </div>
        </div>
    </div>
</body>
 
cs

 

 

 

 

반응형

localStorage vs sessionStorage

 

1. localStorage

1) 개념

* stores data with no expiration date : 

  사용자의 브라우저에 영구적으로 보관되는 데이터

* 5MB 제한

* 보안 취약

* 동기방식 처리

참고 : https://www.w3schools.com/html/html5_webstorage.asp

2) 사용 케이스

사용자가 마지막에 찾아본 사람을 사용자(client) 브라우저의 로컬스토리지에 저장.

사용자가 재진입시 마지막에 찾아본 사람의 정보를 재활용 할 수 있다.

참고 : https://css-tricks.com/localstorage-examples/

 

 

2. sessionStorage

1) 개념

stores data for one session (data is lost when the browser tab is closed) :

사용자가 브라우저를 닫을 경우 사라지는 데이터

 

2) 사용 케이스

ajax 비동기 처리로 서버 통신을 하여 인터페이스를 그릴 때, 화면에서 새로고침이 일어날 경우 화면에 노출중인 값들의 기준(조회조건 등)을 유지시키기 위해 sessionStorage 를 사용.

* 동일한 이유로 localStorage 를 사용해도 상관없지만 localStorage는 삭제를 해주지 않을 경우 사용자 브라우저에 영원히 남게 되므로 삭제 처리를 잘 해주어야 한다.

참고 : https://stackoverflow.com/questions/8498357/when-should-i-use-html5-sessionstorage

 

 

3. 사용법 (저장, 조회, 삭제)

1) 저장(save)

1-1) localStorage.setItem("key", "value"); 

1-2) localStorage.key = "value";

 

2) 조회(find/search/get)

2-1) localStorage.getItem("key");

2-2) var value = localStorage.key;

 

3) 삭제(remove)

localStorage.removeItem("key");

 

※ sessionStorage usage is the same as localStorage

   sessionStorage 사용법은 localStorage사용법과 같다

 

※ How and where to find local/session stored data

    storage에 저장된 데이터 확인법

1. on chrome browser, using developer tools(F12)

  크롬브라우저 개발자 도구에서 확인

: chrome developer tools(F12) > Application tab > Storage tab (left side)

  크롬 개발자도구(F12) > Application 상단탭 > Storage 좌측 탭 에서 확인이 가능하다.

 

2. at local directory

로컬 물리 경로에서 확인

참고 : https://stackoverflow.com/questions/8634058/where-the-sessionstorage-and-localstorage-stored

 

 

※ 엉터리 영어 포스팅이 재밌다.

반응형

+ Recent posts