集成particles.js报Particles is not defined错误粒子效果失效
错误原因与修复方案
Uncaught ReferenceError: Particles is not defined由四个明确问题导致,逐一修复即可让粒子效果正常运行:
- 脚本加载顺序错误
你将自定义业务脚本style.js放在<head>中提前加载,但particles库的引用被放在了<body>末尾。浏览器解析到style.js中调用Particles.init()的逻辑时,particles库文件还未加载执行,全局作用域不存在Particles对象,直接抛出引用错误。 - 库文件路径写法不规范
particles库的引用路径混用了Windows系统反斜杠与Web路径正斜杠:node_modules\particlesjs\dist/particles.min.js,Web环境不识别反斜杠作为路径分隔符,会导致库文件请求404,即便调整加载顺序也无法读取到库代码。 - Particles重复初始化
代码中先后两次调用Particles.init(),一次在window.onload回调中,一次在全局作用域直接执行,会造成粒子效果重复渲染,浪费性能甚至引发渲染冲突。 - 隐性代码错误
导航栏标签拼写错误:<sectio class="nav">缺少末尾的n,应为<section>;导航点击事件回调未传入event参数,点击标签时会触发event is not defined错误。
修复步骤
- 调整脚本加载顺序:将所有脚本按「依赖库在前、业务代码在后」的规则移动到
</body>标签前,删除<head>中对style.js的引用,确保jQuery、particles库全部加载完成后再执行自定义业务逻辑。 - 修正库路径:将particles库路径中的反斜杠全部替换为正斜杠,正确写法为
node_modules/particlesjs/dist/particles.min.js。 - 删除重复初始化逻辑:移除
window.onload中的Particles初始化代码,仅保留带自定义颜色、响应式配置的初始化实例即可。 - 修正拼写错误的section标签,补全点击事件缺失的event参数。
修复后可直接运行的代码
HTML部分
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <link rel="stylesheet" href="style.css"> </head> <body> <section class="nav"> <h1>FRONTEND TRENDS</h1> <h3 class="span loader"><span class="m">B</span><span class="m">E</span><span class="m">N</span><span class="m">E</span><span class="m">F</span><span class="m">I</span><span class="m">T</span><span class="m">S</span><span class="m"> </span><span class="m">o</span><span class="m">f</span><span class="m"> </span><span class="m">T</span><span class="m">E</span><span class="m">C</span><span class="m">H</span><span class="m">N</span><span class="m">O</span><span class="m">L</span><span class="m">O</span><span class="m">G</span><span class="m">I</span><span class="m">E</span><span class="m">S</span></h3> <div class="nav-container"><a class="nav-tab" href="#tab-pwa">PWA</a><a class="nav-tab" href="#tab-graphql">GraphQL</a><a class="nav-tab" href="#tab-next">NEXT</a><a class="nav-tab" href="#tab-typescript">TYPESCRIPT</a><a class="nav-tab" href="#tab-deno">DENO</a><span class="nav-tab-slider"></span></div> </section> <main class="main"> <section class="slider" id="tab-pwa"> <h1>PWA</h1> <h2>the best of both worlds...</h2> </section> <section class="slider" id="tab-graphql"> <h1>GraphQL</h1> <h2>a query language for APIs</h2> </section> <section class="slider" id="tab-next"> <h1>NEXT</h1> <h2>framework for Production</h2> </section> <section class="slider" id="tab-typescript"> <h1>TYPESCRIPT</h1> <h2>giving you better tooling at any scale</h2> </section> <section class="slider" id="tab-deno"> <h1>DENO</h1> <h2>a modern runtime</h2> </section> </main> <canvas class="background"></canvas> <!-- 按依赖优先级加载脚本 --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="node_modules/particlesjs/dist/particles.min.js"></script> <script src="style.js"></script> </body> </html>
JS部分(style.js)
/* Credit and Thanks: Matrix - Particles.js; SliderJS - Ettrics; Design - Sara Mazal Web; Fonts - Google Fonts */ // 仅保留一次带自定义配置的初始化 const particles = Particles.init({ selector: ".background", color: ["#03dac6", "#ff0266", "#000000"], connectParticles: true, responsive: [ { breakpoint: 768, options: { color: ["#faebd7", "#03dac6", "#ff0266"], maxParticles: 43, connectParticles: false } } ] }); class NavigationPage { constructor() { this.currentId = null; this.currentTab = null; this.tabContainerHeight = 70; this.lastScroll = 0; let self = this; // 补全缺失的event传参 $(".nav-tab").click(function (event) { self.onTabClick(event, $(this)); }); $(window).scroll(() => { this.onScroll(); }); $(window).resize(() => { this.onResize(); }); } onTabClick(event, element) { event.preventDefault(); let scrollTop = $(element.attr("href")).offset().top - this.tabContainerHeight + 1; $("html, body").animate({ scrollTop: scrollTop }, 600); } onScroll() { this.checkHeaderPosition(); this.findCurrentTabSelector(); this.lastScroll = $(window).scrollTop(); } onResize() { if (this.currentId) { this.setSliderCss(); } } checkHeaderPosition() { const headerHeight = 75; if ($(window).scrollTop() > headerHeight) { $(".nav-container").addClass("nav-container--scrolled"); } else { $(".nav-container").removeClass("nav-container--scrolled"); } let offset = $(".nav").offset().top + $(".nav").height() - this.tabContainerHeight - headerHeight; if ( $(window).scrollTop() > this.lastScroll && $(window).scrollTop() > offset ) { $(".nav-container").addClass("nav-container--move-up"); $(".nav-container").removeClass("nav-container--top-first"); $(".nav-container").addClass("nav-container--top-second"); } else if ( $(window).scrollTop() < this.lastScroll && $(window).scrollTop() > offset ) { $(".nav-container").removeClass("nav-container--move-up"); $(".nav-container").removeClass("nav-container--top-second"); $(".nav-container").addClass("nav-container--top-first"); } else { $(".nav-container").removeClass("nav-container--move-up"); $(".nav-container").removeClass("nav-container--top-first"); $(".nav-container").removeClass("nav-container--top-second"); } } findCurrentTabSelector(element) { let newCurrentId; let newCurrentTab; let self = this; $(".nav-tab").each(function () { let id = $(this).attr("href"); let offsetTop = $(id).offset().top - self.tabContainerHeight; let offsetBottom = $(id).offset().top + $(id).height() - self.tabContainerHeight; if ( $(window).scrollTop() > offsetTop && $(window).scrollTop() < offsetBottom ) { newCurrentId = id; newCurrentTab = $(this); } }); if (this.currentId != newCurrentId || this.currentId === null) { this.currentId = newCurrentId; this.currentTab = newCurrentTab; this.setSliderCss(); } } setSliderCss() { let width = 0; let left = 0; if (this.currentTab) { width = this.currentTab.css("width"); left = this.currentTab.offset().left; } $(".nav-tab-slider").css("width", width); $(".nav-tab-slider").css("left", left); } } new NavigationPage(); /* Credit and Thanks: Matrix - Particles.js; SliderJS - Ettrics; Design - Sara Mazal Web; Fonts - Google Fonts */
内容的提问来源于stack exchange,提问作者perkays
相关产品推荐
相关产品推荐

