Перейти к содержанию
  • Плавающий боковой блок в Invision Community




    Любой плавающий блок в Invision Community 4 очень просто реализовать с помощью виджета ips.ui.sticky, который довольно просто в применении. Это может быть какой-то рекламный блок, двигающийся вместе с прокруткой страницы, или плавающий весь боковой блок. 

    Пример кода реализации с использованием IPS4 Javascript фреймворка:

    <div data-ipsSticky data-ipsSticky-relativeTo='#ipsLayout_sidebar' data-ipsSticky-disableIn='tablet,phone'>
      Плавающий блок
    </div>

     

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

    У такой реализации есть своеобразный нюанс - при прокрутке страницы боковой блок сразу же закрепляется к верху окна браузера, если блок большой, то основная его часть останется недоступна для просмотра, пока пользователь не доскроллит до конца страницы. 

    Безимени-1.gif

     

    Правильней было бы сначала просмотреть весь боковой блок, после чего закрепить его в нижней части окна браузера. Пример:

    Безимени-2.gif

    Для реализации такого вариант необходимо заменить шаблон core -> front -> global -> sidebar на следёющий код:

     

    Спойлер
    
    {{if (isset( \IPS\Output::i()->sidebar['enabled'] ) and \IPS\Output::i()->sidebar['enabled'] ) && ( ( isset( \IPS\Output::i()->sidebar['contextual'] ) && trim( \IPS\Output::i()->sidebar['contextual'] ) !== '' ) || ( isset( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) && count( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) ) || ( \IPS\Dispatcher::i()->application instanceof \IPS\Application AND \IPS\Dispatcher::i()->application->canManageWidgets() ) )}}
    	<div id='ipsLayout_sidebar' class='ipsLayout_sidebar{$position} {{if !( isset( \IPS\Output::i()->sidebar['contextual'] ) && trim( \IPS\Output::i()->sidebar['contextual'] ) !== '' ) && ( !isset( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) || !count( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) ) && \IPS\Dispatcher::i()->application->canManageWidgets()}}ipsLayout_sidebarUnused{{endif}}' data-controller='core.front.widgets.sidebar'>
    		<div class='ibtFloatSidebar'>
          	{{if isset( \IPS\Output::i()->sidebar['contextual'] ) && trim( \IPS\Output::i()->sidebar['contextual'] ) !== ''}}
    			<aside id="elContextualTools" class='ipsClearfix' {{if isset( \IPS\Output::i()->sidebar['sticky'] )}}data-ipsSticky{{endif}}>
    				{expression="\IPS\Output::i()->sidebar['contextual']" raw="true"}
    			</aside>
    		{{endif}}
    		{{if isset(\IPS\Output::i()->sidebar['widgets']['sidebar']) and count( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) and ( \IPS\core\Advertisement::loadByLocation( 'ad_sidebar' ) ) }}
    			{advertisement="ad_sidebar"}
    			<br><br>
    		{{endif}}
    		{template="widgetContainer" group="global" app="core" params="'sidebar', 'vertical'"}
    	</div></div>
    {{endif}}
    
    <script>
     
      // обработчик "прилипания" контента в правой колонке
    (function(){
    	var a = document.querySelector('.ibtFloatSidebar'), b = null, K = null, Z = 0, P = 0, N = 0;  // если у P ноль заменить на число, то блок будет прилипать до того, как верхний край окна браузера дойдёт до верхнего края элемента, если у N — нижний край дойдёт до нижнего края элемента. Может быть отрицательным числом
    	window.addEventListener('scroll', Ascroll, false);
    	document.body.addEventListener('scroll', Ascroll, false);
    	function Ascroll() {
    		(function(jQuery) {
    			var c = document.querySelector('#ipsLayout_mainArea'),
    				Rc = c.getBoundingClientRect(),
    				Ra = a.getBoundingClientRect(),
    				R1bottom = Rc.bottom;
    			if (b == null) {
    				var Sa = getComputedStyle(a, ''), s = '';
    				for (var i = 0; i < Sa.length; i++) {
    					if (Sa[i].indexOf('overflow') == 0 || Sa[i].indexOf('padding') == 0 || Sa[i].indexOf('border') == 0 || Sa[i].indexOf('outline') == 0 || Sa[i].indexOf('box-shadow') == 0 || Sa[i].indexOf('background') == 0) {
    						s += Sa[i] + ': ' +Sa.getPropertyValue(Sa[i]) + '; '
    					}
    				}
    				b = document.createElement('div');
    				b.className = "stopSticky";
    				b.style.cssText = s + ' box-sizing: border-box; width: ' + a.offsetWidth + 'px;';
    				a.insertBefore(b, a.firstChild);
    				var l = a.childNodes.length;
    				for (var i = 1; i < l; i++) {
    					b.appendChild(a.childNodes[1]);
    				}
    			}
    			//просчитываем высоту колонки
    			a.style.height = b.getBoundingClientRect().height + 'px';
    			a.style.padding = '0';
    			a.style.border = '0';
    			var Rb = b.getBoundingClientRect(),
    				Rh = Ra.top + Rb.height,
    				W = document.documentElement.clientHeight,
    				R1 = Math.round(Rh - R1bottom),
    				R2 = Math.round(Rh - W);
    			if (Ra.bottom < R1bottom) {
    				if((Rc.height > Rb.height) /*&& (Rb.height > W)*/) { // проверка того, что высота колонки больше высоты контента
    					if (Rb.height > W) {
    						if (Ra.top < K) {  // скролл вниз
    							//console.log('скролл вниз');
    							if (R2 + N > R1) {  // не дойти до низа
    								//if ((Rb.bottom - W + N < 0) && (Rb.top - P < 0)) {  // подцепиться
    								if ((parseInt(Rb.bottom) - W + N) <= 0/* && (Rb.top + W < 0)*/) {  // подцепиться
    									b.className = 'startSticky';
    									b.style.top = W - Rb.height - N + 'px';
    									Z = N + Ra.top + Rb.height - W;
    								} else {
    									b.className = 'stopSticky';
    									b.style.top = -Z + 'px';
    								}
    							} else {
    								b.className = 'stopSticky';
    								b.style.top = -R1 + 'px';
    								Z = R1;
    							}
    						} else {  // скролл вверх
    							//console.log('скролл вверх');
    							if (Ra.top - P < 0) {  // не дойти до верха
    								if (Rb.top - P >= 0) {  // подцепиться
    									b.className = 'startSticky';
    									b.style.top = P + 'px';
    									Z = Ra.top - P;
    								} else {
    									b.className = 'stopSticky';
    									b.style.top = -Z + 'px';
    								}
    							} else {
    								b.className = '';
    								b.style.top = '';
    								Z = 0;
    							}
    						}
    						K = Ra.top;
    					} else {
    						if ((Ra.top - P) <= 0) {
    							if ((Ra.top - P) <= R1) {
    								b.className = 'stopSticky';
    								b.style.top = -R1 + 'px';
    							} else {
    								b.className = 'startSticky';
    								b.style.top = P + 'px';
    							}
    						} else {
    							b.className = '';
    							b.style.top = '';
    						}
    					}
    				} else {
    					// если высота контента меньше высоты колонки, то "прибиваем" колонку к верху
    					Z = 0;
    					b.className = 'stopSticky';
    					b.style.top = Z + 'px';
    				}
    				window.addEventListener('resize', function() {
    					a.children[0].style.width = getComputedStyle(a, '').width
    				}, false);
    			}
    		})(jQuery)
    	}
    
    })()
    </script>

     

    В custom.css добавим:

    Спойлер
    
    /**
     * This file is for your custom CSS.
     * This file is not modified or overwritten during upgrades
     * InvisionByte.ru
     */
    #ipsLayout_mainArea {height: auto;}
    .startSticky {position: fixed; z-index: 101;}
    .stopSticky {position: relative; z-index: 101;}

     





    Обратная связь


    Комментариев нет



    Присоединяйтесь к обсуждению

    Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
    Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

    Гость
    Добавить комментарий...

    ×   Вставлено с форматированием.   Вставить как обычный текст

      Разрешено использовать не более 75 эмодзи.

    ×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

    ×   Ваш предыдущий контент был восстановлен.   Очистить редактор

    ×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

    Загрузка...

×
×
  • Создать...

Важная информация

Используя наш сайт вы соглашаетесь с нашей Политикой конфиденциальности