Jump to content

Sticky Sidebar IPS Community


peter_hutomo

Recommended Posts

  • Premium Account

core -> front -> global -> sidebar

All delete and paste this code:

{{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>
 
  // "stick" content handler in the right column
(function(){
	var a = document.querySelector('.ibtFloatSidebar'), b = null, K = null, Z = 0, P = 0, N = 0;  // if P replaces zero with a number, then the block will stick until the top edge of the browser window reaches the top edge of the element, if N - the bottom edge reaches the bottom edge of the element. May be a negative number
	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]);
				}
			}
			// calculate the height of the column
			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)*/) { // check that the column height is greater than the content height
					if (Rb.height > W) {
						if (Ra.top < K) {  // scroll down
							//console.log('scroll down');
							if (R2 + N > R1) {  // не дойти до низа
								//if ((Rb.bottom - W + N < 0) && (Rb.top - P < 0)) {  // pick up
								if ((parseInt(Rb.bottom) - W + N) <= 0/* && (Rb.top + W < 0)*/) {  // pick up
									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 {  // scroll up
							//console.log('scroll up');
							if (Ra.top - P < 0) {  // do not reach the top
								if (Rb.top - P >= 0) {  // pick up
									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 {
					// if the height of the content is less than the height of the column, then we "beat" the column to the top
					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>

In custom.css add

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

Done.

Comments me too lazy to translate and rewrite, sorry.
Everything should work in version 4.1 / 4.2 / 4.3 on any templates (where the sidebar is standard, not redone)

Result:

result.gif.87415c3150f1f3c75803188df28c91a9.gif

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...