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.
window.open('[destination address]', '_blank', '[window option]');
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
The process is the same as OPTION A above, but it will always open a new tab.
window.open('[destination address]', '_blank', '[window option]');
Non-mobile browsers has a concept of "window", so just use window.close()
window.close();
Mobile browsers do not have a concept of "window". They are tab-based, so use self.close()
self.close();
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.
var doc = window.opener.document;
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';
The two sets of code below will help you detect mobile or non-mobile AND Safari or non-Safari browsers.
// 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;
}
// true = Safari, false = non-Safari
function isSafariBrowser() {
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
}
Comprehensive Setup Guide for Prometheus and Grafana in AKS - Powershell (0) | 2023.02.20 |
---|---|
Table-Valued Function (TVF) Explained (with Examples) - T-SQL (0) | 2023.02.19 |
PART 2 - How To Get Data from gRPC-Web Server using the Prot - REACT (0) | 2023.01.29 |
PART 1 - How To Compile Protobuf in Windows Environment - REACT (0) | 2023.01.29 |
Add CORS To gRPC-Web Server - C# & .NET (0) | 2023.01.29 |