// 判断是否为移动端 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端 } }; // Toast Message Helper window.showToast = function(text, type) { if (window.Toast) { var t = type || 'info'; if (typeof window.Toast[t] === 'function') { window.Toast[t](text); } else { window.Toast.info(text); } } }; // Theme Toggle Logic window.initThemeToggle = function() { const avatar = document.getElementById('theme-toggle-avatar'); if (!avatar) return; // Remove existing listeners to avoid duplicates (if any) const newAvatar = avatar.cloneNode(true); avatar.parentNode.replaceChild(newAvatar, avatar); newAvatar.addEventListener('click', function(e) { e.preventDefault(); var html = document.documentElement; var currentTheme = html.getAttribute('data-theme'); var newTheme = currentTheme === 'dark' ? 'light' : 'dark'; var apply = function() { html.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); window.showToast('已切换至 ' + (newTheme === 'dark' ? '深色' : '浅色') + '模式', 'success'); if (window.artalk && typeof window.artalk.setDarkMode === 'function') { window.artalk.setDarkMode(newTheme === 'dark'); } window.dispatchEvent(new Event('resize')); }; if (document.startViewTransition) { document.startViewTransition(function() { apply(); }); } else { apply(); } }); }; // Code Folding Logic window.initCodeFold = function() { const codeBlocks = document.querySelectorAll('.highlight'); codeBlocks.forEach(block => { // Check height (approx 300px) if (block.offsetHeight > 360) { // Check if already processed if (block.parentNode.classList.contains('code-fold-container')) return; // Wrap const wrapper = document.createElement('div'); wrapper.className = 'code-fold-container collapsed'; block.parentNode.insertBefore(wrapper, block); wrapper.appendChild(block); // Add Button const btn = document.createElement('button'); btn.className = 'code-expand-btn'; btn.innerHTML = ' 展开代码 '; btn.onclick = function() { wrapper.classList.remove('collapsed'); // Hide button after expand, or change to collapse? // Usually just expand is enough. btn.style.display = 'none'; }; wrapper.appendChild(btn); } }); }; // Code Copy Logic window.initCodeCopy = function() { // Target pre tags that contain code, or .highlight containers const codeBlocks = document.querySelectorAll('pre'); codeBlocks.forEach(pre => { // Avoid double init if (pre.parentNode.querySelector('.copy-code-btn')) return; if (pre.querySelector('.copy-code-btn')) return; // Check if it's inside a highlight block (Hugo usually does .highlight > pre) // We attach button to the pre or the highlight container? // Attaching to pre is safer for positioning. const btn = document.createElement('button'); btn.className = 'copy-code-btn'; btn.innerHTML = ''; btn.title = "复制代码"; btn.style.cssText = ` position: absolute; top: -6px; right: 5px; background: transparent; border: none; color: #888; cursor: pointer; padding: 5px; border-radius: 4px; transition: all 0.2s; opacity: 0; z-index: 10; `; // Show on hover pre.addEventListener('mouseenter', () => btn.style.opacity = '1'); pre.addEventListener('mouseleave', () => btn.style.opacity = '0'); // Handle touch devices if (window.isMobile()) { btn.style.opacity = '1'; } btn.addEventListener('click', (e) => { e.stopPropagation(); const code = pre.querySelector('code') ? pre.querySelector('code').innerText : pre.innerText; if (navigator.clipboard) { navigator.clipboard.writeText(code).then(() => { window.showToast('代码已复制 / Copied!', 'success'); btn.innerHTML = ''; setTimeout(() => btn.innerHTML = '', 2000); }).catch(err => { console.error('Copy failed', err); window.showToast('复制失败 / Failed', 'error'); }); } else { // Fallback const textarea = document.createElement('textarea'); textarea.value = code; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); window.showToast('代码已复制 / Copied!', 'success'); } }); // Ensure relative positioning if (getComputedStyle(pre).position === 'static') { pre.style.position = 'relative'; } pre.appendChild(btn); }); };