3

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>
Basj
  • 41,386
  • 99
  • 383
  • 673
  • The 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. – Sphinx Feb 28 '18 at 22:12
  • @Sphinx Could you post a working snippet? Thanks in advance. – Basj Feb 28 '18 at 22:13

3 Answers3

7

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
  • 41,386
  • 99
  • 383
  • 673
  • Note: 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). – Basj Mar 03 '18 at 15:10
5

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:

  1. added another parameter to control the state of the popup initialization.

  2. 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>
Sphinx
  • 10,519
  • 2
  • 27
  • 45
  • I 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? – Basj Feb 28 '18 at 22:17
  • Updated the answer, thought of the solution overcomplicated... To removed the `setTimeout`, we can simply added another parameter to indicate if already initialized. – Sphinx Feb 28 '18 at 23:42
  • @Basj, updated the answer, it provides another idea to implement popup modal. – Sphinx Mar 01 '18 at 00:51
0

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"> height=“200”</iframe>
  </div>

</div>
IdioticDev
  • 23
  • 8