Opening an external website in a modal popup

27,297

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:

  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>

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>
Share:
27,297
Basj
Author by

Basj

I work on R&amp;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, 2020

Comments

  • Basj
    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
      Sphinx about 6 years
      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.
    • Basj
      Basj about 6 years
      @Sphinx Could you post a working snippet? Thanks in advance.
  • Basj
    Basj about 6 years
    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?
  • Sphinx
    Sphinx about 6 years
    Updated the answer, thought of the solution overcomplicated... To removed the setTimeout, we can simply added another parameter to indicate if already initialized.
  • Sphinx
    Sphinx about 6 years
    @Basj, updated the answer, it provides another idea to implement popup modal.
  • Basj
    Basj about 6 years
    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).