Opening an external website in a modal popup
Solution 1
The root cause is page.onclick is registered after popup window is open at the first time, then the following 'open popup' will trigger a.onclick and page.onclick in a row, that caused the popup window is open then is closed directly
.
The simple solution is add one parameter to control the state of the popup. if the popup is closed, do nothing in page.onclick.
To remove setTimeout, there are two solution:
added another parameter to control the state of the popup initialization.
Don't make
<div id="page">
is the parent of<a id="popup">
, so<a id="popup">
will not be triggered when clicked<div id="page">
.
Below are two solutions:
I prefer the Solution2, it is better decoupling than Solution1, every component foucs on its own jobs.
Solution 1: added isInit
as the indicator if the popup already finished initialization.
PS: In the comment, you mentioned close the popup only when click on <div id="page">
, to implement this in solution1, I think you have to bind the event =mouseout
, mouseenter
to judge where the mouse clicks.
document.getElementById("a").onclick = function(e) {
e.preventDefault();
var isInit = true; // indicates if the popup already been initialized.
var isClosed = false; // indicates the state of the popup
document.getElementById("popup").style.display = "block";
document.getElementById('iframe').src = "http://example.com";
document.getElementById('page').className = "darken";
document.getElementById('page').onclick = function() {
if(isInit){isInit=false;return;}
if(isClosed){return;} //if the popup is closed, do nothing.
document.getElementById("popup").style.display = "none";
document.getElementById('page').className = "";
isClosed=true;
}
return false;
}
#popup {
display: none;
border: 1px black solid;
width: 400px; height: 200px;
top:20px; left:20px;
background-color: white;
z-index: 10;
padding: 2em;
position: fixed;
}
.darken { background: rgba(0, 0, 0, 0.7); }
#iframe { border: 0; }
html, body, #page { height: 100%; }
<div id="page">
<a href="" id="a">Click me</a><br>
Hello<br>
Hello<br>
<div id="popup">
External website:
<iframe id="iframe"></iframe>
</div>
</div>
Solution 2: make <div id="page">
and <a id="popup">
is cousin not parent relations.
document.getElementById("popup").showpopup = function() {
document.getElementById("popup").style.display = "block";
document.getElementById('iframe').src = "http://example.com";
document.getElementById('page').className = "darken";
document.getElementById("page").style.display = "block";
}
document.getElementById("a").onclick = function(e) {
e.preventDefault();
document.getElementById("popup").showpopup();
}
document.getElementById('page').onclick = function() {
if(document.getElementById("popup").style.display == "block") {
document.getElementById("popup").style.display = "none";
document.getElementById("page").style.display = "none";
document.getElementById('page').className = "";
}
};
#popup {
display: none;
border: 1px black solid;
width: 400px; height: 200px;
top:20px; left:20px;
background-color: white;
z-index: 10;
padding: 2em;
position: fixed;
}
#page {
display: none;
width: 100%; height: 100%;
top:0px; left:0px;
z-index: 9;
padding: 2em;
position: absolute;
}
.darken { background: rgba(0, 0, 0, 0.7); }
#iframe { border: 0; }
html, body, #page { height: 100%; }
<a href="" id="a">Click me</a><br>
Hello<br>
Hello<br>
<div id="page">
</div>
<div id="popup">
External website:
<iframe id="iframe"></iframe>
</div>
Solution 2
Based on Sphinx's great answer, here is what I'll use to create a modal popup displaying an external website in a iframe
with a dark background for the rest of the page when the popup is open:
document.getElementById("link").onclick = function(e) {
e.preventDefault();
document.getElementById("popupdarkbg").style.display = "block";
document.getElementById("popup").style.display = "block";
document.getElementById('popupiframe').src = "http://example.com";
document.getElementById('popupdarkbg').onclick = function() {
document.getElementById("popup").style.display = "none";
document.getElementById("popupdarkbg").style.display = "none";
};
return false;
}
window.onkeydown = function(e) {
if (e.keyCode == 27) {
document.getElementById("popup").style.display = "none";
document.getElementById("popupdarkbg").style.display = "none";
e.preventDefault();
return;
}
}
#popup { display: none; position: fixed; top: 12%; left: 15%; width: 70%; height: 70%; background-color: white; z-index: 10; }
#popup iframe { width: 100%; height: 100%; border: 0; }
#popupdarkbg { position: fixed; z-index: 5; left: 0; top: 0; width: 100%; height: 100%; overflow: hidden; background-color: rgba(0,0,0,.75); display: none; }
<div id="main">
<a href="" id="link">Click me</a><br>
</div>
<div id="popup"><iframe id="popupiframe"></iframe></div>
<div id="popupdarkbg"></div>
Basj
I work on R&D involving Python, maths, machine learning, deep learning, data science, product design, and MacGyver solutions to complex problems. I love prototyping, building proofs-of-concept. For consulting/freelancing inquiries : [email protected]
Updated on August 29, 2020Comments
-
Basj over 3 years
I know that
<a href="http://www.example.com" target="_blank">Click here</a>
opens the link in a new tab (default behaviour in Chrome and Firefox) and that<a href="http://www.example.com" onclick="window.open('http://www.example.com', 'newwindow', 'width=700,height=500'); return false;">Click here</a>
opens it in a new window.
But how to open an external page in a modal popup (centered on screen, rest of the original page "darkened")?
Is there a nice way to do it?
I tried the following code, but it doesn't seem to be working (click: popup opens, reclick, it closes, reclick on link: it doesn't open anymore. Also the iframe doesn't load).
document.getElementById("a").onclick = function(e) { e.preventDefault(); document.getElementById("popup").style.display = "block"; document.getElementById('iframe').src = "http://example.com"; document.getElementById('page').className = "darken"; setTimeout(function() { document.getElementById('page').onclick = function() { document.getElementById("popup").style.display = "none"; document.getElementById('page').className = ""; } }, 100); return false; }
#popup { display: none; border: 1px black solid; width: 400px; height: 200px; top:20px; left:20px; background-color: white; z-index: 10; padding: 2em; position: fixed; } .darken { background: rgba(0, 0, 0, 0.7); } #iframe { border: 0; } html, body, #page { height: 100%; }
<div id="page"> <a href="" id="a">Click me</a><br> Hello<br> Hello<br> <div id="popup"> External website: <iframe id="iframe"></iframe> </div> </div>
-
Sphinx about 6 yearsThe root cause is page.onclick is register after pop up at first time, then the following 'open popup' will trigger a.onclick and page.onclick in a row, that caused the popup is open then is closed directly.
-
Basj about 6 years@Sphinx Could you post a working snippet? Thanks in advance.
-
-
Basj about 6 yearsI had put the
setTimeout
to avoid that the first click automatically triggers the close, could we remove it thanks to your method? Also it would be needed that clicking inside the popup doesn't close it: only clicking outside the popup should close it, how to change this? -
Sphinx about 6 yearsUpdated the answer, thought of the solution overcomplicated... To removed the
setTimeout
, we can simply added another parameter to indicate if already initialized. -
Sphinx about 6 years@Basj, updated the answer, it provides another idea to implement popup modal.
-
Basj about 6 yearsNote: SO disables external website loading in
iframe
of code snippets (for good reasons), so don't forget to enable it to run this code snippet (small icon on top right of browser address bar).