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>
// обработчик "прилипания" контента в правой колонке
(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>
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:
If you liked it, press the likes))