javascriptoverlaystoppropagation

keep wistia overlay open on click - e.stopPropogation on outside box preventing it from closing - stopPropgation misunderstanding


I have some overlays, one has a form and another has a video embed.

The form overlay stays open when you interact with it (I can't post the form because it's an embed and confidential) but the video one closes:

// demo overlay
  let demoButton = document.querySelectorAll('.demo-link-button');
  let demoFormOverlay = document.getElementById('demo-overlay');
  let demoFormOverlayClose = document.getElementById('demo-overlay-close');
  let mainDemoOverlays = document.querySelectorAll('.main-overlay-box');

  // video overlay
  let demoOnDemandButton = document.querySelectorAll('.vid-overlay-trigger');
  let demoOnDemandFormOverlay = document.getElementById('demo-ondemand-overlay');
  let demoOnDemandFormOverlayClose = document.getElementById('demo-ondemand-overlay-close');
  
  
  demoButton.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoFormOverlay.style.display = 'block';
    });
  });

  demoFormOverlayClose.addEventListener('click', function(e) {
    e.preventDefault();
    demoFormOverlay.style.display = 'none';
  });

  demoOnDemandButton.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoOnDemandFormOverlay.style.display = 'block';
    });
  });

  // multiple overlays
  mainDemoOverlays.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoOnDemandFormOverlay.style.display = 'none';
      demoFormOverlay.style.display = 'none';
    });
  });
  demoOnDemandFormOverlayClose.addEventListener('click', function(e) {
    e.preventDefault();
    demoOnDemandFormOverlay.style.display = 'none';
  });
.main-overlay-box {
    display: none;
    position: fixed;
    overflow: scroll;
    top: 0;
    left: 0;
    z-index: 900;
    width: 100%;
    height: 100%;
    background-color: rgb(0 0 0 / 56%);
}
<a class="demo-link-button" href="#">Open Overlay</a>
<a class="demo-link-button"  href="#">Open Overlay</a>
<a class="vid-overlay-trigger"  href="#">Open THE VIDEO Overlay</a>
<a class="vid-overlay-trigger"  href="#">Open THE VIDEO Overlay</a>

<div class="main-overlay-box" id="demo-overlay">
  <div class="demo-overlay-box">
    <a id="demo-overlay-close" href="#">X</a>
    <div style="background-color: #fff;">
      heres one overlay
    </div>
  </div>    
</div>

<div class="main-overlay-box" id="demo-ondemand-overlay">
  <div class="demo-overlay-box">
    <a id="demo-ondemand-overlay-close" href="#">X</a>
    <script src="//fast.wistia.com/embed/medias/s3lqfi0zn7.jsonp" async></script>
<script src="//fast.wistia.com/assets/external/E-v1.js" async></script>
<div class="wistia_embed wistia_async_s3lqfi0zn7" style="height:349px;width:620px">&nbsp;</div>
  </div>    
</div>

When you click on "Open THE VIDEO Overlay" and try to play the video...it won't stay open.

The logic is here:

  mainDemoOverlays.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoOnDemandFormOverlay.style.display = 'none';
      demoFormOverlay.style.display = 'none';
    });
  });

I then figured out it was bubbling so I changed it to:

// demo overlay
  let demoButton = document.querySelectorAll('.demo-link-button');
  let demoFormOverlay = document.getElementById('demo-overlay');
  let demoFormOverlayClose = document.getElementById('demo-overlay-close');
  let mainDemoOverlays = document.querySelectorAll('.main-overlay-box');

  // video overlay
  let demoOnDemandButton = document.querySelectorAll('.vid-overlay-trigger');
  let demoOnDemandFormOverlay = document.getElementById('demo-ondemand-overlay');
  let demoOnDemandFormOverlayClose = document.getElementById('demo-ondemand-overlay-close');
  
  demoButton.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoFormOverlay.style.display = 'block';
    });
  });

  demoFormOverlayClose.addEventListener('click', function(e) {
    e.preventDefault();
    demoFormOverlay.style.display = 'none';
  });

  demoOnDemandButton.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoOnDemandFormOverlay.style.display = 'block';
    });
  });

  // multiple overlays
  mainDemoOverlays.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      e.stopPropogation();
      demoOnDemandFormOverlay.style.display = 'none';
      demoFormOverlay.style.display = 'none';
    });
  });
  demoOnDemandFormOverlayClose.addEventListener('click', function(e) {
    e.preventDefault();
    demoOnDemandFormOverlay.style.display = 'none';
  });
.main-overlay-box {
    display: none;
    position: fixed;
    overflow: scroll;
    top: 0;
    left: 0;
    z-index: 900;
    width: 100%;
    height: 100%;
    background-color: rgb(0 0 0 / 56%);
}
<a class="demo-link-button" href="#">Open Overlay</a>
<a class="demo-link-button"  href="#">Open Overlay</a>
<a class="vid-overlay-trigger"  href="#">Open THE VIDEO Overlay</a>
<a class="vid-overlay-trigger"  href="#">Open THE VIDEO Overlay</a>

<div class="main-overlay-box" id="demo-overlay">
  <div class="demo-overlay-box">
    <a id="demo-overlay-close" href="#">X</a>
    <div style="background-color: #fff;">
      heres one overlay
    </div>
  </div>    
</div>

<div class="main-overlay-box" id="demo-ondemand-overlay">
  <div class="demo-overlay-box">
    <a id="demo-ondemand-overlay-close" href="#">X</a>
    <script src="//fast.wistia.com/embed/medias/s3lqfi0zn7.jsonp" async></script>
<script src="//fast.wistia.com/assets/external/E-v1.js" async></script>
<div class="wistia_embed wistia_async_s3lqfi0zn7" style="height:349px;width:620px">&nbsp;</div>
  </div>    
</div>

But now, when I click on the transparent black area the modal doesn't close.

Why is that?

https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases. It does not, however, prevent any default behaviors from occurring; for instance, clicks on links are still processed. If you want to stop those behaviors, see the preventDefault() method. It also does not prevent immediate propagation to other event-handlers. If you want to stop those, see stopImmediatePropagation().

So I then tried

// demo overlay
  let demoButton = document.querySelectorAll('.demo-link-button');
  let demoFormOverlay = document.getElementById('demo-overlay');
  let demoFormOverlayClose = document.getElementById('demo-overlay-close');
  let mainDemoOverlays = document.querySelectorAll('.main-overlay-box');

  // video overlay
  let demoOnDemandButton = document.querySelectorAll('.vid-overlay-trigger');
  let demoOnDemandFormOverlay = document.getElementById('demo-ondemand-overlay');
  let demoOnDemandFormOverlayClose = document.getElementById('demo-ondemand-overlay-close');
  
  demoButton.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoFormOverlay.style.display = 'block';
    });
  });

  demoFormOverlayClose.addEventListener('click', function(e) {
    e.preventDefault();
    demoFormOverlay.style.display = 'none';
  });

  demoOnDemandButton.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      demoOnDemandFormOverlay.style.display = 'block';
    });
  });

  // multiple overlays
  mainDemoOverlays.forEach(function(elem) {
    elem.addEventListener('click', function(e) {
      e.preventDefault();
      e.stopImmediatePropagation();
      demoOnDemandFormOverlay.style.display = 'none';
      demoFormOverlay.style.display = 'none';
    });
  });
  demoOnDemandFormOverlayClose.addEventListener('click', function(e) {
    e.preventDefault();
    demoOnDemandFormOverlay.style.display = 'none';
  });
.main-overlay-box {
    display: none;
    position: fixed;
    overflow: scroll;
    top: 0;
    left: 0;
    z-index: 900;
    width: 100%;
    height: 100%;
    background-color: rgb(0 0 0 / 56%);
}
<a class="demo-link-button" href="#">Open Overlay</a>
<a class="demo-link-button"  href="#">Open Overlay</a>
<a class="vid-overlay-trigger"  href="#">Open THE VIDEO Overlay</a>
<a class="vid-overlay-trigger"  href="#">Open THE VIDEO Overlay</a>

<div class="main-overlay-box" id="demo-overlay">
  <div class="demo-overlay-box">
    <a id="demo-overlay-close" href="#">X</a>
    <div style="background-color: #fff;">
      heres one overlay
    </div>
  </div>    
</div>

<div class="main-overlay-box" id="demo-ondemand-overlay">
  <div class="demo-overlay-box">
    <a id="demo-ondemand-overlay-close" href="#">X</a>
    <script src="//fast.wistia.com/embed/medias/s3lqfi0zn7.jsonp" async></script>
<script src="//fast.wistia.com/assets/external/E-v1.js" async></script>
<div class="wistia_embed wistia_async_s3lqfi0zn7" style="height:349px;width:620px">&nbsp;</div>
  </div>    
</div>

But now we're right back to where we started.

How do you keep a wistia embed video open to play click, and keep the close button and clicking off of it functional? How does stopPropogation() work/how should it work in this context?

Or am I off and is stopPropogation() not the right concept here?


Solution

  • If I understand you correctly, do you want this (so far only on the example of the video)?

    // demo overlay
    let demoButton = document.querySelectorAll('.demo-link-button');
    let demoFormOverlay = document.getElementById('demo-overlay');
    let demoFormOverlayClose = document.getElementById('demo-overlay-close');
    let mainDemoOverlays = document.querySelectorAll('.main-overlay-box');
    
    // video overlay
    let demoOnDemandButton = document.querySelectorAll('.vid-overlay-trigger');
    let demoOnDemandFormOverlay = document.getElementById('demo-ondemand-overlay');
    let demoOnDemandFormOverlayClose = document.getElementById('demo-ondemand-overlay-close');
    
    
    demoButton.forEach(function(elem) {
      elem.addEventListener('click', function(e) {
        e.preventDefault();
        demoFormOverlay.style.display = 'block';
      });
    });
    
    demoFormOverlayClose.addEventListener('click', function(e) {
      e.preventDefault();
      demoFormOverlay.style.display = 'none';
    });
    
    demoOnDemandButton.forEach(function(elem) {
      elem.addEventListener('click', function(e) {
        e.preventDefault();
        demoOnDemandFormOverlay.style.display = 'block';
      });
    });
    
    // multiple overlays
    mainDemoOverlays.forEach(function(elem) {
      elem.addEventListener('click', function(e) {
        e.preventDefault();
        demoOnDemandFormOverlay.style.display = 'none';
        demoFormOverlay.style.display = 'none';
      });
    });
    demoOnDemandFormOverlayClose.addEventListener('click', function(e) {
      e.preventDefault();
      demoOnDemandFormOverlay.style.display = 'none';
    });
    
    document.querySelector(".wistia_embed").addEventListener("click", e => {
      e.preventDefault();
      e.stopPropagation();
    });
    .main-overlay-box {
      display: none;
      position: fixed;
      overflow: scroll;
      top: 0;
      left: 0;
      z-index: 900;
      width: 100%;
      height: 100%;
      background-color: rgb(0 0 0 / 56%);
    }
    <a class="demo-link-button" href="#">Open Overlay</a>
    <a class="demo-link-button" href="#">Open Overlay</a>
    <a class="vid-overlay-trigger" href="#">Open THE VIDEO Overlay</a>
    <a class="vid-overlay-trigger" href="#">Open THE VIDEO Overlay</a>
    
    <div class="main-overlay-box" id="demo-overlay">
      <div class="demo-overlay-box">
        <a id="demo-overlay-close" href="#">X</a>
        <div style="background-color: #fff;">
          heres one overlay
        </div>
      </div>
    </div>
    
    <div class="main-overlay-box" id="demo-ondemand-overlay">
      <div class="demo-overlay-box">
        <a id="demo-ondemand-overlay-close" href="#">X</a>
        <script src="//fast.wistia.com/embed/medias/s3lqfi0zn7.jsonp" async></script>
        <script src="//fast.wistia.com/assets/external/E-v1.js" async></script>
        <div class="wistia_embed wistia_async_s3lqfi0zn7" style="height:349px;width:620px">&nbsp;</div>
      </div>
    </div>