Express+EJS环境DOM操作报错:Document未定义,求JQuery操作方案
问题根源与解决方案
你犯了核心错误:把服务器端代码和客户端代码搞混了。Node.js服务器环境没有浏览器的原生DOM,你用jsdom模拟的DOM是空的,根本不存在EJS渲染后的<h2>或<input>元素;而且客户端的jQuery应该在浏览器中运行,不能放在服务器端执行。
第一步:清理服务器端代码(index.js)
删掉所有和jsdom、jQuery相关的冗余代码,服务器只负责处理请求、渲染模板。修改后的代码如下:
const express = require('express'); const app = express(); const port = 3000; const ejs = require('ejs'); const bodyParser = require('body-parser'); const _ = require('lodash'); let inputMail = 40; app.use(bodyParser.urlencoded({extended: true})); app.use(express.static('public')); app.set('view engine', 'ejs'); app.get('/', (req, res) => { res.render('home', { inputMail: inputMail }); }); app.get('/blogs/create', (req, res) => { // 补充渲染的模板名称 res.render('create'); }); // 启动服务器 app.listen(port, () => { console.log(`Server running on port ${port}`); });
第二步:创建客户端专用JS文件
在项目的public文件夹下新建js目录,创建client.js文件,所有DOM操作代码都放在这里:
// 等待页面DOM完全加载后再执行操作 $(document).ready(function() { // 修改h2标题颜色 $('.textLogo').css('color', 'red'); // 动态修改input的size属性 $('#inputEmail').attr('size', 50); // 示例:修改文本内容 $('#externalLink').text('已上线!'); });
第三步:修正EJS文件的脚本引用
把EJS里原来引用index.js的地方,改成引用客户端的client.js,保留jQuery的CDN引用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'> <link rel="stylesheet" href="css/styles.css"> <link href="https://emoji-css.afeld.me/emoji.css" rel="stylesheet"> <title>Learning to code</title> </head> <body> <div class="container"> <div class="home_outter"> <div class="home-top-header"> <form action="post"> <i class='bx bx-envelope'></i> <input type="text" id="inputEmail" placeholder="Gert tips and actionable insights on how to build amazing projects" size="<%= inputMail %>"> <button type="submit">Oui, avec plaisir 🤩</button> </form> </div> <div class="links-external"> <span class="text" id="externalLink">Coming Soon!</span> <i class='bx bxl-instagram-alt'></i> <i class='bx bxl-linkedin-square'></i> <i class='bx bxl-twitter'></i> </div> </div> <section id="navbar"> <h2 class="textLogo" id="textLogo" >Learn Code</h2> </section> </div> <div class="footer-padding"> <div class="footer"> <p>Made with 💛 by a daydreamer</p> </div> </div> </body> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <!-- 引用客户端专属JS文件 --> <script src="/js/client.js" type="text/javascript"></script> </html>
关键注意事项
- 环境边界:服务器负责渲染模板、处理请求;客户端(浏览器)负责执行JS操作DOM,两者完全独立,不能混淆。
- DOM加载时机:必须用
$(document).ready()包裹jQuery代码,确保页面元素全部加载完成后再执行操作,避免出现找不到元素的情况。 - 依赖精简:服务器端不需要
jquery和jsdom依赖,可执行npm uninstall jquery jsdom删除,减少冗余。
内容的提问来源于stack exchange,提问作者Kersmo
相关产品推荐
相关产品推荐

