I need a strictly jQuery solution for this problem. This is because I'm using Wordpress and the sidebar widget that I want to make sticky is inside an <aside>
element which I cannot make full height.
In the same way that .scrollTop()
detects how far down the page I am to make the sidebar widget sticky I need JS detect how far up I am from the bottom of the page to "unstick" the widget via assigning a new fixed position.
I tried to to this with .offset()
but I have been unable to make it work so far.
function stopDiv() {
var distance = $('.footer').offset().top - $('.widget').offset().top;
if (distance < 10) {
$('.widget').css({
'top': 'auto',
'bottom': '10px'
});
}
}
As you can see in the snippet below my sidebar scrolls as it should, but I want the sidebar to assume a new fixed position when I reach <10px distance from the footer.
I want the sidebar to assume a new fixed position above the footer until the user scrolls back up.
Edit: The solution suggested below by @Benvc works fine in the snippet, but not on my wordpress site. Here are the console errors I'm getting:
scripts.js:18 Uncaught ReferenceError: s is not defined
at HTMLDocument.<anonymous> (scripts.js:18)
at i (jquery.js:2)
at Object.fireWith [as resolveWith] (jquery.js:2)
at Function.ready (jquery.js:2)
at HTMLDocument.K (jquery.js:2)
at HTMLDocument.s (VM11874 rocket-loader.min.js:1)
at p (VM11874 rocket-loader.min.js:1)
at t.simulateStateAfterDeferScriptsActivation (VM11874 rocket-loader.min.js:1)
at Object.callback (VM11874 rocket-loader.min.js:1)
at t.run (VM11874 rocket-loader.min.js:1)
// Fixed Widget
function fixDiv() {
var $cache = $('.widget');
if ($(window).scrollTop() > 380)
$cache.css({
'position': 'fixed',
'top': '10px',
'right': '30px'
});
else
$cache.css({
'position': 'relative',
'top': 'auto',
'right': 'auto'
});
}
$(window).scroll(fixDiv);
fixDiv();
/* My attempt
function stopDiv() {
var distance = $('.footer').offset().top - $('.widget').offset().top;
if (distance < 10) {
$('.widget').css({
'top': 'auto',
'bottom': '10px'
});
}
}
$(window).scroll(stopDiv);
stopDiv();
*/
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
* {
font-family: 'Open Sans';
color: #fff;
box-sizing: content-box;
}
body {
padding: 0;
margin: 0;
}
p {
margin: 20px;
}
hr {
width: 85%;
border-style: solid;
}
.main-content {
width: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 150px auto;
grid-template-areas: "nav nav nav nav" "main main main sidebar";
grid-column-gap: 20px;
grid-row-gap: 0px;
}
.nav {
grid-area: nav;
background-color: #266392;
display: grid;
grid-template-columns: 1fr 3fr 1fr;
}
.nav h1 {
place-self: center;
font-weight: 400;
font-size: 40px;
grid-column: 2;
}
.nav i {
align-self: center;
font-size: 40px;
}
.main {
height: 1500px;
width: 98%;
justify-self: start;
grid-area: main;
padding: 10px;
float: left;
background-color: #e8624c;
margin: 10px;
}
.sidebar-container {
height: 900px;
width: 300px;
justify-self: start;
background-color: #209B66;
grid-area: sidebar;
grid-column: 4;
top: 10px;
margin: 10px;
padding: 20px;
display: grid;
grid-template-rows: auto;
grid-row-gap: 10px;
}
.sidebar-container>p {
display: grid;
align-items: start;
padding: 0;
margin: 0;
}
.widget {
height: 500px;
width: 300px;
background-color: #E3962F;
}
.footer {
background-color: #333;
height: 800px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="main-content">
<div class="nav">
<h1>Sticky Sidebar Problem</h1>
<i class="fa fa-arrow-down" aria-hidden="true"></i>
</div>
<div class="main">
<p>
[Main Content]
</p>
</div>
<div class="sidebar-container">
<p>[Sidebar Container]</p>
<div class="widget">
<p> [Widget]</p>
</div>
</div>
</div>
<div class="footer"></div>
</body>
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…