Фиксация прокрутки страницы при открытии модального окна в Oxygen

На данный момент базовый элемент "Модал" в Oxygen не имеет опции для блокирования прокрутки страницы при открытии всплывающего окна. Но многие пользователи просят эту функцию.  Кроме этого, при размещении в лайтбоксе контента, превышающего высоту экрана пользователя, модальное окно невозможно прокрутить.

Неизвестно, когда это будет доработано, а пока я предлагаю воспользоваться моим скриптом (смотрите пример).

Основные особенности:

  • Блокировка прокрутки страницы после открытия модального окна;
  • устранение проблемы, когда высота модала превышает высоту экрана (вертикальное переполнение);
  • возможность размещения модала в любой позиции экрана исключая баг с переполнением;
  • устранён рывок при удалении полосы прокрутки путём добавления отступа справа;
  • при позиционировании модала учтена высота админбара для авторизованного пользователя;
  • небольшая доработка для корректного отображения модалов в редакторе;
  • устранение горизонтального переполнения при использовании эффектов анимации с появлением справа.

Для использования вам потребуется скопировать данный код и вставить его в секцию javascript каждого модального окна. Здесь нет опций для изменения, поэтому в целях оптимизации вы можете использовать минифицированную версию скрипта.

/*jQuery Watch Plugin
@author Darcy Clarke
@version 2.0
Copyright (c) 2012 Darcy Clarke
Dual licensed under the MIT and GPL licenses.*/
(function(e){e.fn.watch=function(t,n,r){var i=document.createElement("div");var s=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;var o=window.CustomEvent||function(){return arguments||{}};var u=function(e,t){e="on"+e;var n=e in t;if(!n){t.setAttribute(e,"return;");n=typeof t[e]=="function"}return n};if(typeof n=="function"){r=n;n={}}if(typeof r!="function")r=function(){};n=e.extend({},{throttle:10},n);var a=function(t){var n=this;e.each(this.watching,function(){var e=this;var r=false;var i;for(var s=0;s<e.props.length;s++){i=t[0].attributes[e.props[s]]||t.css(e.props[s]);if(e.vals[s]!=i){e.vals[s]=i;r=true;break}}if(r&&e.callback)e.callback.call(n,new o("AttrChange"))})};return this.each(function(){var o=this;var f=e(this);var l={props:t.split(" "),vals:[],changed:[],callback:r};e.each(l.props,function(e){l.vals[e]=f[0].attributes[l.props[e]]||f.css(l.props[e]);l.changed[e]=false});if(!this.watching)this.watching=[];this.watching.push(l);if(s){var c=new s(function(e){e.forEach(function(e){r.call(o,e)})});c.observe(this,{subtree:false,attributes:true})}else if(u("DOMAttrModified",i)){f.on("DOMAttrModified",r)}else if(u("propertychange",i)){f.on("propertychange",r)}else{setInterval(function(){a.call(o,f)},n.throttle)}})}})(jQuery);

jQuery(document).ready(function($) {

    $('.oxygen-builder-body .oxy-modal-backdrop').css('height','auto');
  
    if($('html').attr('ng-app') == 'CTFrontendBuilder') return;
  
    function scrollbarWidth(){var block = $('<div>').css({'height':'50px','width':'50px'}),indicator = $('<div>').css({'height':'200px'});$('body').append(block.append(indicator));var w1 = $('div',block).innerWidth();block.css('overflow-y','scroll');var w2 = $('div', block).innerWidth();$(block).remove();return (w1 - w2);}
  
    var bg = $('#%%ELEMENT_ID%%').parent('.oxy-modal-backdrop'),
	backsize = $(bg).height();
 
    function fixflex () {
    	var backpos = $(bg).css('align-items'),
	   screenh = $(window).height(),
	   barh = $('#wpadminbar').height();
        $(bg).css({'height':'calc(100% - '+barh+'px)','top':+barh+'px'});
    	if(backsize > screenh) {
           if($(bg).hasClass('right')) {
                $(bg).css('align-items','flex-end');
                $(bg).css('justify-content','flex-start');
           } else if($(bg).hasClass('left')) {
           	$(bg).css('justify-content','flex-start');
           } else {
           	$(bg).css('align-items','flex-start');
           }
    	} else {
            if($(bg).hasClass('right')) {		
                $(bg).css('justify-content','center');
           } else if($(bg).hasClass('left')) {
           	$(bg).css('justify-content','center');
           } else {
           	$(bg).css('align-items',backpos);
           }
        }
    }

    $(window).resize(function(event) {
    	fixflex();
    });
    fixflex();
  
    if(typeof $().watch == 'function') {
	$(bg).watch('display', function() {
            if($(this).css('display')=='flex') {
	        $('body').css({'overflow-y':'hidden', 'height':'100%', 'position':'relative', 'margin-right':scrollbarWidth()+'px'});
                $(this).css('overflow-y','auto');
                if($('#%%ELEMENT_ID%%[data-aos*="left"]')) {
                    $(bg).css('overflow-x','hidden');
                }
	     } else if($(this).css('display')=='none') {
                $('.oxy-modal-backdrop').removeClass("live");
		setTimeout(function() {
		    $('body').css({'overflow-y':'auto','margin-right':'0'});
		}, 300);
	     }
        });
    }

});
Фиксация прокрутки страницы при открытии модального окна в Oxygen Builder

Демо-пример

Рекомендуется проверить на различных разрешениях экрана и разных браузерах, а также на мобильных устройствах.
С большим контентом и прокруткой
Если у вас есть вопросы или пожелания, то напишите комментарий ниже
Если-же вам требуется персональная помощь, персональная доработка скрипта, или консультация, то свяжитесь со мной через форму обратной связи.
Следите за выходом новых советов и уроков:
crossarrow-up