perf(comments): 评论加载提速 + 骨架屏 + 友链弹窗 pjax 修复 + toast 统一 Message.js
优化: - initArtalk 加节点级幂等守卫(mount.__atkInited,失败回滚), 消除 artalk.html/mypjax 多入口导致的 4× comments + 4× pv 重复请求 - fetch 包装层对无 body 的 GET/HEAD 去掉多余 content-type, 消掉 Artalk 对 GET /comments 的 CORS 预检(按完整 URL 缓存, 每篇文章都重付一次 RTT)。实测评论列表 +1150~1565ms → +626ms 修复: - 评论列表骨架屏改注入 .atk-list-body(原骨架在 #Comments 内, 被 Artalk.init 清空),list-loaded/故障/12s 兜底移除 - 友链申请弹窗抽成 modules/friendlink.js 进 page-only bundle (原内联脚本在 #pjax-container 外,pjax 后 flApplyOpenModal 未定义) - toast 统一走本地化 Message.js/Qmsg 适配层(保留 window.Toast/showToast 旧 API) 文档: - README / 架构总览 更新;新增 评论加载优化方案.md
This commit is contained in:
1 parent
9e972f2b61
commit
50a906e07c
14 files changed
+1018
-486
No files matched your search
@@ -1,63 +1,55 @@
|
||||
/**
|
||||
* Toast — lightweight notification
|
||||
* Usage: window.Toast.success('msg'), Toast.error('msg'), Toast.warning('msg'), Toast.info('msg')
|
||||
* window.Toast.show('msg', { type: 'info', duration: 2500 })
|
||||
* Toast — 统一通知组件(Message.js / Qmsg)
|
||||
*
|
||||
* 全站 toast 一律走 Message.js(https://github.com/snwjas/Message.js),
|
||||
* 库本体已本地化:js/libs/message.min.js + css/libs/message.min.css(随 style.css 打包)。
|
||||
* 这里只做一层薄适配,保留旧 API,调用点(utils/floating-tools/artalk…)不用改:
|
||||
* Toast.show(text, { type, duration })
|
||||
* Toast.success / error / warning / info(text, duration?)
|
||||
* showToast(text, type) ← 全局快捷方式
|
||||
*/
|
||||
(function() {
|
||||
var container = null;
|
||||
var counter = 0;
|
||||
(function () {
|
||||
if (window.__yingToastReady) return; // PJAX 重复执行防抖
|
||||
window.__yingToastReady = true;
|
||||
|
||||
function ensureContainer() {
|
||||
if (container) return;
|
||||
container = document.createElement('div');
|
||||
container.className = 'ying-toast-container';
|
||||
document.body.appendChild(container);
|
||||
var Q = window.Qmsg;
|
||||
if (!Q) {
|
||||
// Message.js 没加载出来时兜底:不打断业务,仅降级为无样式 console
|
||||
var fallback = function (text) {
|
||||
try { console.log('[toast]', text); } catch (e) {}
|
||||
};
|
||||
fallback.success = fallback.error = fallback.warning = fallback.info = fallback;
|
||||
window.Toast = fallback;
|
||||
window.showToast = function (text) { fallback(text); };
|
||||
return;
|
||||
}
|
||||
|
||||
function remove(el, delay) {
|
||||
setTimeout(function() {
|
||||
el.classList.remove('ying-toast--visible');
|
||||
el.addEventListener('transitionend', function onEnd(e) {
|
||||
if (e.propertyName !== 'opacity') return;
|
||||
el.removeEventListener('transitionend', onEnd);
|
||||
if (el.parentNode) el.parentNode.removeChild(el);
|
||||
});
|
||||
}, delay);
|
||||
// 全站统一默认值:最多同时 3 条,自动关闭
|
||||
try { Q.config({ maxNums: 3, timeout: 2500 }); } catch (e) {}
|
||||
|
||||
function opt(duration) {
|
||||
return duration ? { timeout: duration } : undefined;
|
||||
}
|
||||
|
||||
window.Toast = {
|
||||
show: function(text, options) {
|
||||
show: function (text, options) {
|
||||
options = options || {};
|
||||
var type = options.type || 'info';
|
||||
var duration = options.duration || 2200;
|
||||
|
||||
ensureContainer();
|
||||
|
||||
var el = document.createElement('div');
|
||||
el.className = 'ying-toast ying-toast--' + type;
|
||||
el.textContent = text;
|
||||
el.setAttribute('role', 'status');
|
||||
el.setAttribute('aria-live', 'polite');
|
||||
container.appendChild(el);
|
||||
|
||||
/* Force layout then animate in */
|
||||
void el.offsetWidth;
|
||||
el.classList.add('ying-toast--visible');
|
||||
|
||||
remove(el, duration);
|
||||
if (typeof Q[type] === 'function') return Q[type](text, opt(options.duration));
|
||||
return Q.info(text, opt(options.duration));
|
||||
},
|
||||
success: function (text, duration) { return Q.success(text, opt(duration)); },
|
||||
error: function (text, duration) { return Q.error(text, opt(duration)); },
|
||||
warning: function (text, duration) { return Q.warning(text, opt(duration)); },
|
||||
info: function (text, duration) { return Q.info(text, opt(duration)); },
|
||||
loading: function (text) { return Q.loading(text); },
|
||||
closeAll: function () { try { Q.closeAll(); } catch (e) {} }
|
||||
};
|
||||
|
||||
success: function(text, duration) {
|
||||
this.show(text, { type: 'success', duration: duration });
|
||||
},
|
||||
error: function(text, duration) {
|
||||
this.show(text, { type: 'error', duration: duration });
|
||||
},
|
||||
warning: function(text, duration) {
|
||||
this.show(text, { type: 'warning', duration: duration });
|
||||
},
|
||||
info: function(text, duration) {
|
||||
this.show(text, { type: 'info', duration: duration });
|
||||
}
|
||||
// 全局快捷方式(utils.js 原实现迁到这里,单一来源)
|
||||
window.showToast = function (text, type) {
|
||||
var t = type || 'info';
|
||||
if (window.Toast && typeof window.Toast[t] === 'function') window.Toast[t](text);
|
||||
else window.Toast.info(text);
|
||||
};
|
||||
})();
|
||||
Reference in new issue
Block a user