Improve window open and close handling

Use pagehide event instead of beforeunload, seems to be more reliable
Add a timeout and info message when opening the window fails
This commit is contained in:
Maximilian Krög
2021-10-20 01:18:05 +02:00
parent 5149224354
commit 7bed63bf3f
3 changed files with 46 additions and 27 deletions

View File

@@ -1,11 +1,11 @@
--- ---
layout: example.html layout: example.html
title: External map title: External map
shortdesc: Show a map in a separate window. shortdesc: Move a map to a seperate window.
docs: > docs: >
Move a map to a seperate window.
tags: "external, window" tags: "external, window"
resources:
--- ---
<div id="map" class="map"></div> <div id="map" class="map"></div>
<input id="extMap" type="button" value="Open external map"></input> <input id="external-map-button" type="button" value="Open external map"></input>
<span id="blocker-notice" hidden>Could not open map in external window. If you are using an popup or ad blocker you may need to disable it for this example.</span>

View File

@@ -5,8 +5,10 @@ import View from '../src/ol/View.js';
import {FullScreen, defaults as defaultControls} from '../src/ol/control.js'; import {FullScreen, defaults as defaultControls} from '../src/ol/control.js';
import {fromLonLat} from '../src/ol/proj.js'; import {fromLonLat} from '../src/ol/proj.js';
const localMapTarget = document.getElementById('map');
const map = new Map({ const map = new Map({
target: 'map', target: localMapTarget,
controls: defaultControls().extend([new FullScreen()]), controls: defaultControls().extend([new FullScreen()]),
layers: [ layers: [
new TileLayer({ new TileLayer({
@@ -20,33 +22,54 @@ const map = new Map({
}); });
let mapWindow; let mapWindow;
const button = document.getElementById('extMap'); function closeMapWindow() {
if (mapWindow) {
mapWindow.close();
mapWindow = undefined;
}
}
// Close external window in case the main page is closed or reloaded
window.addEventListener('pagehide', closeMapWindow);
const button = document.getElementById('external-map-button');
function resetMapTarget() {
localMapTarget.style.height = '';
map.setTarget(localMapTarget);
button.disabled = false;
}
button.addEventListener('click', function () { button.addEventListener('click', function () {
const localMapTarget = document.getElementById('map'); const blockerNotice = document.getElementById('blocker-notice');
localMapTarget.style.height = '0px'; blockerNotice.setAttribute('hidden', 'hidden');
button.disabled = true; button.disabled = true;
// Reset button and map target in case window did not load or open
let timeoutKey = setTimeout(function () {
closeMapWindow();
resetMapTarget();
blockerNotice.removeAttribute('hidden');
timeoutKey = undefined;
}, 3000);
mapWindow = window.open( mapWindow = window.open(
'resources/external-map-map.html', 'resources/external-map-map.html',
'MapWindow', 'MapWindow',
'toolbar=0,location=0,menubar=0,width=800,height=600' 'toolbar=0,location=0,menubar=0,width=800,height=600'
); );
mapWindow.addEventListener('load', function () { mapWindow.addEventListener('DOMContentLoaded', function () {
const extMapDiv = mapWindow.document.getElementById('map'); const externalMapTarget = mapWindow.document.getElementById('map');
map.setTarget(extMapDiv); localMapTarget.style.height = '0px';
extMapDiv.focus(); map.setTarget(externalMapTarget);
externalMapTarget.focus();
mapWindow.addEventListener('beforeunload', function () { if (timeoutKey) {
localMapTarget.style.height = ''; timeoutKey = clearTimeout(timeoutKey);
map.setTarget(localMapTarget); }
button.disabled = false; mapWindow.addEventListener('pagehide', function () {
resetMapTarget();
mapWindow = undefined; // Close window in case user does a page reload
closeMapWindow();
}); });
}); });
}); });
window.addEventListener('beforeunload', function () {
if (mapWindow) {
mapWindow.close();
}
});

View File

@@ -13,10 +13,6 @@
</style> </style>
</head> </head>
<body> <body>
<script type="text/javascript">
if ((window.performance.navigation && window.performance.navigation.type === 1) || window.performance.getEntriesByType('navigation').map((nav) => nav.type).includes('reload'))
window.close();
</script>
<div id="map" class="map" tabindex="0"></div> <div id="map" class="map" tabindex="0"></div>
</body> </body>
</html> </html>