javascripthtmljquerycssdivi

Close popup by clicking the outside area using jQuery


I am working with this tutorial to create a popup using Divi. https://divilover.com/divi-popup-without-plugins-tutorial/ I am having difficulty modifying the javascript to close the popup by clicking the outside area. Here is the code: ( I have tried many edits but StackOverflow is complaining I have already entered too much code. )

jQuery(document).ready(function($) {
    
    
    $('.dl-popup-content').each(function(){
        $(this).wrap('<div class="dl-popup-wrapper"><div class="dl-popup-inside">');
    });
        
        
    $('.dl-popup-trigger, .dl-menu-popup > a').off().click(function(e){
        e.preventDefault();
        SectionID = $(this).attr('href');
        $(SectionID).closest('.dl-popup-wrapper').addClass('popup-is-visible');
        $(SectionID).closest('.et_builder_inner_content').addClass('popup-is-visible');
        $('body').addClass('dl-noscroll');
                
    }); 
            
    $('.dl-popup-close').click(function(e){
        e.preventDefault();
        $('.popup-is-visible').removeClass('popup-is-visible');
        $('body').removeClass('dl-noscroll');
        
        var PopupVideoIframe = $(this).closest('.dl-popup-content').find('.et_pb_video_box iframe');
        var PopupVideoSrc = PopupVideoIframe.attr("src");
        PopupVideoIframe.attr("src", PopupVideoSrc);
        
        var PopupVideoHTML = $(this).closest('.dl-popup-content').find('.et_pb_video_box video');
        PopupVideoHTML.trigger('pause');
    });


}); 
/* Show/hide the popup overlay wrapper when "is-visible" class changes, apply the CSS to frontend only */
body:not(.et-fb) .dl-popup-wrapper {
  position:fixed;
  z-index:990;
  top:0;
  right:0;
  bottom:0;
  left:0;
  transition: all .5s cubic-bezier(.14,.06,.41,1.39);
  opacity:0;
  visibility:hidden;
}
body:not(.et-fb) .dl-popup-wrapper.popup-is-visible {
  opacity:1;
  visibility:visible;
}


/* Allow the content inside the popup wrapper to scroll */
.dl-popup-inside {
  height:100%;
  overflow-y: scroll;
}


/* Prevent Body from Scrolling when Popup is visible */
body.dl-noscroll {
  overflow: hidden;
}

/* Center Align Popup Content inside the Section */
.dl-popup-content {
  display:flex;
  flex-direction:column;
  justify-content: center;
}
.dl-popup-content .et_pb_row {
  margin-top:0;
  margin-bottom:0;
}


/* Adjust the position of the popup overlay for admin bar */
@media (min-width:600px) and (max-width:782px) {
  body:not(.et-fb).admin-bar .dl-popup-wrapper {
    top:46px;
  }
}
@media (min-width:783px) {
  body:not(.et-fb).admin-bar .dl-popup-wrapper {
    top:32px;
  }
}

/* Mave the popup on top of other elements */
.et_builder_inner_content.popup-is-visible {
  z-index:99999;
}

/* Add a hand cursor to the close trigger element */
.dl-popup-close {
  cursor:pointer;
}

/* Add Row animation when popup is triggered */
.dl-popup-wrapper.popup-is-visible .et_pb_row:not(.dl-popup-close) {animation:scale-in .5s cubic-bezier(.14,.06,.41,1.39) both; animation-delay: .5s; }
@keyframes scale-in{0%{transform:scale(0.3);opacity:0}100%{transform:scale(1);opacity:1}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<a href="#contact" class="dl-popup-trigger">Click here</a>
<div id="contact" class="et_pb_section et_pb_section_0 dl-popup-content et_section_regular">
  <div class="et_pb_row et_pb_row_0">
    <div class="et_pb_column et_pb_column_4_4 et_pb_column_0  et_pb_css_mix_blend_mode_passthrough et-last-child">
      <div class="et_pb_module et_pb_icon et_pb_icon_0 dl-popup-close"> <span class="et_pb_icon_wrap "><span class="et-pb-icon"></span></span> </div>
      <div class="et_pb_module et_pb_text et_pb_text_0  et_pb_text_align_left et_pb_bg_layout_light">
        <div class="et_pb_text_inner">
          <h4 class="center red">Popup Content</h4>
        </div>
      </div>
    </div>
  </div>
</div>


Solution

  • To make the popup close when clicking outside of it, you need to add event listeners that detect clicks outside the .dl-popup-content area. Here's an update to your JavaScript that will properly handle this functionality.

    jQuery(document).ready(function($) {
        
        // Wrap the popup content inside a wrapper
        $('.dl-popup-content').each(function() {
            $(this).wrap('<div class="dl-popup-wrapper"><div class="dl-popup-inside">');
        });
    
        // Trigger to open the popup when the button/link is clicked
        $('.dl-popup-trigger, .dl-menu-popup > a').off().click(function(e) {
            e.preventDefault();
            var SectionID = $(this).attr('href');
            $(SectionID).closest('.dl-popup-wrapper').addClass('popup-is-visible');
            $(SectionID).closest('.et_builder_inner_content').addClass('popup-is-visible');
            $('body').addClass('dl-noscroll');
        });
    
        // Close the popup when the close button is clicked
        $('.dl-popup-close').click(function(e) {
            e.preventDefault();
            closePopup();
        });
    
        // Close the popup when clicking outside the popup content (wrapper)
        $(document).click(function(e) {
            // If the click is outside of the popup content, close the popup
            if (!$(e.target).closest('.dl-popup-content').length && !$(e.target).closest('.dl-popup-trigger').length) {
                closePopup();
            }
        });
    
        // Function to close the popup
        function closePopup() {
            $('.popup-is-visible').removeClass('popup-is-visible');
            $('body').removeClass('dl-noscroll');
            
            // If there's a video inside the popup, stop the video
            var PopupVideoIframe = $('.popup-is-visible').find('.et_pb_video_box iframe');
            var PopupVideoSrc = PopupVideoIframe.attr("src");
            PopupVideoIframe.attr("src", PopupVideoSrc); // Reset the iframe src to stop the video
    
            var PopupVideoHTML = $('.popup-is-visible').find('.et_pb_video_box video');
            PopupVideoHTML.trigger('pause'); // Pause the video
        }
    });
    /* General Popup Wrapper */
    body:not(.et-fb) .dl-popup-wrapper {
      position: fixed;
      z-index: 990;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      transition: all 0.5s cubic-bezier(.14, .06, .41, 1.39);
      opacity: 0;
      visibility: hidden;
      background: rgba(0, 0, 0, 0.5); /* Semi-transparent overlay */
    }
    
    /* Make the popup visible */
    body:not(.et-fb) .dl-popup-wrapper.popup-is-visible {
      opacity: 1;
      visibility: visible;
    }
    
    /* Allow content inside the popup wrapper to scroll */
    .dl-popup-inside {
      height: 100%;
      overflow-y: auto;
    }
    
    /* Prevent body from scrolling when the popup is visible */
    body.dl-noscroll {
      overflow: hidden;
    }
    
    /* Center Align Popup Content */
    .dl-popup-content {
      display: flex;
      flex-direction: column;
      justify-content: center;
      background: white; /* Popup background color */
      border-radius: 8px;
      max-width: 80%;
      margin: 0 auto;
      padding: 20px;
      position: relative;
      z-index: 99999;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    }
    
    /* Row inside popup (adjusting margins) */
    .dl-popup-content .et_pb_row {
      margin-top: 0;
      margin-bottom: 0;
    }
    
    /* Close button inside the popup */
    .dl-popup-close {
      cursor: pointer;
      position: absolute;
      top: 10px;
      right: 10px;
      font-size: 24px;
      color: #333;
      background: none;
      border: none;
    }
    
    /* Adjust the position of the popup overlay for the admin bar (if any) */
    @media (min-width: 600px) and (max-width: 782px) {
      body:not(.et-fb).admin-bar .dl-popup-wrapper {
        top: 46px;
      }
    }
    @media (min-width: 783px) {
      body:not(.et-fb).admin-bar .dl-popup-wrapper {
        top: 32px;
      }
    }
    
    /* Scale animation for the popup when it appears */
    .dl-popup-wrapper.popup-is-visible .et_pb_row:not(.dl-popup-close) {
      animation: scale-in 0.5s cubic-bezier(.14, .06, .41, 1.39) both;
      animation-delay: 0.5s;
    }
    
    @keyframes scale-in {
      0% {
        transform: scale(0.3);
        opacity: 0;
      }
      100% {
        transform: scale(1);
        opacity: 1;
      }
    }
    
    /* Hand cursor for close trigger element */
    .dl-popup-close {
      cursor: pointer;
    }
    
    /* Prevent scrolling of the body when the popup is visible */
    body.dl-noscroll {
      overflow: hidden;
    }
    
    /* Click outside detection for closing the popup */
    .dl-popup-wrapper {
      position: fixed;
      z-index: 999;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      background: rgba(0, 0, 0, 0.5); /* Overlay background */
    }
    
    /* Make popup content scrollable */
    .dl-popup-inside {
      max-width: 800px;
      max-height: 90%;
      overflow-y: auto;
    }
    
    /* Make popup content responsive */
    @media (max-width: 768px) {
      .dl-popup-content {
        max-width: 95%;
        padding: 15px;
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <a href="#contact" class="dl-popup-trigger">Click here</a>
    
    <div id="contact" class="et_pb_section et_pb_section_0 dl-popup-content et_section_regular">
      <div class="et_pb_row et_pb_row_0">
        <div class="et_pb_column et_pb_column_4_4 et_pb_column_0 et_pb_css_mix_blend_mode_passthrough et-last-child">
          <div class="et_pb_module et_pb_icon et_pb_icon_0 dl-popup-close">
            <span class="et_pb_icon_wrap"><span class="et-pb-icon"></span></span>
          </div>
          <div class="et_pb_module et_pb_text et_pb_text_0 et_pb_text_align_left et_pb_bg_layout_light">
            <div class="et_pb_text_inner">
              <h4 class="center red">Popup Content</h4>
            </div>
          </div>
        </div>
      </div>
    </div>