상세 컨텐츠

본문 제목

Create A Versatile and Stable Popup Window For All OS's and Browsers - JavaScript

본문

Creating a versatile and stable popup window in a web app is a difficult task because browsers and OS's behave differently.  After some research and trial-and-error, I have found that the method below makes is possible to be compatible on all browsers in any OS environments (Windows, Android, macOS and iOS).  
 

반응형

The biggest hurdle was the Safari browser in iOS and macOS.  In iOS, you have to enable Popup in iOS settings.  In macOS, you have to enable Popups in the browser settings.  In addition to those issuse, Safari browser in macOS blocks any popups in the asynchronous calls (e.g. any ajax calls).   Therefore you must include all possible scenarios when buidling a stable popup window in JavaScript. 
 
I have separated the article in two sections on each topic - mobile and non-mobile scenario - for your easier digestion.
 

728x90

1.  Open

 

A. Non-Mobile - Windows and macOS (EXCLUDING Safari browser)

window.open('[destination address]', '_blank', '[window option]');

 

B. Non-Mobile - macOS - Safari browser - MUST ENABLE POPUP IN BROWSER SETTINGS

Immediately open a blank popup window when a button or function call happens. Then store the window to a variable to use it during the async call.  If you do not assign "height" and "width" in the option, it will automatically open a new tab.

// IN THE MAIN FUNCTION
let windowPopup;

// IN THE BUTTON CLICK EVENT
windowPopup = window.open(null, '_blank', 'height=10,width=10');

After async call, you can change the window option in the callback function (example below).

// IN THE ASYNC CALLBACK FUNCTION
popupWindow.outerHeight = 600;  // SET HEIGHT OF POPUP WINDOW
popupWindow.outerWidth = 400;	// SET WIDTH OF POPUP WINDOW
popupWindow.location = 'destination address';  // SET DESTINATION ADDRESS
popupWindow.focus(); 	        // FOCUS THE POPUP WINDOW

 

C. Mobile (if iOS, you must enable popup in the iOS settings)

The process is the same as OPTION A above, but it will always open a new tab.

window.open('[destination address]', '_blank', '[window option]');

 

2.  Close

 

A. Non-Mobile 

Non-mobile browsers has a concept of "window", so just use window.close()

window.close();

 

B. Mobile (iOS, Android)

Mobile browsers do not have a concept of "window".  They are tab-based, so use self.close()

self.close();

3.  Interact with Parent Window

In order to interact with the parent window, both parent and child windows must have the same domain (browser security).  Store the parent window to a variable in the child window.

 

A. Non-Mobile

var doc = window.opener.document;

 

B. Mobile 

var doc = opener.document;

As you see the examples above, the parent window is now stored as a variable in the child window.  Then you can call anything in the parent window (example below).

doc.getElementById('DOM ID IN THE PARENT WINDOW').value = 'NEW VALUE TO SET';

#.  CODE - HOW TO DETECT BROWSERS AND OS

The two sets of code below will help you detect mobile or non-mobile AND Safari or non-Safari browsers.
 

A. Detect Mobile / Non-Mobile OS

// true = mobile, false = non-mobile
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;
}

 

B. Detect Safari / Non-Safari Browsers

// true = Safari, false = non-Safari
function isSafariBrowser() {
    return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
}

 

728x90
반응형

관련글 더보기