我需要一个严格的jQuery解决方案来解决这个问题。这是因为我使用的是Wordpress,而要粘贴的侧边栏小部件位于<aside>
元素内,因此无法达到全高。
与.scrollTop()
检测到我要使页面侧边小部件变粘的页面向下的方式相同,我需要JS检测我从页面底部到通过分配来“取消粘帖”该窗口小部件的距离一个新的固定职位。
我尝试使用.offset()
来做到这一点,但是到目前为止,我仍然无法使其工作。
function stopDiv() {
var distance = $('.footer').offset().top - $('.widget').offset().top;
if (distance < 10) {
$('.widget').css({
'top': 'auto',
'bottom': '10px'
});
}
}
正如您在侧边栏下方的代码段中所看到的那样,滚动条应该会滚动,但是当我距页脚<10px距离时,我希望侧边栏处于新的固定位置。
我希望边栏在页脚上方占据一个新的固定位置,直到用户向上滚动为止。
编辑:@Benvc所建议的以下解决方案在代码段中运行正常,但在我的wordpress网站上却不行。这是我遇到的控制台错误:
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>
答案 0 :(得分:1)
我们可以将其分解为2个不同的问题。问题1,您需要元素的底部Y弦(a),问题2,您需要页面的底部Y(b)。如果您有这些数据,那么答案就是(b-a)。
为帮助我们,让我们这样创建一个辅助函数:
function getOffset(el) {
const rect = el.getBoundingClientRect();
return {
left: rect.left + window.scrollX,
right: rect.left - window.scrollX,
top: rect.top + window.scrollY,
bottom: rect.bottom -window.scrollY
};
}
使用它,它应该像getOffset(document.body).bottom - getOffset(yourElement).bottom
一样简单。
希望这会有所帮助!
(请注意,我现在无法实际测试此代码,因此它可能开箱即用,因此请更多地用作指导,而不是复制/粘贴)。
答案 1 :(得分:1)
编辑-jQuery解决方案(以下仅原始CSS回答):
根据您的问题编辑提供了更多的约束,并使html / css唯一的解决方案变得更加困难,下面是一个jquery解决方案,其中将您的代码与新的jquery一起用于粘性侧边栏小部件,而css则使侧边栏小部件{{ 1}}和position: absolute
(该值是任意值,具体取决于您希望小部件位于边栏中的确切位置)。另外,请注释掉其他几行css行,这些行可能什么都不做,或干扰了网格布局的响应能力(粘性侧边栏功能可以更改或不更改,尽管您可能需要调整right: 30px
css您的小部件元素(包括媒体查询),具体取决于最终布局的位置。
right
$(function() {
const sidebar = $('.sidebar-container');
const widget = $('.widget');
const footer = $('.footer');
const space = 10; // arbitrary value to create space between the window and widget
const startTop = sidebar.offset().top + 60; // arbitrary start top position
const endTop = footer.offset().top - widget.height() - space;
widget.css('top', startTop);
$(window).scroll(function() {
let windowTop = $(this).scrollTop();
let widgetTop = widget.offset().top;
let newTop = startTop;
if (widgetTop >= startTop && widgetTop <= endTop) {
if (windowTop > startTop - space && windowTop < endTop - space) {
newTop = windowTop + space;
} else if (windowTop > endTop - space) {
newTop = endTop;
}
widget.stop().animate({
'top': newTop
});
}
});
});
@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: end;
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;
position: absolute;
right: 30px;
}
.footer {
background-color: #333;
height: 800px;
}
原始-CSS解决方案:
根据对页脚和浏览器兼容性的要求,无需任何javascript / jquery即可获得所需的效果。您将需要对html进行细微调整,将页脚移到网格外并单独设置样式(在下面的示例中,我仅添加了高度)。然后,您可以将<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>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
和position: sticky
添加到top: 10px
CSS中。
结果是,在滚动标题后,侧边栏开始滚动,然后在碰到页脚时停止滚动。
请注意,IE中不支持.sidebar
(存在polyfill for sticky)。
请参见下面的代码片段,并对代码进行示例调整:
position: sticky
body {
padding: 0;
margin: 0;
}
.main-content {
width: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 80px auto 400px;
grid-template-areas: "nav nav nav nav" "main main main sidebar" "footer footer footer footer";
grid-column-gap: 20px;
grid-row-gap: 10px;
height: 100%;
}
.nav {
grid-area: nav;
background-color: #007ccc;
}
.main {
height: 100%;
max-width: 600px;
justify-self: start;
grid-area: main;
padding: 10px;
float: left;
}
.sidebar {
height: 600px;
width: 300px;
justify-self: start;
background-color: #4BA25E;
grid-area: sidebar;
grid-column: 4;
margin: 10px;
position: sticky;
top: 10px;
}
.footer {
background-color: #333;
height: 400px;
}