jQuery position().top 的行为与固定父级中的 offset().top 相同



我试图制作一个位置感知滚动条,该滚动条使用固定div的最大值而不是窗口。

jQuery 文档对 .position(( 函数的描述如下:

.position(( 方法允许我们检索元素(特别是其边距框(相对于偏移父元素的当前位置

.offset(( 方法描述如下

获取第一个元素的当前坐标,或设置匹配元素集中每个元素相对于文档的坐标。

我在这里收集的是,.position()应该是相对于父级的,而offset()总是相对于文档的。

我试图使我的菜单按钮相对于固定div 中的当前滚动位置而不是窗口突出显示。但是,我从.position().top那里得到的东西似乎永远与固定div的.scrollTop()

这是我的问题的小提琴。如果我将事情切换到相对于窗口工作,一切都很好。

第二次我尝试使其相对于父div,然后它就会变得混乱。

https://jsfiddle.net/cs83083/0kb5tm41/6/

对于小提琴对手,这是代码!

任何见解都值得赞赏!

.HTML

<div class="wrapper">
<div class="menu-left">
<div class="menu-item" data-target="sec1">
Section 1
</div>
<div class="menu-item" data-target="sec2">
Section 2
</div>
<div class="menu-item" data-target="sec3">
Section 3
</div>
<div class="menu-item" data-target="sec4">
Section 4
</div>
</div>
<div class="page-content">
<h2 class="header" id="sec1">Section 1</h2>
<div class="text-block">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut 
enim ad minim veniam, quis nostrud exercitation ullamco laboris 
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
</div>
<h2 class="header" id="sec2">Section 2</h2>
<div class="text-block">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut 
enim ad minim veniam, quis nostrud exercitation ullamco laboris 
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
</div>
<h2 class="header" id="sec3">Section 3</h2>
<div class="text-block">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut 
enim ad minim veniam, quis nostrud exercitation ullamco laboris 
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
</div>
<h2 class="header" id="sec4">Section 4</h2>
<div class="text-block">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut 
enim ad minim veniam, quis nostrud exercitation ullamco laboris 
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
</div>
</div>
</div>

.CSS

html,
body {
margin: 0;
padding: 0;
height: 100%;
}
.wrapper {
padding-left: 240px;
display: block;
}
.menu-left {
background-color: #CCC !important;
height: 100%;
display: block;
width: 240px;
margin-left: -240px;
position: fixed;
z-index: 1000;
}
.page-content {
background-color: #666;
height: 100%;
width: 100%;
position: fixed;
padding: 10px;
overflow: scroll;
}
.menu-item {
border-bottom: 1px solid #000;
padding: 10px;
}
.menu-item:first-child {
border-top: 1px solid #000;
}
.text-block {
border: 1px solid #000;
width: 600px;
display: block;
padding: 10px;
}
.menu-item:hover,
.active {
background: #666;
color: #fff;
}

JavaScript

container = $(".page-content");
$(".menu-item").click(function(e) {
data_target = $(e.target).attr("data-target");
container.animate({
scrollTop: $("#" + data_target).offset().top - container.offset().top + container.scrollTop()
}, 2000);
});
$('.menu-item').on('click', function(event) {
$('.menu-item').removeClass('active');
$(this).addClass('active');
});
container.on('scroll', function() {
//$(window).on('scroll', function() {
$('.header').each(function() {
if(container.scrollTop()  >= $(this).offset().top) {
//if(container.scrollTop()  >= $(this).position().top) {
//if ($(window).scrollTop() >= $(this).offset().top) {
var id = $(this).attr('id');
$('.menu-item').removeClass('active');
$('div[data-target=' + id + ']').addClass('active');
}
});
});

看起来你最大的问题是你在 .on('scroll'( 中获取标头的偏移量以及容器 scrollTop((。这意味着每次滚动时它们都会"刷新"。您需要在加载文档时存储初始偏移,然后运行滚动。

此外,由于您已经根据scrollTop设置了addClass/removeClass,因此在"单击"时无需再次添加它。这可能就是你行为不稳定的原因。

这是我起草的笔

var headerIds = [];
var headerOffset = [];
$('.header').each(function(){
headerIds.push(this.id)
headerOffset.push($(this).offset().top)
})
$(".menu-item").click(function(e) {
data_target = $(e.target).attr("data-target");
container.animate({
scrollTop: $("#" + data_target).offset().top - container.offset().top + container.scrollTop() 
}, 2000);
});
$(container).on("scroll", function(e) {
headerIds.forEach(function(el, i){
if ($(container).scrollTop() > (headerOffset[i]-20)) {
$('.menu-item').removeClass('active');
$('.menu-item:nth-of-type(' + (i + 1) + ')').addClass('active');
var id = $(this).attr('id');
}
});
});

相关内容

最新更新