Skip to content

Commit 3b6b1a9

Browse files
1 parent 715c607 commit 3b6b1a9

486 files changed

Lines changed: 77698 additions & 4488 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

404.html

Lines changed: 150 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@
9090
<meta property="og:description" content="404">
9191
<meta property="og:locale" content="zh_CN">
9292
<meta property="og:image" content="https://blog.mhuig.top/lib/favicon/android-chrome-192x192.png">
93-
<meta property="article:published_time" content="2025-11-12T20:37:01.705Z">
94-
<meta property="article:modified_time" content="2025-11-12T20:37:01.705Z">
93+
<meta property="article:published_time" content="2025-11-14T01:55:25.450Z">
94+
<meta property="article:modified_time" content="2025-11-14T01:55:25.450Z">
9595
<meta property="article:author" content="MHuiG">
9696
<meta property="article:tag" content="Blog, MHuiG, @MHuiG, iMHuiG, 博客, Magicland, 魔法世界">
9797
<meta name="twitter:card" content="summary">
@@ -2085,12 +2085,113 @@
20852085

20862086
<script>
20872087
/************这个文件存放不需要重载的全局变量和全局函数*********/
2088-
window.volantis = {}; // volantis 全局变量
2088+
// window.volantis = {}; // volantis 全局变量
2089+
/**
2090+
* 内存安全的全局 volantis 对象实现
2091+
* 特性:
2092+
* 1. 支持 window.volantis.xxx = yyy 直观赋值语法
2093+
* 2. 基于 WeakMap 存储数据,自动回收内存
2094+
* 3. 支持属性枚举(如 Object.keys(window.volantis))
2095+
* 4. 支持删除属性(delete window.volantis.xxx)
2096+
*/
2097+
(function initializeVolantis() {
2098+
// 1. 初始化 WeakMap 存储实际数据(键:volantisProxy 实例,值:属性键值对)
2099+
const volantisDataStore = new WeakMap();
2100+
2101+
// 2. 创建 Proxy 代理处理属性访问
2102+
const volantisProxy = new Proxy({}, {
2103+
/**
2104+
* 拦截属性读取(如 window.volantis.dom)
2105+
* @param {Object} target - 代理目标对象(仅作为占位符,不存储数据)
2106+
* @param {string} prop - 访问的属性名
2107+
* @returns {any} 属性值或 undefined
2108+
*/
2109+
get(target, prop) {
2110+
const data = volantisDataStore.get(volantisProxy);
2111+
return data?.[prop]; // 使用可选链避免数据未初始化时的错误
2112+
},
2113+
2114+
/**
2115+
* 拦截属性赋值(如 window.volantis.dom = "a")
2116+
* @param {Object} target - 代理目标对象
2117+
* @param {string} prop - 赋值的属性名
2118+
* @param {any} value - 赋值的属性值
2119+
* @returns {boolean} 赋值是否成功
2120+
*/
2121+
set(target, prop, value) {
2122+
// 初始化数据容器(若不存在)
2123+
if (!volantisDataStore.has(volantisProxy)) {
2124+
volantisDataStore.set(volantisProxy, Object.create(null)); // 使用无原型对象避免原型污染
2125+
}
2126+
// 存储属性值
2127+
const data = volantisDataStore.get(volantisProxy);
2128+
data[prop] = value;
2129+
return true; // 符合 Proxy 规范,返回成功标志
2130+
},
2131+
2132+
/**
2133+
* 拦截属性删除(如 delete window.volantis.dom)
2134+
* @param {Object} target - 代理目标对象
2135+
* @param {string} prop - 要删除的属性名
2136+
* @returns {boolean} 删除是否成功
2137+
*/
2138+
deleteProperty(target, prop) {
2139+
const data = volantisDataStore.get(volantisProxy);
2140+
if (!data || !Object.prototype.hasOwnProperty.call(data, prop)) {
2141+
return false; // 属性不存在,删除失败
2142+
}
2143+
delete data[prop];
2144+
// 若数据为空,清理 WeakMap 条目(优化内存回收)
2145+
if (Object.keys(data).length === 0) {
2146+
volantisDataStore.delete(volantisProxy);
2147+
}
2148+
return true;
2149+
},
2150+
2151+
/**
2152+
* 拦截属性枚举(如 Object.keys(window.volantis))
2153+
* @param {Object} target - 代理目标对象
2154+
* @returns {string[]} 可枚举的属性名数组
2155+
*/
2156+
ownKeys(target) {
2157+
const data = volantisDataStore.get(volantisProxy);
2158+
return data ? Object.keys(data) : [];
2159+
},
2160+
2161+
/**
2162+
* 拦截属性描述符查询(如 Object.getOwnPropertyDescriptor)
2163+
* @param {Object} target - 代理目标对象
2164+
* @param {string} prop - 属性名
2165+
* @returns {PropertyDescriptor|undefined} 属性描述符
2166+
*/
2167+
getOwnPropertyDescriptor(target, prop) {
2168+
const data = volantisDataStore.get(volantisProxy);
2169+
if (!data || !Object.prototype.hasOwnProperty.call(data, prop)) {
2170+
return undefined;
2171+
}
2172+
return {
2173+
value: data[prop],
2174+
writable: true,
2175+
enumerable: true,
2176+
configurable: true
2177+
};
2178+
}
2179+
});
2180+
2181+
// 3. 挂载到 window 对象,暴露全局访问入口
2182+
Object.defineProperty(window, 'volantis', {
2183+
value: volantisProxy,
2184+
writable: true, // 允许后续手动设置为 null 触发清理
2185+
configurable: true,
2186+
enumerable: true
2187+
});
2188+
2189+
})();
20892190
volantis.debug = "false"; // 调试模式
20902191
volantis.dom = {}; // 页面Dom see: /source/js/app.js etc.
20912192
/******************** volantis.EventListener ********************************/
20922193
// 事件监听器 see: /source/js/app.js
2093-
volantis.EventListener = {}
2194+
/*volantis.EventListener = {}
20942195
// 这里存放pjax切换页面时将被移除的事件监听器
20952196
volantis.EventListener.list = []
20962197
//构造方法
@@ -2105,7 +2206,46 @@
21052206
i.ele.removeEventListener(i.type, i.f, false)
21062207
})
21072208
volantis.EventListener.list = []
2108-
}
2209+
}*/
2210+
volantis.EventListener = (() => {
2211+
// 用 WeakMap 存储 DOM 元素与监听器的映射(键为 DOM 元素,值为监听器数组)
2212+
const listenerWeakMap = new WeakMap();
2213+
2214+
return {
2215+
// 注册事件监听器(替代原有的构造方法)
2216+
add(type, f, ele) {
2217+
if (!ele || typeof ele.removeEventListener !== 'function') {
2218+
console.error('Invalid DOM element:', ele);
2219+
return;
2220+
}
2221+
2222+
// 为元素添加监听器并存储到 WeakMap
2223+
ele.addEventListener(type, f, false);
2224+
if (!listenerWeakMap.has(ele)) {
2225+
listenerWeakMap.set(ele, []); // 初始化元素的监听器数组
2226+
}
2227+
listenerWeakMap.get(ele).push({ type, f }); // 存储监听器元数据
2228+
},
2229+
2230+
// 移除指定元素的所有监听器
2231+
removeByElement(ele) {
2232+
if (!listenerWeakMap.has(ele)) return;
2233+
2234+
// 遍历并移除该元素的所有监听器
2235+
listenerWeakMap.get(ele).forEach(({ type, f }) => {
2236+
ele.removeEventListener(type, f, false);
2237+
});
2238+
listenerWeakMap.delete(ele); // 清除 WeakMap 中的记录
2239+
},
2240+
2241+
// 移除所有元素的监听器(用于 pjax 页面切换等场景)
2242+
remove() {
2243+
// WeakMap 无法直接遍历键,需通过临时数组缓存元素
2244+
const elements = Array.from(listenerWeakMap.keys());
2245+
elements.forEach(ele => this.removeByElement(ele));
2246+
}
2247+
};
2248+
})();
21092249
/******************** volantis.dom.$ ********************************/
21102250
// 注:这里没有选择器,也没有forEach一次只处理一个dom,这里重新封装主题常用的dom方法,返回的是dom对象,对象包含了以下方法,同时保留dom的原生API
21112251
function volantisDom(ele) {
@@ -2142,7 +2282,8 @@
21422282
this.ele.on = (c, f, r = 1) => {
21432283
this.ele.addEventListener(c, f, false)
21442284
if (r) {
2145-
volantis.EventListener.list.push(new volantisEventListener(c, f, this.ele))
2285+
//volantis.EventListener.list.push(new volantisEventListener(c, f, this.ele))
2286+
volantis.EventListener.add(c, f, this.ele);
21462287
}
21472288
return this.ele
21482289
}
@@ -2497,7 +2638,7 @@
24972638
root: '/Test/',
24982639
debug: false,
24992640
default: {"avatar":"https://static.mhuig.top/npm/volantis-static@0.0.1660614606622/media/placeholder/avatar/round/3442075.svg","link":"https://static.mhuig.top/npm/volantis-static@0.0.1660614606622/media/placeholder/link/8f277b4ee0ecd.svg","cover":"https://static.mhuig.top/npm/volantis-static@0.0.1660614606622/media/placeholder/cover/76b86c0226ffd.svg","image":"https://static.mhuig.top/npm/volantis-static@0.0.1660614606622/media/placeholder/image/2659360.svg"},
2500-
lastupdate: new Date(1762979826528),
2641+
lastupdate: new Date(1763085330336),
25012642
cdn: {
25022643
izitoast_css: 'https://cdn.bootcdn.net/ajax/libs/izitoast/1.4.0/css/iziToast.min.css',
25032644
izitoast_js: 'https://cdn.bootcdn.net/ajax/libs/izitoast/1.4.0/js/iziToast.min.js',
@@ -2547,8 +2688,9 @@
25472688
}
25482689
}
25492690
</script>
2691+
25502692

2551-
<script type="application/ld+json">[{"@context":"http://schema.org","@type":"Organization","name":"MHuiG Magicland","url":"https://blog.mhuig.top/Test/","logo":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}},{"@context":"http://schema.org","@type":"Person","name":"MHuiG","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png"},"url":"https://blog.mhuig.top/Test/","sameAs":["https://github.com/MHuiG","https://twitter.com/iMHuiG","https://t.me/MHuiG","https://keybase.io/MHuiG"],"description":"「Be Yourself, Make a Difference.」"},{"@context":"http://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://blog.mhuig.top/Test/","name":"Magicland"}}]},{"@context":"http://schema.org","@type":"WebSite","name":"MHuiG Magicland","url":"https://blog.mhuig.top/Test/","keywords":"Blog, MHuiG, @MHuiG, iMHuiG, 博客, Magicland, 魔法世界","description":"MHuiG Blog (MHuiG的博客) Magicland(MHuiG的魔法世界) —— MHuiG(@MHuiG) 随便写写画画的地方 - Magic Island","author":{"@type":"Person","name":"MHuiG","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png"},"url":"https://blog.mhuig.top/Test/","description":"「Be Yourself, Make a Difference.」"},"publisher":{"@type":"Organization","name":"MHuiG Magicland","url":"https://blog.mhuig.top/Test/","logo":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}},"potentialAction":{"@type":"SearchAction","name":"Coco | The Cat of MHuiG","target":{"@type":"EntryPoint","urlTemplate":"https://blog.mhuig.top/havefun/Coco/?s={search_term_string}"},"query-input":"required name=search_term_string"}},{"@context":"http://schema.org","@type":"BlogPosting","description":"MHuiG Blog (MHuiG的博客) Magicland(MHuiG的魔法世界) —— MHuiG(@MHuiG) 随便写写画画的地方 - Magic Island","inLanguage":"zh-CN","mainEntityOfPage":{"@type":"WebPage","@id":"https://blog.mhuig.top/404"},"author":{"@type":"Person","name":"MHuiG","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png"},"url":"https://blog.mhuig.top/Test/"},"publisher":{"@type":"Organization","name":"MHuiG Magicland","logo":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}},"url":"https://blog.mhuig.top/404","wordCount":0,"datePublished":"2025-11-12T20:37:01.705Z","dateModified":"2025-11-12T20:37:01.705Z","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}}]</script>
2693+
<script type="application/ld+json">[{"@context":"http://schema.org","@type":"Organization","name":"MHuiG Magicland","url":"https://blog.mhuig.top/Test/","logo":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}},{"@context":"http://schema.org","@type":"Person","name":"MHuiG","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png"},"url":"https://blog.mhuig.top/Test/","sameAs":["https://github.com/MHuiG","https://twitter.com/iMHuiG","https://t.me/MHuiG","https://keybase.io/MHuiG"],"description":"「Be Yourself, Make a Difference.」"},{"@context":"http://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://blog.mhuig.top/Test/","name":"Magicland"}}]},{"@context":"http://schema.org","@type":"WebSite","name":"MHuiG Magicland","url":"https://blog.mhuig.top/Test/","keywords":"Blog, MHuiG, @MHuiG, iMHuiG, 博客, Magicland, 魔法世界","description":"MHuiG Blog (MHuiG的博客) Magicland(MHuiG的魔法世界) —— MHuiG(@MHuiG) 随便写写画画的地方 - Magic Island","author":{"@type":"Person","name":"MHuiG","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png"},"url":"https://blog.mhuig.top/Test/","description":"「Be Yourself, Make a Difference.」"},"publisher":{"@type":"Organization","name":"MHuiG Magicland","url":"https://blog.mhuig.top/Test/","logo":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}},"potentialAction":{"@type":"SearchAction","name":"Coco | The Cat of MHuiG","target":{"@type":"EntryPoint","urlTemplate":"https://blog.mhuig.top/havefun/Coco/?s={search_term_string}"},"query-input":"required name=search_term_string"}},{"@context":"http://schema.org","@type":"BlogPosting","description":"MHuiG Blog (MHuiG的博客) Magicland(MHuiG的魔法世界) —— MHuiG(@MHuiG) 随便写写画画的地方 - Magic Island","inLanguage":"zh-CN","mainEntityOfPage":{"@type":"WebPage","@id":"https://blog.mhuig.top/404"},"author":{"@type":"Person","name":"MHuiG","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png"},"url":"https://blog.mhuig.top/Test/"},"publisher":{"@type":"Organization","name":"MHuiG Magicland","logo":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}},"url":"https://blog.mhuig.top/404","wordCount":0,"datePublished":"2025-11-14T01:55:25.450Z","dateModified":"2025-11-14T01:55:25.450Z","image":{"@type":"ImageObject","url":"/lib/favicon/android-chrome-192x192.png","width":192,"height":192}}]</script>
25522694

25532695
<!-- import head_end begin -->
25542696
<!-- import head_end end -->

0 commit comments

Comments
 (0)