Moderator |
|
Het idee
Voor wat complexere backends heb ik waarschijnlijk op den duur meerdere gerelateerde informatieschermen nodig die soortgelijke data bijwerken, waarbij ik steeds verder inzoom op de informatie die ik wil aanpassen. Het idee is dat ik daarvoor meerdere popups gebruik.
De uitdagingen
Ondertussen ben ik al tegen een aantal dingen aan gelopen:
* Als je een (of meerdere) popup(s) opent, wil je de onderliggende pagina('s) waarschijnlijk "vergrendelen" zodat je alleen informatie kunt wijzigen op het laagste gelegen niveau. Dit omdat je wijzigingen mogelijk van invloed zijn op informatie uit bovengelegen niveau's.
Oplossing: vanuit de popup zet je een absoluut gepositioneerde div over de inhoud van je parent window, en deze verwijder je weer wanneer je de popup sluit.
* Je schakelt tussen applicaties en je popup volgorde raakt ontregeld en/of je raakt je "actieve" popup kwijt
Oplossing: door het klikken op een "inactief" window wordt de bijbehorende popup gefocust. Dit proces kun je herhalen totdat je de laatst geopende (actieve) popup bereikt
* Als je een popup sluit via een link moet het parent window weer ontgrendeld worden. Ook als je op het kruisje (de X knop van het window) klikt.
Oplossing: schrijf code (bijvoorbeeld een functie) voor zowel deze link klik als het onbeforeunload event.
* Je wilt de inhoud van een popup kunnen herladen.
In de huidige opzet wordt daarmee het onbeforeunload event getriggerd, wat er waarschijnlijk mede voor zorgt dat de popup gesloten wordt. Dit willen we niet.
Oplossing: voorzie links / acties die de pagina verversen van code die het onbeforeunload onklaar maakt (en als de pagina herladen is staat deze weer "op scherp".
* Als je klaar bent met een popup dan kan dit gevolgen hebben voor de samenstelling van de informatie van het bovengelegen scherm. Je hebt bijvoorbeeld in de popup gegevens aangepast die op het bovengelegen scherm al werden weergegeven. Dit scherm zou dus ververst moeten worden (zonder dat deze gesloten wordt ).
Oplossing: combineer dit in de code die zorgt voor het sluiten van de huidige popup.
Voorlopige opzet
Okay, sommige dingen zijn nog hardcoded, ook gebruik ik (nog) geen jQuery voor betere crossbrowser compatibiliteit, maar de volgende code werkt al best aardig. Hierin zijn alle bovenstaande punten / wensen verwerkt en het werkt al best intuitief.
popup.js
var popupWindow = null;
var popupOpener = window.opener;
// Note that the popup name must be unique.
function popup(url, name) {
var left = window.screenX;
var top = window.screenY;
popupWindow = window.open(url, name, 'left='+(left + 50)+',top='+(top + 25)+',width=640,height=480');
return false;
}
function focusPopup() {
if (window.popupWindow) {
popupWindow.focus();
}
}
// For use inside popups
// as an alternative, you could add an event listener to the popupWindow
// when it completes loading you can execute a callback function
// @see http://stackoverflow.com/questions/1372022/waiting-for-child-window-loading-to-complete
function popupOnLoad() {
var parentOverlay = popupOpener.document.getElementById('overlay');
parentOverlay.style.display = 'block';
}
// close as reserved name does not work well
function popupClose(refreshParent) {
var parentOverlay = popupOpener.document.getElementById('overlay');
parentOverlay.style.display = 'none';
// popupOpener.focus(); // does not work, needs to be called from creator?
if (refreshParent) {
popupOpener.disablePopupClose();
popupOpener.location.reload();
}
window.close();
return false;
}
// temporarily disable onbeforeunload so popup does not close when refreshing content
function disablePopupClose() {
window.onbeforeunload = null;
}
var popupWindow = null; var popupOpener = window.opener; // Note that the popup name must be unique. function popup(url, name) { var left = window.screenX; var top = window.screenY; popupWindow = window.open(url, name, 'left='+(left + 50)+',top='+(top + 25)+',width=640,height=480'); return false; } function focusPopup() { if (window.popupWindow) { popupWindow.focus(); } } // For use inside popups // as an alternative, you could add an event listener to the popupWindow // when it completes loading you can execute a callback function // @see http://stackoverflow.com/questions/1372022/waiting-for-child-window-loading-to-complete function popupOnLoad() { var parentOverlay = popupOpener.document.getElementById('overlay'); parentOverlay.style.display = 'block'; } // close as reserved name does not work well function popupClose(refreshParent) { var parentOverlay = popupOpener.document.getElementById('overlay'); parentOverlay.style.display = 'none'; // popupOpener.focus(); // does not work, needs to be called from creator? if (refreshParent) { popupOpener.disablePopupClose(); popupOpener.location.reload(); } window.close(); return false; } // temporarily disable onbeforeunload so popup does not close when refreshing content function disablePopupClose() { window.onbeforeunload = null; }
style.css
#overlay { position: absolute; width: 100%; height: 100%; left: 0; top: 0; z-index: 999; background-color: #666666; display: none; opacity: 0.9; }
#overlay { position: absolute; width: 100%; height: 100%; left: 0; top: 0; z-index: 999; background-color: #666666; display: none; opacity: 0.9; }
index.htm
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>popup test</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="popup.js"></script>
</head>
<body>
<div id="overlay" onclick="focusPopup()"></div>
<a href="javascript:void(0)" onclick="return popup('popup.htm', 'een');">popup</a>
</body>
</html>
<!DOCTYPE html> <link rel="stylesheet" type="text/css" href="style.css" /> <div id="overlay" onclick="focusPopup()"></div> <a href="javascript:void(0)" onclick="return popup('popup.htm', 'een');">popup </a>
popup.htm (popup level 1)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>popup test</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="popup.js"></script>
</head>
<body onbeforeunload="popupClose()">
<div id="overlay" onclick="focusPopup()"></div>
<a href="javascript:void(0)" onclick="return popup('popup2.htm', 'twee')">another popup</a>
<a href="popup.htm" onclick="disablePopupClose()">refresh me</a>
<a href="javascript:void(0)" onclick="return popupClose(false)">close</a>
<script type="text/javascript">
//<![CDATA[
// you probably only want to call this the first time you load this popup
popupOnLoad();
alert('loaded');
//]]>
</script>
</body>
</html>
<!DOCTYPE html> <link rel="stylesheet" type="text/css" href="style.css" /> <body onbeforeunload="popupClose()"> <div id="overlay" onclick="focusPopup()"></div> <a href="javascript:void(0)" onclick="return popup('popup2.htm', 'twee')">another popup </a> <a href="popup.htm" onclick="disablePopupClose()">refresh me </a> <a href="javascript:void(0)" onclick="return popupClose(false)">close </a> <script type="text/javascript"> //<![CDATA[ // you probably only want to call this the first time you load this popup popupOnLoad(); alert('loaded'); //]]>
popup2.htm (popup level 2)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>popup test 2</title>
<style type="text/css">
</style>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="popup.js"></script>
</head>
<body onbeforeunload="popupClose()">
<div id="overlay"></div>
<a href="javascript:void(0)" onclick="return popupClose(false)">close</a>
<a href="javascript:void(0)" onclick="return popupClose(true)">close and refresh</a>
<script type="text/javascript">
//<![CDATA[
// you probably only want to call this the first time you load this popup
popupOnLoad();
//]]>
</script>
</body>
</html>
<!DOCTYPE html> <link rel="stylesheet" type="text/css" href="style.css" /> <body onbeforeunload="popupClose()"> <a href="javascript:void(0)" onclick="return popupClose(false)">close </a> <a href="javascript:void(0)" onclick="return popupClose(true)">close and refresh </a> <script type="text/javascript"> //<![CDATA[ // you probably only want to call this the first time you load this popup popupOnLoad(); //]]>
Of probeer het hier uit.
Ideeën / suggesties?
|