博客UI优化之旅:打造个性化Hexo博客 在搭建个人博客的过程中,除了内容的质量,博客的视觉体验同样重要。一个精心设计的UI不仅能提升用户体验,还能彰显个人品味。本文将分享我在优化Hexo博客UI过程中的经验和技巧,希望能为同样热爱折腾的你提供一些启发。
🎨 整体设计理念 在开始具体的优化工作前,我花了不少时间思考博客的整体设计理念。最终,我确定了以下几点:
简约而不简单 :避免过多的视觉干扰,但保留足够的设计细节
响应式设计 :在各种设备上都能提供良好的浏览体验
性能优先 :确保加载速度快,交互流畅
个性化表达 :融入个人风格,与大众博客有所区别
带着这些理念,我开始了一系列的优化工作。
🚀 加载体验优化 自定义加载动画 网站加载时的第一印象非常重要。我设计了一个简洁的巫师加载动画,让等待变得有趣。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 (function ( ) { 'use strict' ; console .log ('🧙♂️ 巫师加载动画修复脚本启动' ); let loadingStartTime = Date .now (); let isLoadingHidden = false ; function smartHideLoading ( ) { if (isLoadingHidden) return ; const loadingBox = document .getElementById ('loading-box' ); if (!loadingBox) return ; const currentTime = Date .now (); const elapsedTime = currentTime - loadingStartTime; const minDisplayTime = 2500 ; if (elapsedTime < minDisplayTime) { const remainingTime = minDisplayTime - elapsedTime; setTimeout (() => { hideLoadingAnimation (); }, remainingTime); } else { hideLoadingAnimation (); } } function hideLoadingAnimation ( ) { if (isLoadingHidden) return ; const loadingBox = document .getElementById ('loading-box' ); if (!loadingBox) return ; isLoadingHidden = true ; loadingBox.classList .add ('loaded' ); document .body .style .overflow = 'auto' ; } })();
这段代码解决了加载动画显示时间过短或过长的问题,确保用户体验的一致性。同时,我还添加了超时保护机制,防止加载动画卡住。
图片懒加载优化 为了加快页面加载速度,我对图片懒加载进行了优化:
1 2 3 4 5 6 lazyload: enable: true field: site placeholder: data:image/svg+xml;base64,... blur: true
这种配置不仅能延迟加载图片,还能在加载前显示模糊的占位图,提供更好的视觉过渡。
🌙 暗色模式增强 暗色模式切换修复 暗色模式是现代网站的标配,但Butterfly主题的暗色模式切换按钮有时会失效。我编写了修复脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 (function ( ) { 'use strict' ; function initDarkmodeFix ( ) { const darkmodeButton = document .getElementById ('darkmode' ); if (!darkmodeButton) return ; const hasClickEvent = darkmodeButton.onclick || darkmodeButton.getAttribute ('onclick' ) || darkmodeButton.hasAttribute ('data-click-bound' ); if (hasClickEvent) return ; darkmodeButton.addEventListener ('click' , function (e ) { e.preventDefault (); e.stopPropagation (); if (typeof btf !== 'undefined' && typeof btf.darkmode === 'function' ) { btf.darkmode (); return ; } const currentTheme = document .documentElement .getAttribute ('data-theme' ); const newTheme = currentTheme === 'dark' ? 'light' : 'dark' ; document .documentElement .setAttribute ('data-theme' , newTheme); try { if (typeof btf !== 'undefined' && btf.saveToLocal ) { btf.saveToLocal .set ('theme' , newTheme, 2 ); } else { localStorage .setItem ('theme' , newTheme); } } catch (error) { console .warn ('保存主题设置失败:' , error); } }); darkmodeButton.setAttribute ('data-click-bound' , 'true' ); } if (document .readyState === 'loading' ) { document .addEventListener ('DOMContentLoaded' , initDarkmodeFix); } else { initDarkmodeFix (); } setTimeout (initDarkmodeFix, 500 ); })();
自定义暗色模式样式 除了修复功能外,我还为暗色模式定制了专属样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [data-theme="dark" ] .nav-search-input { border-color : rgba (255 , 255 , 255 , 0.2 ); background : rgba (0 , 0 , 0 , 0.3 ); color : #fff ; } [data-theme="dark" ] .nav-search-input :focus { border-color : rgba (255 , 255 , 255 , 0.4 ); background : rgba (0 , 0 , 0 , 0.5 ); } [data-theme="dark" ] .nav-search-results { background : #2d3748 ; border : 1px solid #4a5568 ; } [data-theme="dark" ] .nav-search-item { border-bottom-color : #4a5568 ; } [data-theme="dark" ] .nav-search-item :hover { background-color : #4a5568 ; } [data-theme="dark" ] .nav-search-title { color : #e2e8f0 ; } [data-theme="dark" ] .nav-search-content { color : #a0aec0 ; }
这些样式确保了暗色模式下各元素的视觉协调性,提供了更舒适的夜间阅读体验。
🔍 搜索功能增强 导航栏搜索 为了方便用户快速查找内容,我在导航栏添加了搜索功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 (function ( ) { 'use strict' ; let searchData = []; let isDataLoaded = false ; let searchTimeout = null ; function initSearch ( ) { const searchInput = document .getElementById ('nav-search-input' ); const searchResults = document .getElementById ('nav-search-results' ); if (!searchInput || !searchResults) return ; searchInput.addEventListener ('input' , handleInput); searchInput.addEventListener ('focus' , handleFocus); searchInput.addEventListener ('keydown' , handleKeydown); document .addEventListener ('click' , function (e ) { if (!e.target .closest ('.nav-search-container' )) { hideResults (); } }); loadSearchData (); } async function loadSearchData ( ) { try { const response = await fetch ('/search.xml' ); if (!response.ok ) throw new Error ('Failed to fetch search data' ); const xmlText = await response.text (); const parser = new DOMParser (); const xmlDoc = parser.parseFromString (xmlText, 'text/xml' ); const entries = xmlDoc.querySelectorAll ('entry' ); searchData = Array .from (entries).map (entry => ({ title : entry.querySelector ('title' )?.textContent || '' , content : entry.querySelector ('content' )?.textContent ?.replace (/<[^>]+>/g , '' ) || '' , url : entry.querySelector ('url' )?.textContent || '' })); isDataLoaded = true ; } catch (error) { console .warn ('Search data loading failed:' , error); } } })();
搜索历史记录 为了提升用户体验,我还添加了搜索历史记录功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 (function ( ) { 'use strict' ; let searchHistory = []; let isInitialized = false ; setTimeout (initSearchEnhance, 1000 ); function initSearchEnhance ( ) { if (isInitialized) return ; isInitialized = true ; loadSearchHistory (); addKeyboardShortcuts (); enhanceSearchInput (); } function loadSearchHistory ( ) { try { const stored = localStorage .getItem ('blog-search-history' ); searchHistory = stored ? JSON .parse (stored) : []; } catch (e) { searchHistory = []; } } function saveSearchHistory (query ) { if (!query || query.length < 2 ) return ; searchHistory = searchHistory.filter (item => item !== query); searchHistory.unshift (query); searchHistory = searchHistory.slice (0 , 8 ); try { localStorage .setItem ('blog-search-history' , JSON .stringify (searchHistory)); } catch (e) { } } })();
🤖 AI摘要功能 为了让读者快速了解文章内容,我添加了AI摘要功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 (function ( ) { 'use strict' ; if (!document .querySelector ('.post-content' )) return ; setTimeout (initAISummary, 500 ); function initAISummary ( ) { const aiSummaryHTML = ` <div class="ai-summary" id="ai-summary"> <div class="ai-summary-header"> <div class="ai-summary-left"> <div class="ai-summary-icon">AI</div> <h3 class="ai-summary-title">AI摘要</h3> </div> <div class="ai-summary-right"> <span class="ai-summary-badge">智能生成</span> <button class="ai-summary-refresh" onclick="refreshAISummary()"> <i class="fas fa-sync-alt"></i> </button> </div> </div> <div class="ai-summary-content"> <div class="ai-summary-text" id="ai-summary-text"> <div class="loading-dots"> <span></span> <span></span> <span></span> </div> 正在生成摘要... </div> </div> <div class="ai-summary-footer"> <div class="ai-summary-info"> <i class="fas fa-robot"></i> 由AI智能生成 </div> </div> </div> ` ; const postContent = document .querySelector ('.post-content' ); if (postContent) { postContent.insertAdjacentHTML ('beforebegin' , aiSummaryHTML); setTimeout (generateAISummary, 800 ); } } function typeWriter (element, text, speed = 40 ) { element.innerHTML = '' ; let i = 0 ; function type ( ) { if (i < text.length ) { element.innerHTML += text.charAt (i); i++; setTimeout (type, speed); } else { element.innerHTML += '<span class="typing-cursor"></span>' ; } } type (); } })();
这个功能通过分析文章内容,自动生成摘要,并以打字机效果呈现,增加了交互的趣味性。
📊 性能监控 为了持续优化博客性能,我添加了轻量级性能监控:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 (function ( ) { 'use strict' ; const ENABLE_MONITORING = false ; if (!ENABLE_MONITORING ) return ; let performanceData = { pageLoadTime : 0 , domContentLoadedTime : 0 , firstPaintTime : 0 , resourceLoadTime : 0 , jsExecutionTime : 0 }; function monitorPageLoad ( ) { window .addEventListener ('load' , function ( ) { setTimeout (() => { const navigation = performance.getEntriesByType ('navigation' )[0 ]; const paint = performance.getEntriesByType ('paint' ); if (navigation) { performanceData.pageLoadTime = Math .round (navigation.loadEventEnd - navigation.fetchStart ); performanceData.domContentLoadedTime = Math .round (navigation.domContentLoadedEventEnd - navigation.fetchStart ); } if (paint.length > 0 ) { const firstPaint = paint.find (entry => entry.name === 'first-paint' ); if (firstPaint) { performanceData.firstPaintTime = Math .round (firstPaint.startTime ); } } console .group ('🚀 页面性能监控' ); console .log ('页面加载时间:' , performanceData.pageLoadTime + 'ms' ); console .log ('DOM加载时间:' , performanceData.domContentLoadedTime + 'ms' ); console .log ('首次绘制时间:' , performanceData.firstPaintTime + 'ms' ); const rating = getPerformanceRating (performanceData.pageLoadTime ); console .log ('性能评级:' , rating.text , rating.emoji ); console .groupEnd (); }, 100 ); }); } })();
🎨 自定义CSS样式 除了功能性优化,我还添加了大量自定义CSS样式,使博客更具个性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .waline-container { background : rgba (255 , 255 , 255 , 0.95 ); backdrop-filter : blur (20px ); border-radius : 16px ; border : 1px solid rgba (255 , 255 , 255 , 0.3 ); box-shadow : 0 8px 32px rgba (0 , 0 , 0 , 0.1 ); margin : 2rem 0 ; padding : 1.5rem ; transition : all 0.3s ease; } .waline-container :hover { box-shadow : 0 12px 48px rgba (0 , 0 , 0 , 0.15 ); transform : translateY (-2px ); }
这些样式为博客添加了现代感和立体感,提升了整体视觉效果。
📱 响应式设计优化 为了确保在各种设备上的良好体验,我对响应式设计进行了优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @media (max-width : 768px ) { .nav-search-container { display : none; } .waline-container { padding : 1rem !important ; } .wl-avatar { width : 28px !important ; height : 28px !important ; } .wl-head , .wl-content , .wl-meta { padding : 0.5rem !important ; } }
这些样式确保了在移动设备上的良好显示效果,提供了更好的移动端体验。
🔧 配置优化 最后,我对Butterfly主题的配置进行了优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 code_blocks: theme: light macStyle: false height_limit: false word_wrap: false copy: true language: true shrink: false fullpage: false social: fab fa-github: https://github.com/swkajnBruceee || Github || '#24292e' fas fa-envelope: mailto:your-email@example.com || Email || '#4a7dbe' fab fa-twitter: https://twitter.com/ || Twitter || '#00acee' fab fa-telegram: https://t.me/ || Telegram || '#0088cc'
这些配置使博客的功能更加丰富,同时保持了视觉的一致性。
🎁 总结与展望 通过这一系列的UI优化,我的Hexo博客不仅在视觉上更加吸引人,功能上也更加完善。当然,博客优化是一个持续的过程,未来我计划:
进一步优化加载速度 :使用更先进的资源压缩和缓存策略
添加更多交互元素 :如阅读进度条、目录自动展开等
优化SEO :提升博客在搜索引擎中的排名
增强无障碍功能 :让博客对所有用户都友好
希望这篇文章能给你的博客优化之旅带来一些启发。如果你有任何问题或建议,欢迎在评论区留言交流!
本文首发于个人博客,转载请注明出处。 如果你喜欢这篇文章,欢迎分享给更多的人!
BruceLee
With each passing breeze,we exchange gentle greetings
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Bruce's Blog !