.NET Core应用中Tabulator加载不全 脚本引入延迟问题咨询
问题根源
你的代码有4个直接导致加载顺序异常的错误,和网络延迟无关,setTimeout只是刚好撞上了加载完成的时间点,本质是碰运气:
- 基础HTML结构完全不符合规范:你把页面内容容器
<div class="container body-content">放在了<head>标签之前,整个文档缺失<html>、<body>根标签,浏览器会自动重构DOM树,直接打乱所有资源的加载、执行顺序。 - 带
src属性的脚本标签内联代码无效:你写的<script type="module" src="~/js/site.js">标签内部的import语句会被浏览器直接忽略——只要script标签带了src属性,标签体里的所有代码都不会执行,你写的模块导入逻辑根本没跑。 - 混用两种Tabulator引入方式:你同时加载CDN的UMD全局版Tabulator,又试图用ESM模块方式导入,两类脚本的执行队列完全独立,全局
Tabulator变量的挂载时机完全不可控。 - 取值方式错误:你在defer脚本里用
this.Tabulator取值,defer脚本执行时的上下文不保证this指向window,就算Tabulator已经挂载到全局,你用this也可能取到undefined。
修正步骤
- 先把Layout.cshtml的HTML结构改成符合W3C规范的格式,所有资源按顺序放对位置,给普通脚本加
defer保证执行顺序:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link href="https://redacted.com/tabulator.min.css" rel="stylesheet" /> @* 二选一:要么用CDN全局引入,要么走npm包ESM引入,不要同时写 *@ @* 选CDN引入就保留下面这行 *@ <script defer src="https://redacted.com/tabulator.min.js"></script> @* 选ESM引入就删掉上面CDN的script,保留下面这行 *@ <script defer type="module" src="~/js/site.js" asp-append-version="true"></script> </head> <body> <div class="container body-content"> @RenderBody() </div> <script defer> // 所有初始化逻辑放到DOMContentLoaded回调里,不要用setTimeout document.addEventListener('DOMContentLoaded', () => { // 取全局变量统一用window,不要用this console.log("脚本加载完成,Tabulator状态:", window.Tabulator); // 这里写所有Tabulator初始化代码 }); </script> </body> </html>
- 如果选择ESM方式引入Tabulator,把import逻辑移到
site.js文件内部,不要写在script标签里:
// ~/js/site.js 文件内容 import {Tabulator, FilterModule, HtmlTableImportModule, SelectRowModule} from 'tabulator-tables'; // 注册用到的模块 Tabulator.registerModule([FilterModule, HtmlTableImportModule, SelectRowModule]); // 等DOM加载完成再初始化表格 document.addEventListener('DOMContentLoaded', () => { // 这里直接用导入的Tabulator变量初始化,不需要依赖全局变量 new Tabulator("#example-table", { // 表格配置 }); });
注意:所有带
defer属性的脚本,都会在DOMContentLoaded事件触发前按引入顺序执行完成,只要结构写对,完全不需要靠延时等变量加载。
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

