使用Express GET方法结合jsdom在Node中访问DOM时btn未定义问题
错误原因
- 作用域限制:
let关键字声明的变量有块级作用域,你在JSDOM.fromFile的then回调块内定义的btn仅在该块内部有效,路由回调属于外层作用域,无法访问该变量。 - 异步时序问题:
JSDOM.fromFile是异步方法,不会阻塞后续代码执行,你现在的写法会先启动服务、注册路由,很可能出现路由被触发时JSDOM.fromFile还没执行完成的情况,就算你把btn提到外层也可能拿到未赋值的空值。
修复方案
把btn提升到外层作用域,同时等JSDOM加载完成后再启动Express服务,保证时序正确,示例代码如下:
const jsdom = require("jsdom"); const express = require('express') const app = express() const { JSDOM } = jsdom; // 把btn声明到外层作用域 let btn = null; JSDOM.fromFile("./index.html").then(dom => { btn = dom.window.document.querySelector('.btn'); // 加载完成后再启动服务,保证路由触发时btn已经赋值 app.listen(3000, () => console.log('服务启动在3000端口')); }).catch(err => console.log(err)); app.get("/", (req, res) => { res.sendFile("./index.html", {root: __dirname}) console.log(btn) });
如果后续有多个路由需要操作DOM元素,也可以把整个JSDOM实例存储在外层作用域,需要的时候再实时查询元素,避免变量缓存旧DOM节点的问题。
内容的提问来源于stack exchange,提问作者jaguar
相关产品推荐
相关产品推荐

