- This topic has 19 replies, 2 voices, and was last updated 3 years, 4 months ago by
David.
-
AuthorPosts
-
November 16, 2022 at 6:50 am #2417989
Dorin
I’m in need of a solution that prevents body scrolling when modals are open on every device, os and web browser. It seems CSS only can’t achieve what I’m after. I stumbled upon this script that does exactly that. Now I tried loading the script via the cdn files using a hook element. My code looks something like this (I targeted the off canvas menu) – but it doesn’t work:
<script src="https://cdnjs.cloudflare.com/ajax/libs/body-scroll-lock/3.1.5/bodyScrollLock.min.js" integrity="sha512-HowizSDbQl7UPEAsPnvJHlQsnBmU2YMrv7KkTBulTLEGz9chfBoWYyZJL+MUO6p/yBuuMO/8jI7O29YRZ2uBlA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/body-scroll-lock/3.1.5/bodyScrollLock.es6.min.js" integrity="sha512-HCiqK+5xnhw9WYQN+BP6yKFr6iZ+euY5CtCVw/q//BLb3X7xsYNYB+/cCWhzE1m39WfDaXnaNZeDa4++lMKHtQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/body-scroll-lock/3.1.5/bodyScrollLock.esm.min.js" integrity="sha512-1D7ifQ1x2RpCxn+WK5i9bAUQ4KlK2BETBSgMOf+clTopmDVxkBBXcUgK7UA5LQ4kcgvqEcxLlnwvVQq1fgIPfw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script> const bodyScrollLock = require('body-scroll-lock'); const disableBodyScroll = bodyScrollLock.disableBodyScroll; const enableBodyScroll = bodyScrollLock.enableBodyScroll; const targetElement = document.querySelector('#generate-slideout-menu'); disableBodyScroll(targetElement); enableBodyScroll(targetElement); </script>I know it’s not a css specific question, but any idea on how to achieve a proper body scroll lock when a modal is open is greatly appreciated. Most of my pages use overlay modals (I’m leaving an example). I’m just trying to enhance the user experience, especially on mobile.
November 16, 2022 at 8:00 am #2418323David
StaffCustomer SupportHi there,
is it just for the Off canvas ? if so – what about this CSS:
.slide-opened body { max-height: 100vh; overflow: hidden; } .slide-opened #generate-slideout-menu { overflow: scroll; }November 16, 2022 at 8:16 am #2418357Dorin
Works well, David. Thanks. Do you think I can make it work for the modals in the page I left privately? That’s my main issue right now.
November 16, 2022 at 8:23 am #2418373David
StaffCustomer SupportOk, its possible but not in its present state.
Where does the modal script come from? As currently it simply changes an inline style to show the modal, and we need it to toggle a class on thebodyor better still thehtmlelement.November 16, 2022 at 8:29 am #2418391Dorin
The script sits below the html in the custom html block on the page. I took the code from this codepen.
November 16, 2022 at 8:41 am #2418410David
StaffCustomer SupportOk, so thats good as you can edit it.
At the top of the script add:var rootHTML = document.getElementsByTagName( 'html' )[0]This will load the
HTMLelement into therootHTMLvariable.Then in your script there are two click events:
modal_btn_multi[i].onclick = function() { var ElementIndex = this.getAttribute('data-index'); modalparent[ElementIndex].style.display = "block"; }; // When the user clicks on <span> (x), close the modal span_close_multi[i].onclick = function() { var ElementIndex = this.getAttribute('data-index'); modalparent[ElementIndex].style.display = "none"; };change them to:
modal_btn_multi[i].onclick = function() { var ElementIndex = this.getAttribute('data-index'); modalparent[ElementIndex].style.display = "block"; rootHTML.classList.add('modal-open'); }; // When the user clicks on <span> (x), close the modal span_close_multi[i].onclick = function() { var ElementIndex = this.getAttribute('data-index'); modalparent[ElementIndex].style.display = "none"; rootHTML.classList.remove('modal-open'); };This should now toggle the
modal-openclass on the HTML Element.And then our CSS becomes:
.slide-opened body, .modal-open body { max-height: 100vh; overflow: hidden; } .slide-opened #generate-slideout-menu, .modal-open .modal { overflow: scroll; }November 16, 2022 at 10:08 am #2418523Dorin
Made all the updates, but now the modals are not opening.
November 17, 2022 at 4:29 am #2419387David
StaffCustomer SupportOK,
reverse the changes to the Javascript.
keep the CSS.
Now add this script to your footer:var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutationRecord) { rootHTML.classList.toggle('modal-open'); }); }); var rootHTML = document.getElementsByTagName( 'html' )[0]; var modals = document.querySelectorAll('.modal'); modals.forEach(modal => { observer.observe(modal, { attributes: true, attributeFilter: ['style'] }); });This should observe any changes to the
modalelements styles and add themodal-openclass to theHTMLnode.November 17, 2022 at 5:31 am #2419464Dorin
Still not working unfortunately. Sorry to bug you with this issue.
November 17, 2022 at 6:45 am #2419561David
StaffCustomer SupportI can see the Class being toggled on the head, so the JS is working.
Did you change the CSS to:.slide-opened body, .modal-open body { max-height: 100vh; overflow: hidden; } .slide-opened #generate-slideout-menu, .modal-open .modal { overflow: scroll; }November 17, 2022 at 6:52 am #2419567Dorin
Yes, that code is in place. It’s working for the offcanvas menu, but not for the rest of the modals.
November 17, 2022 at 7:07 am #2419595David
StaffCustomer SupportYou have this CSS for the tablet:
/* Tablet view */ @media(max-width: 1024px) and (min-width: 769px) { .separate-containers .inside-article, .inside-header, .inside-site-info { padding-left: 20px; padding-right: 20px; } .swiper-button-next, .swiper-button-prev { display: none; } body .main-navigation.offside { width: 50%; }Is missing a closing
}for the @media query.
It should be:/* Tablet view */ @media(max-width: 1024px) and (min-width: 769px) { .separate-containers .inside-article, .inside-header, .inside-site-info { padding-left: 20px; padding-right: 20px; } .swiper-button-next, .swiper-button-prev { display: none; } body .main-navigation.offside { width: 50%; } }Without that, the CSS below it is being included inside that media query
November 17, 2022 at 7:39 am #2419660Dorin
Brilliant stuff, David. It’s working now. Sorry about forgetting to close that piece of code.
The only area where it seems to not work everytime (on some modals it’s working, on others it doesn’t, espcially the last one in the list) is on Safari for mobile. What happens is the vertical scrollbar of the body remains visible sometimes and that triggers the scroll. Any chance to hide the vertical scrollbar of the body?November 17, 2022 at 7:48 am #2419687David
StaffCustomer SupportHmmm… tricky one.
What if we move the ovrflow scroll to themodal-contentin the CSS ie..slide-opened body, .modal-open body { max-height: 100vh; overflow: hidden; } .slide-opened #generate-slideout-menu, .modal-open .modal-content { overflow: scroll; }November 17, 2022 at 8:09 am #2420027Dorin
The same behaviour. Sometimes works, other times the scroll gets activated. Some resources on the web suggest adding
position: fixed;to the body element when the modal is open. Don’t know exactly how to implement it. -
AuthorPosts
- You must be logged in to reply to this topic.