>我在页面上有一个元素的排列 - 通过CMS控制的位置,它为每个元素提供宽度,顶部位置,左侧位置,z索引和"速度"。
速度用于使用 JS 创建视差效果。它取它的"速度"并按window.pageYOffset
计算——如果速度小于 0,则window.pageYOffset
除以速度,如果大于 0,则window.pageYOffset
乘以速度。在滚动时,它会调整 Y 平移以产生这种"视差"效果。
这通常都很好,但是当然,当您在滚动上更改元素的Y位置时,您会在底部留下一个"间隙"(如果滚动速度与用户滚动速度匹配,则元素将位于该间隙)。
为了纠正这一点,我认为我会得到最底部的元素,并得到它getBoundingClientRect().bottom
位置,并在滚动时降低容器的高度以匹配该元素的底部,以便当您向下或向上滚动时,容器会收缩/扩展以匹配,从而消除间隙。
但是,这似乎不起作用。数学/逻辑要么是错误的,要么我错过了整个事情。
下面是我的代码,我已经设置了一个JSFiddle来帮助可视化这一点。
https://jsfiddle.net/6up3vqjn/2/
// Runs on init and resize
function parallaxInit() {
var $container = $('.parallax'),
container = $container[0];
var testArray = [],
$testLastElement;
$('.parallax > .group').each(function() {
var $group = $(this),
group = $group[0],
groupBounds = group.getBoundingClientRect(),
$lastElement,
lastElementBoundsBottom = 0;
$group.find('> div').each(function() {
var $div = $(this),
div = $div[0],
initTop = $div.attr('data-top');
if (initTop == 0) {
$div.css('top', '0');
} else {
$div.css('top', $(window).width() / 12 * initTop - 26 + 'px');
};
group.removeAttribute('style');
$group.height(group.scrollHeight).attr('data-height', group.scrollHeight);
var divBounds = div.getBoundingClientRect();
testArray.push(divBounds.bottom);
});
});
$('.parallax > .group > div').each(function() {
var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;
if (divBottomBounds == Math.max.apply(Math, testArray)) {
$testLastElement = $(this);
$(this).addClass('is--last');
}
var letters = "0123456789ABCDEF";
var color = '#';
for (var i = 0; i < 6; i++) color += letters[(Math.floor(Math.random() * 16))];
$(this).css('background-color', color);
});
$container[0].style.height = $testLastElement[0].getBoundingClientRect().bottom + 'px';
}
parallaxInit();
$(window).on('resize', parallaxInit);
// Runs on scroll
function parallax() {
var $container = $('.parallax');
var test = 0;
var testArray = [],
$testLastElement;
$('.parallax > .group').each(function() {
var $group = $(this),
group = $group[0],
groupHeight = $group.attr('data-height'),
groupBounds = group.getBoundingClientRect();
$group.find('> div').each(function() {
var $this = $(this),
speed = $this.attr('data-speed');
if (speed < 0) {
speed = Math.abs(speed);
var yPos = window.pageYOffset / speed;
} else {
var yPos = window.pageYOffset * speed;
}
yPos = -yPos;
$this[0].style.transform = "translate3d(0, " + yPos + "px, 0)";
var divBounds = $this[0].getBoundingClientRect(),
divRelativeBounds = {};
testArray.push(divBounds.bottom);
});
});
$('.parallax > .group > div').each(function() {
var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;
$(this).removeClass('is--last');
if (divBottomBounds == Math.max.apply(Math, testArray)) {
$testLastElement = $(this);
$(this).addClass('is--last');
}
});
$container[0].style.height = $testLastElement[0].getBoundingClientRect().bottom + 'px';
}
$(window).bind('scroll', parallax);
更新了删除容器高度计算的 JSFiddle:https://jsfiddle.net/ejqhvz2c/
我不是 100% 这正是你所追求的,但我已经停止了过度滚动和滚动到空白。首先,我更改了触发事件的方式。由于它是一个视差,我将其绑定到滚轮事件而不是实际滚动,当页面实际包含内容时,这实际上并不重要。然后我使用了一个名为paralaxYOffset
的全局变量,我决定最好以 +- 50 间隔递增以保持平滑度,并停止过度滚动,我添加了一个检查以查看 y 位置是否.is--last
<= 0,然后不允许视差进一步滚动。
事件变更:
if(e.originalEvent.deltaY > 0){
if($(".is--last")[0].getBoundingClientRect().y > 0){
window.paralaxYOffset += 50;
}
}else{
window.paralaxYOffset -= 50;
}
if(window.paralaxYOffset < 0)
window.paralaxYOffset = 0;
为了确保一切正常并删除溢出滚动条,我.parallax
设置为100vh
和overflow: hidden
我相信这实现了您的要求:)
https://jsfiddle.net/fynmtk9b/4/
我不太确定你在这里想实现什么。但是,如果您想限制容器高度以匹配组div 组件的高度,只需将容器显示设置为内容并从组div 组件中删除所有高度属性,它就可以工作。
<div class="parallax" style="display:contents;">
这是小提琴:https://jsfiddle.net/bf3e82o4/3/
试试这个编辑! 我限制了容器高度以适合所有组件的高度
function parallaxInit() {
var $container = $('.parallax'),
container = $container[0];
var testArray = [],
$testLastElement;
$('.parallax > .group').each(function() {
var $group = $(this),
group = $group[0],
groupBounds = group.getBoundingClientRect(),
$lastElement,
lastElementBoundsBottom = 0;
$group.find('> div').each(function() {
var $div = $(this),
div = $div[0],
initTop = $div.attr('data-top');
if (initTop == 0) {
$div.css('top', '0');
} else {
$div.css('top', $(window).width() / 12 * initTop - 26 + 'px');
};
group.removeAttribute('style');
//$group.height(group.scrollHeight).attr('data-height', group.scrollHeight);
var divBounds = div.getBoundingClientRect();
testArray.push(divBounds.bottom);
});
});
$('.parallax > .group > div').each(function() {
var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;
if (divBottomBounds == Math.max.apply(Math, testArray)) {
$testLastElement = $(this);
$(this).addClass('is--last');
}
var letters = "0123456789ABCDEF";
var color = '#';
for (var i = 0; i < 6; i++) color += letters[(Math.floor(Math.random() * 16))];
$(this).css('background-color', color);
});
}
parallaxInit();
$(window).on('resize', parallaxInit);
function parallax() {
var $container = $('.parallax');
var test = 0;
var testArray = [],
$testLastElement;
$('.parallax > .group').each(function() {
var $group = $(this),
group = $group[0],
groupHeight = $group.attr('data-height'),
groupBounds = group.getBoundingClientRect();
$group.find('> div').each(function() {
var $this = $(this),
speed = $this.attr('data-speed');
if (speed < 0) {
speed = Math.abs(speed);
var yPos = window.pageYOffset / speed;
} else {
var yPos = window.pageYOffset * speed;
}
yPos = -yPos;
$this[0].style.transform = "translate3d(0, " + yPos + "px, 0)";
var divBounds = $this[0].getBoundingClientRect(),
divRelativeBounds = {};
testArray.push(divBounds.bottom);
});
});
$('.parallax > .group > div').each(function() {
var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;
$(this).removeClass('is--last');
if (divBottomBounds == Math.max.apply(Math, testArray)) {
$testLastElement = $(this);
$(this).addClass('is--last');
}
});
}
$(window).bind('scroll', parallax);
.parallax {
position: relative;
overflow: hidden;
z-index: 1;
.group {
position: relative;
> div {
position: absolute;
picture {
display: block;
}
}
}
}
<div class="parallax" style="display:contents;">
<div class="group" data-height="">
<div style="width:50%;left:0%;z-index:1" data-top="1" data-speed="2">
<picture data-ratio data-format="portrait" style="padding-bottom:128.97%;"></picture>
</div>
<div style="width:83.333333333333%;left:8.3333333333333%;z-index:2" data-top="6" data-speed="1">
<picture data-ratio data-format="landscape" style="padding-bottom:93.31%;"></picture>
</div>
<div style="width:33.333333333333%;left:66.666666666667%;z-index:3" data-top="2" data-speed="2.5">
<picture data-ratio data-format="portrait" style="padding-bottom:129.29%;"></picture>
</div>
<div style="width:50%;left:0%;z-index:4" data-top="14" data-speed="2.5">
<picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
</div>
<div style="width:50%;left:50%;z-index:5" data-top="14" data-speed="1">
<picture data-ratio data-format="landscape" style="padding-bottom:69.38%;"></picture>
</div>
</div>
<div class="group" data-height="">
<div style="width:83.333333333333%;left:8.3333333333333%;z-index:1" data-top="1" data-speed="2">
<picture data-ratio data-format="landscape" style="padding-bottom:75%;"></picture>
</div>
<div style="width:50%;left:41.666666666667%;z-index:2" data-top="6" data-speed="2">
<picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
</div>
</div>
<div class="group" data-height="">
<div style="width:33.333333333333%;left:0%;z-index:1" data-top="1" data-speed="3">
<picture data-ratio data-format="portrait" style="padding-bottom:129.66%;"></picture>
</div>
<div style="width:33.333333333333%;left:25%;z-index:2" data-top="5" data-speed="3.5">
<picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
</div>
<div style="width:58.333333333333%;left:16.666666666667%;z-index:3" data-top="5" data-speed="3">
<picture data-ratio data-format="landscape" style="padding-bottom:66.5%;"></picture>
</div>
<div style="width:58.333333333333%;left:16.666666666667%;z-index:4" data-top="13" data-speed="3.6">
<picture data-ratio data-format="landscape" style="padding-bottom:43.3%;"></picture>
</div>
</div>
<div class="group" data-height="">
<div style="width:100%;left:0%;z-index:1" data-top="0" data-speed="3.2">
<picture data-ratio data-format="landscape" style="padding-bottom:74.89%;"> </picture>
</div>
<div style="width:50%;left:0%;z-index:2" data-top="5" data-speed="4">
<picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
</div>
<div style="width:41.666666666667%;left:58.333333333333%;z-index:3" data-top="0" data-speed="3.5">
<picture data-ratio data-format="landscape" style="padding-bottom:75%;"></picture>
</div>
<div style="width:33.333333333333%;left:58.333333333333%;z-index:4" data-top="18" data-speed="4.7">
<picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
</div>
</div>
</div>
希望这有帮助。 你很好!!