Jump to content

Sticky sidebar is stuttering sometimes. Cant figure out why?


Maxxius

Recommended Posts

Posted

hi,

I'm using this script which makes the sidebar to become sticky. Its very nice to have but on some pages the stuttering happens as you scroll down. I can't seem to resolve what causes it. This happens on firefox and chrome browsers.

You can experience this stuttering here: https://ggames.com.br/downloads/

And it is not because of ads, if I remove them completely the other last block then starts twitching.

This is the script I used to make that sidebar:

Template > Core > Front > Global > Sidebar

{{$adsForceSidebar = ( \IPS\Settings::i()->ads_force_sidebar AND \IPS\core\Advertisement::loadByLocation( 'ad_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() ) || $adsForceSidebar )}}
	<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() && !$adsForceSidebar}}ipsLayout_sidebarUnused{{endif}}' data-controller='core.front.widgets.sidebar'>
		{{if $announcements = \IPS\core\Announcements\Announcement::loadAllByLocation( 'sidebar' ) AND ( ( isset( \IPS\Output::i()->sidebar['contextual'] ) && trim( \IPS\Output::i()->sidebar['contextual'] ) !== '' ) OR ( isset( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) && \count( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) ) )}}
			{template="announcementSidebar" group="global" app="core" params="$announcements"}
		{{endif}}
		<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 $adsForceSidebar OR ( \IPS\core\Advertisement::loadByLocation( 'ad_sidebar' ) AND ( ( isset( \IPS\Output::i()->sidebar['contextual'] ) && trim( \IPS\Output::i()->sidebar['contextual'] ) !== '' ) OR ( isset( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) && \count( \IPS\Output::i()->sidebar['widgets']['sidebar'] ) ) ) )}}
			<div data-role='sidebarAd'>
				{advertisement="ad_sidebar"}
			</div>
			<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>

and this CSS>Core>Front>Custom>custom.css

#ipsLayout_mainArea {height: auto;}
.startSticky {position: fixed; z-index: 101;}
.stopSticky {position: relative; z-index: 101;}

 

Posted

@opentype, native sticky function works weird. It sticks the sidebar until scrolling of the main window is done. It should work vise versa. Scroll everything and stick when the end of parent element is reached. I have never get an answer if this is bug or works as desired. 

Posted

Have you tried removing those sidebar ads and checking it? I removed the first ad where it had an issue to begin with and it scrolled past until I got to the second one.

Also, like opentype stated, try the sticky function, Edge will no longer be after Wednesday, the new browser is released using chromium so the sticky feature should be ok to use in all 3 browsers after that.

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...