基于Remy Sharp的jQuery视口插件偏移触发问题求助
嘿,我明白你遇到的问题了——Remy Sharp的插件本身很好用,但固定偏移量没法适配上下滚动的不同需求,对吧?我帮你调整一下插件逻辑,完美实现你要的效果:
核心思路
关键就是根据滚动方向动态调整触发偏移量:
- 向下滚动时,让元素进入视口200px后再触发淡入,避免提前触发导致效果失效
- 向上滚动时,让元素即将滚出/刚进入视口边缘(提前200px)就触发对应效果,符合你要的“即将滚出时fade-out,进入时fade-in”的反向逻辑
修改后的插件代码
我给原插件加了滚动方向追踪和动态偏移的逻辑:
(function($) { // 追踪滚动方向:down/up var scrollDirection = 'down'; var lastScrollTop = 0; $(window).on('scroll', function() { var currentScrollTop = $(this).scrollTop(); scrollDirection = currentScrollTop > lastScrollTop ? 'down' : 'up'; lastScrollTop = currentScrollTop; }); $.fn.visible = function(partial, hidden, directionOffset) { // 默认偏移200px,可自定义 directionOffset = directionOffset || 200; var $t = $(this), $w = $(window), viewTop = $w.scrollTop(), viewBottom = viewTop + $w.height(), elTop = $t.offset().top, elBottom = elTop + $t.height(); // 根据滚动方向调整元素的触发边界 var adjustedElTop = scrollDirection === 'down' ? elTop + directionOffset : elTop - directionOffset; var adjustedElBottom = scrollDirection === 'down' ? elBottom + directionOffset : elBottom - directionOffset; // 处理隐藏元素的判断逻辑(原插件保留) var isElementVisible = hidden === true ? $t[0].offsetWidth * $t[0].offsetHeight : true; // 判断调整后的元素边界是否在视口内 return !!isElementVisible && ( (adjustedElBottom <= viewBottom && adjustedElBottom >= viewTop) || (adjustedElTop >= viewTop && adjustedElTop <= viewBottom) ); }; })(jQuery);
初始化触发逻辑
接下来是元素的类名切换逻辑,同时支持element1、element2和图片:
$(window).scroll(function() { // 处理element2:进入视口淡入,离开淡出 $('.element2').each(function() { var $el = $(this); if ($el.visible(true, false, 200)) { $el.addClass('fade-in').removeClass('fade-out'); } else { $el.addClass('fade-out').removeClass('fade-in'); } }); // 处理element1:向上滚动进入时淡入,向下滚动即将滚出时淡出 $('.element1').each(function() { var $el = $(this); if ($el.visible(true, false, 200)) { $el.addClass('fade-in').removeClass('fade-out'); } else { $el.addClass('fade-out').removeClass('fade-in'); } }); // 处理图片:进入视口淡入 $('img').each(function() { var $el = $(this); if ($el.visible(true, false, 200)) { $el.addClass('fade-in'); } }); }); // 页面加载时手动触发一次滚动,避免初始在视口的元素无效果 $(window).scroll();
配套CSS样式
别忘了加淡入淡出的过渡效果:
/* 淡入淡出过渡动画 */ .fade-in { opacity: 1; transition: opacity 0.5s ease-in; } .fade-out { opacity: 0; transition: opacity 0.5s ease-out; } /* 初始状态:未进入视口的元素默认隐藏 */ .element2, img { opacity: 0; }
关键说明
- 滚动方向的判断是通过对比当前滚动位置和上一次的滚动位置实现的,简单靠谱
- 偏移量
directionOffset可以自定义,你如果觉得200px不合适,改数字就行 - 原插件的
partial参数设为true,表示元素只要有一部分在视口调整后的边界内就触发,刚好符合你“进入一部分再触发”的需求
内容的提问来源于stack exchange,提问作者HelloWorldGeek
相关产品推荐
相关产品推荐

