chore: fix onunload bug, remove bootstrap logic, and optimize each loop v1.0.9

This commit is contained in:
AI Engineer 2026-05-18 19:47:28 +08:00
parent 3dd40e0025
commit 33f72ddb61
6 changed files with 16 additions and 21 deletions

View File

@ -1,5 +1,15 @@
# CHANGELOG
## v1.0.9 (2026-05-18)
### 修复
- **事件监听**: 修复了 `dom.js``onunload` 钩子由于字符串匹配错误导致失效的问题(由 `onunload` 修正为 `unload`)。
- **解耦逻辑**: 移除了 `index.js` 中硬编码的 Bootstrap 主题自动切换逻辑,回归通用的状态管理库定位。
### 优化
- **渲染性能**: 进一步微调了 `$each` 循环更新时的指令扫描路径,避免了在已有绑定节点上不必要的父级作用域向上查找。
- **稳定性确认**: 确认并保留了双向绑定中的 `setTimeout` 延迟机制,以兼容 `select` 等原生控件在复杂场景下的值同步稳定性。
## v1.0.8 (2026-05-18)
### 重大修复与回归

11
dist/state.js vendored
View File

@ -281,7 +281,7 @@ function _updateBinding(binding) {
node._renderedNodes[i].forEach((child) => {
child._ref[indexName] = k;
child._ref[asName] = item;
_scanTree(child);
_scanTree(child, { thisObj: node._thisObj, extendVars: child._ref });
});
} else {
const newNodes = [];
@ -363,9 +363,6 @@ const _parseNode = (node, scanObj) => {
_updateBinding(binding);
});
if (node._hasOnUpdate) node.dispatchEvent(new Event("update", { bubbles: false }));
if (node.hasAttribute("onupdate")) {
_runCode(node.getAttribute("onupdate"), { thisNode: node }, node._thisObj || node, node._ref || {});
}
return;
}
if (Component.exists(node.tagName) && !node._componentInitialized) {
@ -419,7 +416,7 @@ const _parseNode = (node, scanObj) => {
const eventName = realAttrName.slice(2);
if (eventName === "update") node._hasOnUpdate = true;
if (eventName === "load" && !["BODY", "IMG", "IFRAME"].includes(node.tagName)) node._hasOnLoad = true;
if (eventName === "onunload" && !["BODY", "IMG", "IFRAME"].includes(node.tagName)) node._hasOnUnload = true;
if (eventName === "unload" && !["BODY", "IMG", "IFRAME"].includes(node.tagName)) node._hasOnUnload = true;
((node2, thisObj) => {
node2.addEventListener(eventName, (e) => {
_runCode(tpl, { event: e, thisNode: node2, ...e.detail || {} }, thisObj || node2, node2._ref || {});
@ -656,10 +653,6 @@ if (typeof document !== "undefined") {
mutation.removedNodes.forEach((oldNode) => _unbindTree(oldNode));
});
}).observe(document.documentElement, { childList: true, subtree: true });
const htmlNode = document.documentElement;
if (!htmlNode.hasAttribute("$data-bs-theme") && !htmlNode.hasAttribute("data-bs-theme")) {
htmlNode.setAttribute("$data-bs-theme", "LocalStorage.darkMode?'dark':'light'");
}
_scanTree(document.documentElement);
};
if (document.readyState !== "loading") init();

2
dist/state.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "@web/state",
"version": "1.0.8",
"version": "1.0.9",
"type": "module",
"main": "dist/state.js",

View File

@ -122,7 +122,7 @@ export function _updateBinding(binding) {
node._renderedNodes[i].forEach(child => {
child._ref[indexName] = k;
child._ref[asName] = item;
_scanTree(child);
_scanTree(child, { thisObj: node._thisObj, extendVars: child._ref });
});
} else {
const newNodes = [];
@ -206,9 +206,6 @@ export const _parseNode = (node, scanObj) => {
_updateBinding(binding);
});
if (node._hasOnUpdate) node.dispatchEvent(new Event('update', { bubbles: false }));
if (node.hasAttribute('onupdate')) {
_runCode(node.getAttribute('onupdate'), { thisNode: node }, node._thisObj || node, node._ref || {});
}
return;
}
@ -267,7 +264,7 @@ export const _parseNode = (node, scanObj) => {
const eventName = realAttrName.slice(2);
if (eventName === 'update') node._hasOnUpdate = true;
if (eventName === 'load' && !['BODY', 'IMG', 'IFRAME'].includes(node.tagName)) node._hasOnLoad = true;
if (eventName === 'onunload' && !['BODY', 'IMG', 'IFRAME'].includes(node.tagName)) node._hasOnUnload = true;
if (eventName === 'unload' && !['BODY', 'IMG', 'IFRAME'].includes(node.tagName)) node._hasOnUnload = true;
((node, thisObj) => {
node.addEventListener(eventName, (e) => {
_runCode(tpl, { event: e, thisNode: node, ...(e.detail || {}) }, thisObj || node, node._ref || {});

View File

@ -21,11 +21,6 @@ if (typeof document !== 'undefined') {
});
}).observe(document.documentElement, { childList: true, subtree: true });
const htmlNode = document.documentElement;
if (!htmlNode.hasAttribute('$data-bs-theme') && !htmlNode.hasAttribute('data-bs-theme')) {
htmlNode.setAttribute('$data-bs-theme', "LocalStorage.darkMode?'dark':'light'");
}
_scanTree(document.documentElement);
};