Javascript 使用jQuery和CSS3';s TranslateX()在将父元素滚动到视图中时显示元素

Javascript 使用jQuery和CSS3';s TranslateX()在将父元素滚动到视图中时显示元素,javascript,jquery,css,scroll,transform,Javascript,Jquery,Css,Scroll,Transform,当一个圆的父部分滚动到视图中时,我想改变它的位置 当父对象在视图中后向下滚动时,它应该向右移动,当向上滚动时,它应该移回原来的位置。(-200px向左)只有在用户主动滚动时才能移动它 如果用户一直向下滚动到圆圈父部分的最底部,或者如果用户已经向下滚动到底部并重新加载页面,则圆圈应显示在其完全显示的位置 我当前的代码部分工作正常,但我很难根据父元素的可视程度来显示整个元素,也很难在滚动到最底部后重新加载页面时将其显示在最终位置 JSFiddle: var$window=$(window), $s

当一个圆的父部分滚动到视图中时,我想改变它的位置

当父对象在视图中后向下滚动时,它应该向右移动,当向上滚动时,它应该移回原来的位置。(-200px向左)只有在用户主动滚动时才能移动它

如果用户一直向下滚动到圆圈父部分的最底部,或者如果用户已经向下滚动到底部并重新加载页面,则圆圈应显示在其完全显示的位置

我当前的代码部分工作正常,但我很难根据父元素的可视程度来显示整个元素,也很难在滚动到最底部后重新加载页面时将其显示在最终位置

JSFiddle:

var$window=$(window),
$sectionFour=$('.sectionFour'),
$circle=$sectionFour.find('.circle'),
lastScrollTop=0,
位置=-200;
函数revealCircle(){
var是可见的,
st=$window.scrollTop();
isVisible=isInView($Section4);
如果(可见){
//log('第四部分在视图中,所以让我们做一些事情!');
如果(st>lastScrollTop){
如果(位置===0){
返回错误
}
$circle.css('transform','translateX('+position+'px'))
位置++;
}否则{
如果(位置==-200){
返回错误
}
$circle.css('transform','translateX('+position+'px'))
位置--;
}
}
}
函数isInView(节点){
var-rect;
if(jQuery的typeof=='function'&&node instanceof jQuery){
节点=节点[0];
}
rect=node.getBoundingClientRect();
返回(
(矩形高度>0 | |矩形宽度>0)&&
rect.bottom>=0&&
rect.right>=0&&

rect.top您的代码可以简化一点。当页面滚动时,您需要跟踪的唯一值是
scrollTop()
。因为
$sectionFour
的几何结构从未改变,所以您可以立即缓存它的
getBoundingClientRect()

一旦你知道
$sectionFour
在视图中,你想计算出它的总高度有多少像素在视图中,将其转换成一个百分比,然后将该百分比应用到-200的初始位置。基本上,当只有几个像素显示时,这是一个小百分比,例如10%和-200变为-180。当在完全可见的情况下,百分比应接近100%,-200变为0。这意味着您没有跟踪上一个位置或滚动的方向,您只是根据当前视口(scrollTop)计算该值

var$window=$(window),
$sectionFour=$('.sectionFour'),
$circle=$sectionFour.find('.circle');
rect=$sectionFour[0]。getBoundingClientRect();
函数revealCircle(){
var scrollTop=$window.scrollTop();
var windowHeight=$window[0]。innerHeight;
如果(滚动顶部+窗口高度>矩形顶部){
var percentVisible=(scrollTop-(rect.top-windowHeight))/rect.height;
var位置=200-(可见百分比*200);
$circle.css('transform','translateX(-'+position+'px');
}
}
$window.on('scroll',revalcircle);
body{margin:0;}
.圆圈{
宽度:400px;
高度:400px;
背景:#fff;
-webkit边界半径:200px;
-moz边界半径:200px;
边界半径:200px;
转换:translateX(-200px);}
.科{
最小高度:400px;}
.第一节{
背景色:红色;}
.第二节{
背景色:橙色;}
.第三节{
背景色:黄色;}
.第四节{
背景色:绿色;}

对于纯JS解决方案,使用css变量可能更简单:

const sectFour=document.querySelector(“#section four”)
,divCircle=sectFour.querySelector(“.circle”)
函数可见百分比(elm)
{
设rect=elm.getBoundingClientRect()
,viewHeight=Math.max(document.documentElement.clientHeight,window.innerHeight)
,visu=viewHeight-rect.top
返回(visu=0)=>checkVisible
}
window.onscroll=\u=>
{
设circlePos=可见百分比(第四节)*2
如果(圈数>=0)
{
divCircle.style.setProperty('--circle pos',`-${200 circlePos}px`)
//IE 11://divCircle.style=('transform:translateX(-'+(200圈)+'px'))
}
}
*{margin:0}
.圆圈{
--圆圈位置:-200px;
宽度:400px;
高度:400px;
背景色:#fff;
-webkit边界半径:200px;
-moz边界半径:200px;
边界半径:200px;
变换:translateX(var(--circle pos));
/*IE 11…………:translateX(-200px)*/
}
截面{最小高度:400px;}
第n节类型(1){背景色:红色;}
第n节(2){背景色:橙色;}
第n节类型(3){背景色:黄色;}
节:第n个类型(4){背景色:绿色;}

您应该看看,这是为解决类似您的问题而设计的。侦听滚动事件并计算位置可能会导致性能下降

首先,您必须定义IO的选项:

let options = {
  root: document.querySelectorAll('.section-four'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);
在定义了选项之后,您必须告诉观察者要观察哪些元素,我想在您的情况下,这将是
。第四节

let targets = document.querySelectorAll('.section-four');
targets.forEach(target => {
  observer.observe(target) } 
)
最后一步是定义应该执行一次的回调函数。
。第四节将进入视图:

let callback = (entries, observer) => { 
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element
    // here you can do something like $(entry.target).find('circle') to get your circle
  });
};
看一看,根据元素的可视程度,背景颜色会发生变化。我认为这与你的问题很接近,你只是不改变背景颜色,而是在元素内设置圆的动画

网站上还有另一个演示,显示元素的多少