Lottie视口触发时调用jQuery自定义isOnScreen方法报not a function如何解决
报错原因
- jQuery别名不匹配:你自定义方法时挂载到了
$.fn上,但业务代码调用时使用的是jQuery(...)。如果项目开启了jQuery.noConflict()来避免和其他JS库冲突,$就不会指向jQuery对象,自定义方法实际没有挂载到jQuery的原型链上,调用时就会报“不是函数”的错误。 - 代码加载顺序错误:存在以下任意一种加载顺序问题都会导致方法注册失败:jQuery库在自定义
isOnScreen方法之后才加载、自定义方法的代码在业务调用代码之后才执行。 - 缺少边界判断:原自定义方法没有判断目标元素是否存在,若
jQuery('#circle-anim')匹配不到页面元素,调用offset()会返回undefined,读取属性时也会引发连锁报错。
另外你的业务代码中还存在冗余逻辑:lottie.loadAnimation(circle)是多余代码,circle本身已经是加载完成的Lottie实例,不需要二次传入加载,重复执行还会引发额外报错。同时滚动事件触发频率极高,每次触发只要元素在视口就会重复初始化Lottie动画,会造成性能浪费。
修复方案
- 统一jQuery别名,补全边界判断
将自定义方法的代码包裹在自执行函数中,确保$指向jQuery,同时补全元素存在性判断,避免边界报错:
(function($){ $.fn.isOnScreen = function(){ // 元素不存在直接返回false if(!this.length) return false; var win = $(window); var viewport = { top : win.scrollTop(), left : win.scrollLeft() }; viewport.right = viewport.left + win.width(); viewport.bottom = viewport.top + win.height(); var bounds = this.offset(); bounds.right = bounds.left + this.outerWidth(); bounds.bottom = bounds.top + this.outerHeight(); return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom)); }; })(jQuery);
- 调整代码加载顺序
确保代码执行顺序为:先加载jQuery官方库 → 再加载上面的自定义isOnScreen方法代码 → 最后执行业务调用代码。 - 优化业务逻辑,避免重复初始化
增加初始化标记,删除冗余的Lottie加载代码,同时页面加载完成后先执行一次判断,避免元素默认在视口时需要滚动才触发动画:
jQuery(document).ready(function(){ // 标记动画是否已初始化,避免重复加载 let lottieInited = false; // 页面加载完成先判断一次 checkInView(); // 绑定滚动事件 jQuery(window).scroll(checkInView); function checkInView() { if (!lottieInited && jQuery('#circle-anim').isOnScreen()) { var circle = lottie.loadAnimation({ container: document.getElementById("anim-badge-1"), renderer: "svg", loop: true, autoplay: true, path: "PATH TO JSON" // 替换为你的动画JSON文件实际路径 }); circle.playSegments( [ [0, 30], [162, 575] ], true ); // 标记已初始化 lottieInited = true; alert("in viewport!"); } else { console.log('not visible'); } } });
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

