第十三天挑战(滑动图片滚入)
所有内容均上传至gitee,答案不唯一,仅代表本人思路
中文详解:github.com/soyaine/Jav...
该详解是Soyaine及其团队 整理编撰的,是对源代码的详解 ,强烈推荐大家观看学习!!!!!!!
本人gitee:gitee.com/thats-all-r...
效果
-
样式分析
- 组件整体居中,文本中插入图片
-
逻辑分析
- 当滚动条划入到图片范围内时,图片从两侧滑入展示
- 当滚动条划出图片范围时,图片滑出
本人代码及思路分析
仅提供布局及逻辑代码
结构:
html
<p>文本内容</p>
<img src="http://unsplash.it/400/401" class="align-right slide-in">
逻辑:
js
//挑战自带函数,用来限制滚动触发频率
function debounce(func, wait = 20, immediate = true) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
//图片展示代码
const img = document.querySelectorAll('img')
function moveActive(){
img.forEach((item,index) => {
if(Math.abs(item.offsetTop - document.documentElement.scrollTop) <= 700 ){
item.classList.add('active')
}else {
item.classList.remove('active')
}
})
}
window.addEventListener('scroll',debounce(moveActive))
分析:
-
整体思路:获取图片元素,监听滑动事件,设定图片显示范围(这里利用的是当滑动距离 - 图片相对于其 offsetParent元素的顶部内边距的距离),根据范围对图片进行展示或隐藏
-
具体实现:
- querySelectorAll获取图片元素用来控制图片
- 通过scrollTop视图顶部到展示窗口的距离,即该页面被滑动的距离
- 通过offsetTop获取img图片内边距距离其父级元素顶部的距离
- 让offsetTop - scrollTop ,并取其绝对值,作为图片展示的范围,即当滑动的距离距离图片所在位置差值为X的时候,图片展示,否则隐藏
- 根据范围展示或隐藏图片
-
弊端分析(与官方方法对比):
- 判断不够精确: 这个条件只考虑了图片顶部与视口顶部的距离,没有考虑图片底部的位置。这可能导致一些情况下判断不够精确,例如图片只是部分进入视口时。
官方代码
官方代码仅代表该案例原作者思路,不唯一
结构
html
<p>文本内容</p>
<img src="http://unsplash.it/400/401" class="align-right slide-in">
逻辑
js
//节流函数
function debounce(func, wait = 20, immediate = true) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
//动效函数
const sliderImages = document.querySelectorAll('.slide-in');
function checkSlide() {
sliderImages.forEach(sliderImage => {
// half way through the image
const slideInAt = (window.scrollY + window.innerHeight) - sliderImage.height / 2;
// bottom of the image
const imageBottom = sliderImage.offsetTop + sliderImage.height;
const isHalfShown = slideInAt > sliderImage.offsetTop;
const isNotScrolledPast = window.scrollY < imageBottom;
if (isHalfShown && isNotScrolledPast) {
sliderImage.classList.add('active');
} else {
sliderImage.classList.remove('active');
}
});
}
window.addEventListener('scroll', debounce(checkSlide));
分析
仅代表本人对该代码的分析
建议直接去看Soyaine的中文详解
- **整体思路:**整体思路与上述保持一致,这里添加了图片底部对于视窗底部的判断,更加完善
- 具体实现:
slideInAt
:该变量确定滚动视口到达的位置,即视口底部减去图片高度的一半。这样计算是为了确保图片至少在视口的一半以上,从而产生视觉上的渐显效果。imageBottom
:这是图片底部距离页面顶部的位置。通过将图片顶部偏移量和图片高度相加,可以得到图片底部的位置。isHalfShown
:这个变量检查滚动视口是否超过了图片的顶部位置。如果滚动视口的位置大于图片顶部位置,那么意味着图片至少被滚动了一半以上。isNotScrolledPast
:这个变量检查当前滚动的位置是否小于图片底部的位置。如果滚动位置小于图片底部位置,说明图片还没有完全滚出视口。
- 优点:
- 性能较好 : 代码使用了节流函数
debounce
,它可以控制滚动事件的触发频率,避免了过多的计算和页面重绘,提高了性能。 - 精确控制: 通过计算图片的位置和窗口滚动的距离,精确地判断图片是否已经滚动到了页面的一半,并且没有滚动超过图片的底部,这样可以确保动画效果只在图片完全进入视口时才触发,避免了不必要的动画播放。
- 灵活性: 代码中使用了变量来保存计算结果,使得后续对滚动条件的调整更加灵活,可以根据实际需要对滚动触发条件进行调整。
- 性能较好 : 代码使用了节流函数