fixed bug

This commit is contained in:
Vaica committed 2026-01-31 19:24:22 +08:00
1 parent 7b945786ed
commit 54b18039e3
21 files changed
+2363 -408

No files matched your search

+93
View File
@@ -0,0 +1,93 @@
// Global Artalk Initialization Function (Supports PJAX)
window.initArtalk = function() {
if (!document.querySelector("#Comments")) return;
// Check if configuration exists
if (!window.artalkConfig) {
console.warn('window.artalkConfig is not defined. Skipping Artalk init.');
return;
}
// Check if Artalk library is loaded
if (typeof Artalk === 'undefined') {
console.warn('Artalk library is not loaded yet. Waiting for bundle...');
return;
}
try {
var artalk = Artalk.init(window.artalkConfig);
window.artalk = artalk; // Expose to window for other scripts
// Handle list-loaded event for lazy loading avatars and animations
artalk.on('list-loaded', function() {
// Restore AI Comment if configured
if (window.artalkConfig.aiComment) {
var ai = window.artalkConfig.aiComment;
var listBody = document.querySelector('.atk-list .atk-list-body');
if (listBody && !listBody.querySelector('.atk-ai-comment')) {
var aiCommentHtml = `
<div class="atk-comment-wrap atk-comment atk-ai-comment" id="atk-comment-ai">
<div class="atk-avatar" uk-scrollspy="cls: uk-animation-scale-up; delay: 200">
<img src="${ai.avatar}" alt="${ai.name}">
</div>
<div class="atk-main" uk-scrollspy="cls: uk-animation-slide-right-small; delay: 300">
<div class="atk-header">
<span class="atk-nick" uk-scrollspy="cls: uk-animation-slide-top-small; delay: 350">${ai.name}</span>
<span class="atk-badge">AI</span>
<span class="atk-date">${ai.date}</span>
</div>
<div class="atk-body">
<div class="atk-content">${ai.content}</div>
</div>
</div>
</div>
`;
listBody.insertAdjacentHTML('afterbegin', aiCommentHtml);
// Hide "No Comment" placeholder if it exists
var noComment = document.querySelector('.atk-list-no-comment');
if (noComment) {
noComment.style.display = 'none';
}
}
}
// Add staggered animation to the comment list
var list = document.querySelector('.atk-list');
if (list) {
list.setAttribute('uk-scrollspy', 'target: > .atk-comment-wrap; cls: uk-animation-slide-bottom-small; delay: 50');
}
// Apply granular animations to inner elements
document.querySelectorAll('.atk-comment-wrap:not(.atk-ai-comment)').forEach(function(wrap) {
var avatar = wrap.querySelector('.atk-avatar');
if (avatar) avatar.setAttribute('uk-scrollspy', 'cls: uk-animation-scale-up; delay: 200');
var main = wrap.querySelector('.atk-main');
if (main) main.setAttribute('uk-scrollspy', 'cls: uk-animation-slide-right-small; delay: 300');
var nick = wrap.querySelector('.atk-nick');
if (nick) nick.setAttribute('uk-scrollspy', 'cls: uk-animation-slide-top-small; delay: 350');
});
// Find all avatars in the comment list
var avatars = document.querySelectorAll('.atk-list .atk-avatar img');
avatars.forEach(function(img) {
var src = img.getAttribute('src');
if (src) {
img.setAttribute('data-lazy-src', src);
img.removeAttribute('src');
img.classList.add('lazyload');
}
});
// Trigger lazy load update
if (window.lazyLoadAgain) {
window.lazyLoadAgain();
}
});
} catch (e) {
console.error('Artalk init failed:', e);
}
};
@@ -0,0 +1,106 @@
window.initFloatingTools = function() {
// 1. Back to Top
var backToTopButton = document.getElementById('back-to-top');
if (backToTopButton) {
var ticking = false;
function update() {
var btn = document.getElementById('back-to-top');
if (!btn) return;
if (window.scrollY > 300) {
if (!btn.classList.contains('show')) {
btn.classList.add('show');
}
} else {
if (btn.classList.contains('show')) {
btn.classList.remove('show');
}
}
ticking = false;
}
// Global Scroll Handler
if (!window.backToTopScrollHandler) {
window.backToTopScrollHandler = function() {
if (!ticking) {
window.requestAnimationFrame(update);
ticking = true;
}
};
window.addEventListener('scroll', window.backToTopScrollHandler, { passive: true });
}
// Re-bind click event
var newBtn = backToTopButton.cloneNode(true);
backToTopButton.parentNode.replaceChild(newBtn, backToTopButton);
backToTopButton = newBtn;
backToTopButton.addEventListener('click', function(e) {
e.preventDefault();
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
}
// 2. Theme Toggle
var themeToggle = document.getElementById('theme-toggle');
if (themeToggle) {
var newToggle = themeToggle.cloneNode(true);
themeToggle.parentNode.replaceChild(newToggle, themeToggle);
themeToggle = newToggle;
// Update icon based on current theme
var updateIcon = function() {
var currentTheme = document.documentElement.getAttribute('data-theme');
var icon = themeToggle.querySelector('i');
if (icon) {
if (currentTheme === 'dark') {
icon.className = 'ri-moon-line';
} else {
icon.className = 'ri-sun-line';
}
}
};
updateIcon();
themeToggle.addEventListener('click', function() {
var currentTheme = document.documentElement.getAttribute('data-theme');
var newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
updateIcon();
// Trigger Artalk theme update
if (window.artalk) {
window.artalk.setDarkMode(newTheme === 'dark');
}
});
}
// 3. To Comments
var toComments = document.getElementById('to-comments');
if (toComments) {
var newToComments = toComments.cloneNode(true);
toComments.parentNode.replaceChild(newToComments, toComments);
toComments = newToComments;
toComments.addEventListener('click', function(e) {
e.preventDefault();
var comments = document.getElementById('Comments');
if (comments) {
comments.scrollIntoView({ behavior: 'smooth' });
} else {
var artalkEl = document.querySelector('.artalk');
if (artalkEl) {
artalkEl.scrollIntoView({ behavior: 'smooth' });
} else {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
}
}
});
}
};
+88
View File
@@ -0,0 +1,88 @@
(function() {
var defaults = {
showTime: 800,
offsetBottom: 0,
offsetTopm: 50,
onLoadBackEnd: function (index, dom) { },
onLoadBackStart: function (index, dom) { }
};
var observer;
function init(setting) {
defaults = Object.assign({}, defaults, setting || {});
// Initialize IntersectionObserver
if (!observer) {
observer = new IntersectionObserver(function(entries, self) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var img = entry.target;
showImg(img);
self.unobserve(img);
}
});
}, {
rootMargin: defaults.offsetTopm + "px 0px " + defaults.offsetBottom + "px 0px"
});
}
processImages();
}
function processImages() {
var images = document.querySelectorAll('img:not(.blog-img):not([data-comp])');
images.forEach(function(img) {
// Check if already processed or has data-lazy-src
if (img.getAttribute('data-lazy-src')) {
// Already setup for lazy load, just observe
observer.observe(img);
} else if (img.getAttribute('src')) {
// Convert to lazy load
var src = img.getAttribute('src');
img.setAttribute('data-lazy-src', src);
img.setAttribute('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
observer.observe(img);
}
});
}
function showImg(dom) {
if (dom.getAttribute('data-comp')) return;
dom.setAttribute('data-comp', 'true');
var src = dom.getAttribute('data-lazy-src');
if (!src) return;
// Create a temporary image to preload
var temp = new Image();
temp.onload = function() {
// Prepare for transition
dom.style.opacity = 0;
dom.style.transition = "opacity " + (defaults.showTime / 1000) + "s ease-in-out";
// Swap source
dom.setAttribute('src', src);
// Force reflow
void dom.offsetWidth;
// Fade in
dom.style.opacity = 1;
};
temp.onerror = function() {
// On error, show anyway
dom.setAttribute('src', src);
dom.style.opacity = 1;
};
temp.src = src;
}
function tryAgain() {
processImages();
}
window.lazyLoadInit = init;
window.lazyLoadAgain = tryAgain;
})();
+17
View File
@@ -0,0 +1,17 @@
window.initLoader = function() {
var loader = document.getElementById('loader');
if (!loader) return;
// 定时关闭
setTimeout(function() {
loader.classList.add('hide');
}, 30000);
// 点击关闭
var closeBtn = document.getElementById('closeloader');
if (closeBtn) {
closeBtn.addEventListener('click', function() {
loader.classList.add('hide');
});
}
};
+196
View File
@@ -0,0 +1,196 @@
window.initSearch = function() {
initSearchModal();
initInlineSearch();
};
function loadSearchIndex() {
if (!window.searchIndex) {
return fetch('/index.json')
.then(response => response.json())
.then(data => {
window.searchIndex = data;
return data;
})
.catch(err => console.error('Failed to load search index:', err));
}
return Promise.resolve(window.searchIndex);
}
function initSearchModal() {
var searchBtn = document.getElementById('search-btn');
var searchModal = document.getElementById('search-modal');
if (searchBtn && searchModal) {
// Clone to remove old listeners
var newSearchBtn = searchBtn.cloneNode(true);
searchBtn.parentNode.replaceChild(newSearchBtn, searchBtn);
searchBtn = newSearchBtn;
searchBtn.addEventListener('click', function() {
searchModal.classList.add('show');
var input = document.getElementById('search-input');
if (input) setTimeout(function() { input.focus(); }, 100);
loadSearchIndex();
});
// Close logic
var closeBtn = searchModal.querySelector('.close-search');
if (closeBtn) {
closeBtn.onclick = function() {
searchModal.classList.remove('show');
};
}
// Click outside to close
searchModal.onclick = function(e) {
if (e.target === searchModal) {
searchModal.classList.remove('show');
}
};
// Search Input Logic
var searchInput = document.getElementById('search-input');
var searchResults = document.getElementById('search-results');
if (searchInput && searchResults) {
// Clone input to remove old listeners
var newInput = searchInput.cloneNode(true);
searchInput.parentNode.replaceChild(newInput, searchInput);
searchInput = newInput;
// Clone results to remove old listeners
var newResults = searchResults.cloneNode(true);
searchResults.parentNode.replaceChild(newResults, searchResults);
searchResults = newResults;
// Close modal when a result is clicked
searchResults.addEventListener('click', function(e) {
if (e.target.closest('a')) {
searchModal.classList.remove('show');
}
});
searchInput.addEventListener('input', function() {
var query = this.value.trim().toLowerCase();
if (!window.searchIndex || query.length === 0) {
searchResults.innerHTML = '<p class="search-tip">输入关键词并回车进行搜索</p>';
return;
}
var results = window.searchIndex.filter(function(item) {
return (item.title && item.title.toLowerCase().includes(query)) ||
(item.summary && item.summary.toLowerCase().includes(query));
});
if (results.length > 0) {
var html = results.map(function(item) {
return `
<div class="search-result-item">
<a href="${item.permalink}" class="search-result-title">${item.title}</a>
<span class="search-result-date">${item.date}</span>
<div class="search-result-summary">${item.summary || ''}</div>
</div>
`;
}).join('');
searchResults.innerHTML = html;
// Refresh PJAX to recognize new links
if (window.pjax) {
window.pjax.refresh(searchResults);
}
} else {
searchResults.innerHTML = '<p class="search-tip">未找到相关文章</p>';
}
});
}
}
}
function initInlineSearch() {
var header = document.getElementById('essay-header');
var searchContainer = document.getElementById('search-container');
var input = document.getElementById('inline-search-input');
var resultsContainer = document.getElementById('inline-search-results');
window.toggleSearchMode = function(show) {
if (!header || !searchContainer || !input || !resultsContainer) return;
if (show) {
header.style.display = 'none';
searchContainer.style.display = 'block';
input.focus();
loadSearchIndex();
} else {
header.style.display = 'inline-flex';
searchContainer.style.display = 'none';
input.value = '';
resultsContainer.classList.remove('show');
resultsContainer.innerHTML = '';
}
};
if (!header || !searchContainer || !input || !resultsContainer) return;
// Input Event
var newInput = input.cloneNode(true);
input.parentNode.replaceChild(newInput, input);
input = newInput;
input.addEventListener('input', function() {
var query = this.value.trim().toLowerCase();
if (query.length === 0) {
resultsContainer.classList.remove('show');
resultsContainer.innerHTML = '';
return;
}
if (!window.searchIndex) return;
var results = window.searchIndex.filter(function(item) {
return (item.title && item.title.toLowerCase().includes(query)) ||
(item.summary && item.summary.toLowerCase().includes(query));
});
if (results.length > 0) {
var html = results.slice(0, 5).map(function(item) {
return `
<a href="${item.permalink}" class="search-result-item" style="display:block; text-decoration:none;" onclick="window.toggleSearchMode(false)">
<span class="search-result-title">${item.title}</span>
<div style="display:flex; align-items:center;">
<span class="search-result-date">${item.date}</span>
</div>
</a>
`;
}).join('');
resultsContainer.innerHTML = html;
resultsContainer.classList.add('show');
// PJAX Refresh
if (window.pjax) {
window.pjax.refresh(resultsContainer);
}
} else {
resultsContainer.innerHTML = '<div class="search-result-item" style="text-align:center;color:#999;cursor:default;">无搜索结果</div>';
resultsContainer.classList.add('show');
}
});
// Close on click outside
if (!window.inlineSearchClickOutside) {
window.inlineSearchClickOutside = function(e) {
var header = document.getElementById('essay-header');
var searchContainer = document.getElementById('search-container');
var resultsContainer = document.getElementById('inline-search-results');
if (header && searchContainer && resultsContainer && searchContainer.style.display === 'block') {
if (!searchContainer.contains(e.target) && !header.contains(e.target) && !resultsContainer.contains(e.target)) {
window.toggleSearchMode(false);
}
}
};
document.addEventListener('click', window.inlineSearchClickOutside);
}
}
+8
View File
@@ -0,0 +1,8 @@
// 判断是否为移动端
window.isMobile = function() {
if (window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
return true; // 移动端
} else {
return false; // PC端
}
};