fixed bug
This commit is contained in:
1 parent
7b945786ed
commit
54b18039e3
21 files changed
+2363
-408
No files matched your search
-97
@@ -1,97 +0,0 @@
|
||||
(function ($) {
|
||||
var defaults = {
|
||||
showTime: 800,
|
||||
offsetBottom: 0,
|
||||
offsetTopm: 50,
|
||||
onLoadBackEnd: function (index, dom) { },
|
||||
onLoadBackStart: function (index, dom) { }
|
||||
};
|
||||
|
||||
var $lazyImgList = $();
|
||||
|
||||
function checkOffset() {
|
||||
var scrollTop = $(document).scrollTop();
|
||||
var windowHeight = $(window).height();
|
||||
|
||||
$lazyImgList.each(function (index) {
|
||||
var $dom = $(this);
|
||||
if ($dom.attr("data-comp")) return; // Already processed
|
||||
|
||||
var offsetTop = $dom.offset().top;
|
||||
// Check if image is in viewport (with some buffer)
|
||||
if (offsetTop - scrollTop + defaults.offsetTopm >= 0 &&
|
||||
offsetTop - scrollTop < (windowHeight + defaults.offsetBottom)) {
|
||||
|
||||
showImg($dom, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showImg($dom, index) {
|
||||
$dom.attr("data-comp", "true");
|
||||
var src = $dom.attr("data-lazy-src");
|
||||
|
||||
defaults.onLoadBackStart(index, $dom);
|
||||
|
||||
// Create a temporary image to preload
|
||||
var temp = new Image();
|
||||
temp.onload = function() {
|
||||
// Prepare for transition
|
||||
$dom.css({
|
||||
"opacity": 0,
|
||||
"transition": "opacity " + (defaults.showTime / 1000) + "s ease-in-out"
|
||||
});
|
||||
|
||||
// Swap source
|
||||
$dom.attr("src", src);
|
||||
|
||||
// Force reflow to ensure transition triggers
|
||||
void $dom[0].offsetWidth;
|
||||
|
||||
// Fade in
|
||||
$dom.css("opacity", 1);
|
||||
|
||||
defaults.onLoadBackEnd(index, $dom);
|
||||
};
|
||||
temp.onerror = function() {
|
||||
// On error, show anyway (maybe broken image icon) but ensure visible
|
||||
$dom.attr("src", src);
|
||||
$dom.css("opacity", 1);
|
||||
};
|
||||
temp.src = src;
|
||||
}
|
||||
|
||||
function init(setting) {
|
||||
defaults = $.extend(defaults, setting);
|
||||
|
||||
// Auto-convert standard images to lazy load format
|
||||
// Exclude .blog-img (Header Avatar) to prevent visibility issues
|
||||
$("img").not(".blog-img").each(function() {
|
||||
var $this = $(this);
|
||||
// Only convert if not already converted and has a src
|
||||
if (!$this.attr("data-lazy-src") && $this.attr("src")) {
|
||||
$this.attr("data-lazy-src", $this.attr("src"));
|
||||
// Set placeholder
|
||||
$this.attr("src", "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==");
|
||||
}
|
||||
});
|
||||
|
||||
$lazyImgList = $("img[data-lazy-src]");
|
||||
|
||||
checkOffset();
|
||||
|
||||
// Debounced scroll handler could be better, but sticking to simple binding for now
|
||||
$(window).off("scroll.lazy").on("scroll.lazy resize.lazy", function() {
|
||||
checkOffset();
|
||||
});
|
||||
}
|
||||
|
||||
function tryAgain() {
|
||||
// Re-initialize for new content
|
||||
init(defaults);
|
||||
}
|
||||
|
||||
window.lazyLoadInit = init;
|
||||
window.lazyLoadAgain = tryAgain;
|
||||
|
||||
})(jQuery);
|
||||
+19
-185
@@ -1,190 +1,24 @@
|
||||
// 判断是否为移动端
|
||||
function isMobile() {
|
||||
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端
|
||||
}
|
||||
}
|
||||
|
||||
// 文章图片灯箱
|
||||
window.ViewImage && ViewImage.init('.post-content img');
|
||||
|
||||
// Pure JavaScript Back to Top (High Performance)
|
||||
// Initial Call
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var backToTopButton = document.getElementById('back-to-top');
|
||||
if (backToTopButton) {
|
||||
var isVisible = false;
|
||||
var ticking = false;
|
||||
// 文章图片灯箱
|
||||
if (window.ViewImage) {
|
||||
ViewImage.init('.post-content img');
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (window.scrollY > 300) {
|
||||
if (!isVisible) {
|
||||
backToTopButton.classList.add('show');
|
||||
isVisible = true;
|
||||
}
|
||||
} else {
|
||||
if (isVisible) {
|
||||
backToTopButton.classList.remove('show');
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', function() {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(update);
|
||||
ticking = true;
|
||||
}
|
||||
}, { passive: true });
|
||||
|
||||
backToTopButton.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
// 初始化各个模块
|
||||
if (window.initLoader) window.initLoader();
|
||||
if (window.initFloatingTools) window.initFloatingTools();
|
||||
if (window.initSearch) window.initSearch();
|
||||
if (window.initArtalk) window.initArtalk();
|
||||
|
||||
// 文章图片懒加载
|
||||
if (typeof lazyLoadInit === 'function') {
|
||||
lazyLoadInit({
|
||||
offsetBottom: 800,
|
||||
offsetTopm: 800,
|
||||
showTime: 1100
|
||||
});
|
||||
} else {
|
||||
console.warn('lazyLoadInit is not defined');
|
||||
}
|
||||
});
|
||||
|
||||
// loader定时器
|
||||
$(document).ready(function () {
|
||||
setTimeout(function () {
|
||||
$("#loader").addClass("hide");
|
||||
}, 30000);
|
||||
});
|
||||
|
||||
|
||||
// 点击进入按钮
|
||||
$("#closeloader").click(function () {
|
||||
$("#loader").addClass("hide");
|
||||
});
|
||||
// nav栏样式调整
|
||||
$('#libabys').first().attr("style", "margin-left: -5px");
|
||||
|
||||
$('#libabys').eq(1).attr("style", "margin-left: -5px");
|
||||
// 友链列表版样式调整
|
||||
$('.itp-index:odd').attr("style", "float: right;width:48%;");
|
||||
|
||||
//文章图片懒加载
|
||||
if (typeof lazyLoadInit === 'function') {
|
||||
lazyLoadInit({
|
||||
// coverColor: "white",
|
||||
// coverDiv: "<div style='display: flex; justify-content: center; align-items: center; height: 200px; color: #000000;'><span>优世界·一个记录生活点滴的小站</span></div>",
|
||||
offsetBottom: 800,
|
||||
offsetTopm: 800,
|
||||
showTime: 1100
|
||||
});
|
||||
} else {
|
||||
console.warn('lazyLoadInit is not defined');
|
||||
}
|
||||
|
||||
|
||||
// 异步初始化 Artalk 并获取评论数据 (Moved to barrage.js)
|
||||
|
||||
// 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...');
|
||||
// Optional: Retry logic could be added here if needed, but usually bundle is loaded by now
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if Artalk is already initialized on this container to avoid duplicates
|
||||
// But Artalk.init usually handles this or we create a new instance.
|
||||
// Since we want to re-bind to the new DOM after PJAX, we create a new instance.
|
||||
|
||||
// Clean up previous instance if needed? Artalk doesn't strictly require explicit destroy if DOM is removed,
|
||||
// but it's good practice. For now, we assume simple re-init is fine.
|
||||
|
||||
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 (Avatar, Nickname, Main Content)
|
||||
// Note: We already added attributes to AI comment above, but this loop ensures all other comments get it too.
|
||||
// Duplicate attributes on AI comment are harmless or we can skip it.
|
||||
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'); // Add class if your lazyloader needs it
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger lazy load update
|
||||
// Assuming window.lazyLoadInstance is available or using the global function
|
||||
if (window.lazyLoadAgain) {
|
||||
window.lazyLoadAgain();
|
||||
}
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.error('Artalk init failed:', e);
|
||||
}
|
||||
};
|
||||
@@ -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' });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
})();
|
||||
@@ -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');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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端
|
||||
}
|
||||
};
|
||||
@@ -1,26 +1,55 @@
|
||||
// 定义pjax 预设pjax
|
||||
var pjax = new Pjax({
|
||||
// 这里填写页面中改变的部分(和 CSS 选择器用法一样)
|
||||
selectors: ["title", "#pjax-container"],
|
||||
cacheBust: false,
|
||||
elements: "a"
|
||||
// 移除 sideBySide,改用默认替换以配合骨架屏逻辑
|
||||
});
|
||||
// 设置图片灯箱回调函数
|
||||
// Removed redundant lazyimg_pjax definition as EasyLazyload.min.js handles it globally now
|
||||
(function() {
|
||||
if (typeof Pjax === 'undefined') {
|
||||
console.error('Pjax library is not loaded.');
|
||||
return;
|
||||
}
|
||||
|
||||
var pjax = new Pjax({
|
||||
// 这里填写页面中改变的部分(和 CSS 选择器用法一样)
|
||||
selectors: ["title", "#pjax-container"],
|
||||
cacheBust: false,
|
||||
elements: "a", // 拦截所有链接
|
||||
switches: {
|
||||
"#pjax-container": Pjax.switches.default
|
||||
}
|
||||
});
|
||||
|
||||
// 将 pjax 实例挂载到 window 以便调试或外部访问
|
||||
window.pjax = pjax;
|
||||
|
||||
console.log("Pjax initialized:", pjax);
|
||||
})();
|
||||
|
||||
// pjax预先加载代码
|
||||
function pjax_reload() {
|
||||
console.log("Pjax reload triggered");
|
||||
// 给pjax容器加入css过渡动画
|
||||
// $("#pjax-container").addClass("uk-animation-slide-bottom-small");
|
||||
// var pjaxContainer = document.getElementById("pjax-container");
|
||||
// if (pjaxContainer) pjaxContainer.classList.add("uk-animation-slide-bottom-small");
|
||||
|
||||
// 评论区过渡动画
|
||||
$(".comment-meta").attr("uk-scrollspy", "cls: uk-animation-fade; delay: 100");
|
||||
$(".comment-author vcard").attr("uk-scrollspy", "cls: uk-animation-fade; delay: 100");
|
||||
$(".comment-metadata").attr("uk-scrollspy", "cls: uk-animation-fade; delay: 100");
|
||||
$(".comment-content").attr("uk-scrollspy", "cls: uk-animation-fade; delay: 100");
|
||||
$(".reply").attr("uk-scrollspy", "cls: uk-animation-fade; delay: 100");
|
||||
var selectors = [
|
||||
".comment-meta",
|
||||
".comment-author vcard",
|
||||
".comment-metadata",
|
||||
".comment-content",
|
||||
".reply"
|
||||
];
|
||||
|
||||
selectors.forEach(function(selector) {
|
||||
document.querySelectorAll(selector).forEach(function(el) {
|
||||
el.setAttribute("uk-scrollspy", "cls: uk-animation-fade; delay: 100");
|
||||
});
|
||||
});
|
||||
|
||||
// 说说页面过渡动画
|
||||
$("#shuoshuo_body").attr("uk-scrollspy", "target: > .shuoshuo; cls: uk-animation-fade; delay: 250");
|
||||
var shuoshuoBody = document.getElementById("shuoshuo_body");
|
||||
if (shuoshuoBody) {
|
||||
shuoshuoBody.setAttribute("uk-scrollspy", "target: > .shuoshuo; cls: uk-animation-fade; delay: 250");
|
||||
}
|
||||
}
|
||||
|
||||
// pjax发送时期
|
||||
document.addEventListener("pjax:send", function () {
|
||||
// pjax动画减少圆圈动画
|
||||
@@ -30,43 +59,57 @@ document.addEventListener("pjax:send", function () {
|
||||
// pjax执行动画开始
|
||||
NProgress.start(); //加载动画效果开始
|
||||
});
|
||||
|
||||
// Pjax 成功后,重新加载下面的函数
|
||||
document.addEventListener("pjax:success", function () {
|
||||
// 重载图片懒加载插件的js
|
||||
lazyLoadInit({
|
||||
// coverColor: "white",
|
||||
// coverDiv: "<div style='display: flex; justify-content: center; align-items: center; height: 200px; color: #000000;'><span>优世界·一个记录生活点滴的小站</span></div>",
|
||||
offsetBottom: 800,
|
||||
offsetTopm: 800,
|
||||
showTime: 1100
|
||||
});
|
||||
if (typeof lazyLoadInit === 'function') {
|
||||
lazyLoadInit({
|
||||
// coverColor: "white",
|
||||
// coverDiv: "<div style='display: flex; justify-content: center; align-items: center; height: 200px; color: #000000;'><span>优世界·一个记录生活点滴的小站</span></div>",
|
||||
offsetBottom: 800,
|
||||
offsetTopm: 800,
|
||||
showTime: 1100
|
||||
});
|
||||
}
|
||||
// 激活文章图片灯箱
|
||||
window.ViewImage && ViewImage.init('.post-content img');
|
||||
if (window.ViewImage) {
|
||||
ViewImage.init('.post-content img');
|
||||
}
|
||||
});
|
||||
|
||||
// pjax加载完成
|
||||
document.addEventListener("pjax:complete", function () {
|
||||
// pjax完成动画
|
||||
NProgress.done();
|
||||
if (typeof NProgress !== 'undefined') {
|
||||
NProgress.done();
|
||||
}
|
||||
|
||||
// 重载一些js样式调整
|
||||
pjax_reload()
|
||||
pjax_reload();
|
||||
|
||||
// 初始化代码复制
|
||||
initCodeCopy()
|
||||
if (typeof initCodeCopy === 'function') initCodeCopy();
|
||||
|
||||
// 初始化代码折叠
|
||||
initCodeFold()
|
||||
if (typeof initCodeFold === 'function') initCodeFold();
|
||||
|
||||
// 初始化友链状态
|
||||
if (typeof window.initLinkStatus === 'function') {
|
||||
window.initLinkStatus();
|
||||
}
|
||||
|
||||
// 重载评论
|
||||
if (typeof window.initArtalk === 'function') {
|
||||
window.initArtalk();
|
||||
}
|
||||
|
||||
// 重载不蒜子统计
|
||||
if (typeof window.bsz_fetch === 'function') {
|
||||
window.bsz_fetch();
|
||||
}
|
||||
|
||||
// 重载 Search 和 Floating Tools (Moved from main.js)
|
||||
if (typeof window.initFloatingTools === 'function') window.initFloatingTools();
|
||||
if (typeof window.initSearch === 'function') window.initSearch();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user