상세 컨텐츠

본문 제목

모든 환경에서 사용가능한 JavaScript (자바스크립트) 팝업 창 코드

본문

웹앱에서 팝업 창을 이용하는 것이 아주 까다롭습니다. 더군다나 iOS에서는 잘 호환이 안되죠. 여러 리서치를 하고 나서 테스트 결과 다음 아래의 방법이 Windows, Android, macOS, iOS에서의 여러 브라우저와 호환이 가능하다고 결론이 나왔습니다.
 

반응형


문제 되는 점은 iOS와 macOS의 사파리 브라우저입니다. iOS는 먼저 iOS 세팅에서 팝업 해제를 하여야 하고 macOS 에서는 사파리 브라우저 세팅에서 팝업 해제를 해야 합니다. 게다가 macOS의 사파리는 asynchronous 콜에서 (예제로 $.ajax 콜) callback 함수 중에 팝업창을 열지 못하게 막아놨습니다. 그래서 모든 상황에 맞춰서 코딩을 해야 하죠.

팝업창 사용 시 유용한 세 가지 기능을 비모바일과 모바일 환경으로 나누어 알려드리겠습니다.


1. OPEN - 팝업창 열기


a. Windows와 macOS (Safari 브라우저 제외)

window.open('주소', '_blank', '옵션');

b. macOS - Safari 브라우저 - 팝업 해제 필요

버튼이 눌러지거나 함수가 발동되는 즉시 blank 팝업창을 열어주세요. 그 창을 변수에 저장해야 합니다. 옵션값에 height과 width를 지정하지 않으면 창이 아니고 탭으로 바뀝니다.

// *메인*
let windowPopup;

// *버튼 click 이벤트 함수 중*
windowPopup = window.open(null, '_blank', 'height=10,width=10');

그리고 asynchronous 콜을 시행하고 나서 돌아오는 callback 함수에 다음의 예제와 같이 열린 창에 주소와 다른 옵션들을 변경합니다.

// *asynchronous callback 함수중*
popupWindow.outerHeight = 600;  // 팝업 창 세로길이
popupWindow.outerWidth = 400;	// 팝업 창 가로길이
popupWindow.location = '주소';  // 새 주소 지정
popupWindow.focus(); 	        // 팝업창을 포커스

c. Mobile - 모바일 환경 (iOS - 팝업 해제 필요, Android)

아래와 같이 a와 같은 방식이나 항상 새 탭으로 열립니다.

window.open('주소', '_blank', '옵션');

 


2. CLOSE - 팝업 창 닫기


a. Non-Mobile - 비모바일 환경

팝업 창이라 window를 쓰면 됨.

window.close();

b. Mobile - 모바일 환경 (iOS, Android)

탭이라 self를 쓰면 됨.

self.close();

모바일 브라우저엔 window라는 개념이 없기 때문입니다.
 

728x90

3. Parent Window - 부모창 데이터 연동 방법

부모창과 연동이 되기 위해서는 팝업 창과 부모 창의 도메인 주소가 같아야 합니다.


a. Non-Mobile - 비모바일 환경

var doc = window.opener.document;

b. Mobile - 모바일 환경 (iOS, Android)

var doc = opener.document;

부모 창이 doc이라는 변수에 지정된 후 다음과 같이 사용할 수 있습니다. 위의 2번 같이 모바일 브라우저엔 window라는 개념이 없기 때문입니다.

doc.getElementById('부모창의 엘리먼트 돔 ID').value = '새로운 값';

#. 부록

다음의 두 코드 블록은 모바일 환경인지와 사파리 브라우저인지 알려주는 자바스크립트 코드입니다.

// true = 모바일, false = 비모바일
function isMobile() {

    if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
        || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4))) {
        return true;
    }

    return false;
}
// true = 사파리 브라우저, false = 그외의 브라우저
function isSafariBrowser() {
    return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
}

즐겁게 코딩하세요. 감사합니다


도움이 되셨거나 즐거우셨다면 아래의 ❤️공감버튼이나 구독버튼을 눌러 주세요~  감사합니다

 

 

728x90
반응형

관련글 더보기