JS动态加载jQuery失效报$未定义错误排查求助
原始相关代码
plugins.js
var jquery = document.createElement("script"); jquery.type = "text/javascript"; jquery.src = "assets/vendor/js/jquery.min.js"; document.body.appendChild(jquery);
index.html
<body> <script src="./assets/js/plugins.js"></script> <script src="./assets/js/main.js"></script> </body> </html>
报错信息
Uncaught ReferenceError: $ is not defined at main.js:1
错误根因
动态创建的script标签加载外部资源是异步行为:当plugins.js执行插入jQuery的script标签逻辑后,浏览器不会等待jQuery下载、解析完成再执行后续的main.js,而是会立刻执行main.js代码,此时全局还没有挂载jQuery的$对象,就会抛出未定义报错。
解决方案
方案1:监听onload事件加载业务代码(推荐)
该方案不会阻塞页面渲染,兼容性好。调整逻辑在jQuery加载完成后再加载main.js即可:
修改后的plugins.js:
var jquery = document.createElement("script"); jquery.type = "text/javascript"; jquery.src = "assets/vendor/js/jquery.min.js"; // 监听jQuery加载完成事件 jquery.onload = function() { // 动态加载main.js var mainScript = document.createElement("script"); mainScript.src = "./assets/js/main.js"; document.body.appendChild(mainScript); } document.body.appendChild(jquery);
修改后的index.html删除单独引入main.js的逻辑:
<body> <script src="./assets/js/plugins.js"></script> </body> </html>
方案2:关闭script异步加载(不推荐)
如果不想调整现有代码结构,可以给动态创建的jQuery标签关闭异步属性,浏览器会阻塞后续代码执行直到jQuery加载完成,缺点是会拖慢页面渲染速度:
仅需修改plugins.js,添加一行配置即可:
var jquery = document.createElement("script"); jquery.type = "text/javascript"; jquery.src = "assets/vendor/js/jquery.min.js"; jquery.async = false; // 关闭异步加载 document.body.appendChild(jquery);
方案3:main.js内轮询检测jQuery加载状态
如果不想调整脚本引入逻辑,可以把main.js内的业务逻辑包裹在轮询检测逻辑中,等jQuery加载完成后再执行:
修改后的main.js:
var checkJqueryTimer = setInterval(function() { if (window.$) { clearInterval(checkJqueryTimer); // 此处写原main.js的业务代码 console.log($('body')); } }, 50);
内容的提问来源于stack exchange,提问作者cinoprogrammer
相关产品推荐
相关产品推荐

