웹앱에서 팝업 창을 이용하는 것이 아주 까다롭습니다. 더군다나 iOS에서는 잘 호환이 안되죠. 여러 리서치를 하고 나서 테스트 결과 다음 아래의 방법이 Windows, Android, macOS, iOS에서의 여러 브라우저와 호환이 가능하다고 결론이 나왔습니다.
문제 되는 점은 iOS와 macOS의 사파리 브라우저입니다. iOS는 먼저 iOS 세팅에서 팝업 해제를 하여야 하고 macOS 에서는 사파리 브라우저 세팅에서 팝업 해제를 해야 합니다. 게다가 macOS의 사파리는 asynchronous 콜에서 (예제로 $.ajax 콜) callback 함수 중에 팝업창을 열지 못하게 막아놨습니다. 그래서 모든 상황에 맞춰서 코딩을 해야 하죠.
팝업창 사용 시 유용한 세 가지 기능을 비모바일과 모바일 환경으로 나누어 알려드리겠습니다.
window.open('주소', '_blank', '옵션');
버튼이 눌러지거나 함수가 발동되는 즉시 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(); // 팝업창을 포커스
아래와 같이 a와 같은 방식이나 항상 새 탭으로 열립니다.
window.open('주소', '_blank', '옵션');
팝업 창이라 window를 쓰면 됨.
window.close();
탭이라 self를 쓰면 됨.
self.close();
모바일 브라우저엔 window라는 개념이 없기 때문입니다.
부모창과 연동이 되기 위해서는 팝업 창과 부모 창의 도메인 주소가 같아야 합니다.
var doc = window.opener.document;
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);
}
즐겁게 코딩하세요. 감사합니다
도움이 되셨거나 즐거우셨다면 아래의 ❤️공감버튼이나 구독버튼을 눌러 주세요~ 감사합니다
AutoMapper (오토매퍼) 사용법 - C# & .NET (0) | 2022.12.05 |
---|---|
Azure AKS (에저 쿠버네티스 서비스) 에서 Prometheus (프로메테우스) 와 Grafana (그라파나) 설치 - Powershell (0) | 2022.12.02 |
.NET gRPC 서버 제작과 gRPC-Web 기능 넣기 (0) | 2022.11.28 |
React (리액트) 와 gRPC-Web : PART 2 : gRPC-Web 서버로 부터 데이터 받기 (0) | 2022.11.28 |
React (리액트) 와 gRPC-Web : PART 1 : 윈도즈 환경에서의 Protobuf 컴필레이션 방법 (0) | 2022.11.25 |