// 移动端优化组件
(function() {
let isMobile = false;
let isTablet = false;
let currentOrientation = 'portrait';
// 检测设备类型
function detectDevice() {
const userAgent = navigator.userAgent.toLowerCase();
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
// 检测是否为移动设备
isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent) || screenWidth <= 768;
isTablet = /ipad|android(?!.*mobile)|tablet/i.test(userAgent) || (screenWidth > 768 && screenWidth <= 1024);
// 检测屏幕方向
currentOrientation = screenWidth > screenHeight ? 'landscape' : 'portrait';
// 添加设备类到body(确保body存在)
if (document.body) {
document.body.classList.remove('mobile', 'tablet', 'desktop', 'portrait', 'landscape');
document.body.classList.add(
isMobile ? 'mobile' : isTablet ? 'tablet' : 'desktop',
currentOrientation
);
}
return { isMobile, isTablet, currentOrientation };
}
// 添加移动端优化样式
function addMobileStyles() {
const style = document.createElement('style');
style.textContent = `
/* 移动端基础优化 */
* {
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* 允许文本选择 */
p, h1, h2, h3, h4, h5, h6, span, div, article, section {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
/* 移动端滚动优化 */
html {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* 移动端字体优化 */
body.mobile {
font-size: 16px; /* 防止iOS缩放 */
line-height: 1.6;
-webkit-text-size-adjust: 100%;
-moz-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
/* 移动端容器优化 */
.container {
padding-left: 1rem;
padding-right: 1rem;
}
body.mobile .container {
padding-left: 1rem;
padding-right: 1rem;
}
body.tablet .container {
padding-left: 2rem;
padding-right: 2rem;
}
/* 移动端导航优化 */
body.mobile #navbar {
padding: 0.75rem 1rem;
}
body.mobile .nav-container {
padding: 0.75rem 0;
}
/* 移动端按钮优化 */
body.mobile button,
body.mobile .btn {
min-height: 44px; /* iOS推荐的最小触摸目标 */
padding: 0.75rem 1.5rem;
font-size: 1rem;
}
/* 移动端表单优化 */
body.mobile input,
body.mobile textarea,
body.mobile select {
min-height: 44px;
padding: 0.75rem;
font-size: 16px; /* 防止iOS缩放 */
border-radius: 8px;
}
/* 移动端卡片优化 */
body.mobile .card,
body.mobile .glass-card {
margin-bottom: 1rem;
padding: 1rem;
border-radius: 12px;
}
/* 移动端文字优化 */
body.mobile h1 {
font-size: 2rem;
line-height: 1.2;
margin-bottom: 1rem;
}
body.mobile h2 {
font-size: 1.75rem;
line-height: 1.3;
margin-bottom: 0.75rem;
}
body.mobile h3 {
font-size: 1.5rem;
line-height: 1.4;
margin-bottom: 0.5rem;
}
body.mobile p {
font-size: 1rem;
line-height: 1.6;
margin-bottom: 1rem;
}
/* 移动端网格优化 */
body.mobile .grid {
grid-template-columns: 1fr;
gap: 1rem;
}
body.mobile .grid-cols-2,
body.mobile .grid-cols-3,
body.mobile .grid-cols-4,
body.mobile .md\\:grid-cols-2,
body.mobile .md\\:grid-cols-3,
body.mobile .lg\\:grid-cols-3 {
grid-template-columns: 1fr;
}
/* 平板端网格优化 */
body.tablet .grid-cols-3,
body.tablet .lg\\:grid-cols-3 {
grid-template-columns: repeat(2, 1fr);
}
/* 移动端间距优化 */
body.mobile .py-16 { padding-top: 3rem; padding-bottom: 3rem; }
body.mobile .py-12 { padding-top: 2rem; padding-bottom: 2rem; }
body.mobile .py-8 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
body.mobile .mb-12 { margin-bottom: 2rem; }
body.mobile .mb-8 { margin-bottom: 1.5rem; }
/* 移动端图片优化 */
body.mobile img {
max-width: 100%;
height: auto;
border-radius: 8px;
}
/* 横屏优化 */
body.mobile.landscape {
/* 横屏时减少垂直间距 */
}
body.mobile.landscape .py-16 {
padding-top: 2rem;
padding-bottom: 2rem;
}
body.mobile.landscape h1 {
font-size: 1.75rem;
margin-bottom: 0.75rem;
}
/* 移动端返回顶部按钮优化 */
body.mobile #back-to-top {
bottom: 1.5rem;
right: 1.5rem;
}
body.mobile .back-to-top-btn {
width: 3rem;
height: 3rem;
}
/* 移动端页面加载器优化 */
body.mobile #page-loader .w-20 {
width: 4rem;
height: 4rem;
}
body.mobile #page-loader h1 {
font-size: 1.25rem;
}
body.mobile #page-loader .w-64 {
width: 16rem;
}
/* 防止页面缩放 */
@media screen and (max-width: 768px) {
html {
zoom: 1;
-ms-zoom: 1;
-webkit-zoom: 1;
-moz-zoom: 1;
}
}
/* 触摸设备特定优化 */
@media (hover: none) and (pointer: coarse) {
/* 移除hover效果,使用active效果 */
.hover\\:scale-110:hover {
transform: none;
}
.hover\\:scale-110:active {
transform: scale(1.05);
}
.hover\\:shadow-xl:hover {
box-shadow: none;
}
.hover\\:shadow-xl:active {
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
}
/* 安全区域适配(iPhone X等带刘海屏的设备) */
@supports (padding: max(0px)) {
body.mobile {
padding-left: max(1rem, env(safe-area-inset-left));
padding-right: max(1rem, env(safe-area-inset-right));
}
body.mobile #navbar {
padding-left: max(1rem, env(safe-area-inset-left));
padding-right: max(1rem, env(safe-area-inset-right));
padding-top: max(0.75rem, env(safe-area-inset-top));
}
body.mobile #back-to-top {
right: max(1.5rem, env(safe-area-inset-right));
bottom: max(1.5rem, env(safe-area-inset-bottom));
}
}
`;
document.head.appendChild(style);
}
// 优化图片加载
function optimizeImages() {
const images = document.querySelectorAll('img');
images.forEach(img => {
// 添加懒加载
if (!img.loading) {
img.loading = 'lazy';
}
// 添加错误处理
img.addEventListener('error', function() {
this.style.display = 'none';
});
// 移动端图片优化
if (isMobile) {
// 移动端使用较小的图片
const src = img.src;
if (src && !src.includes('placeholder')) {
// 这里可以添加图片压缩逻辑
}
}
});
}
// 优化触摸事件
function optimizeTouch() {
// 添加触摸反馈
document.addEventListener('touchstart', function(e) {
const target = e.target;
if (target.tagName === 'BUTTON' || target.classList.contains('btn') || target.tagName === 'A') {
target.style.opacity = '0.7';
}
}, { passive: true });
document.addEventListener('touchend', function(e) {
const target = e.target;
if (target.tagName === 'BUTTON' || target.classList.contains('btn') || target.tagName === 'A') {
setTimeout(() => {
target.style.opacity = '';
}, 150);
}
}, { passive: true });
// 防止双击缩放
let lastTouchEnd = 0;
document.addEventListener('touchend', function(event) {
const now = (new Date()).getTime();
if (now - lastTouchEnd <= 300) {
event.preventDefault();
}
lastTouchEnd = now;
}, false);
}
// 处理屏幕方向变化
function handleOrientationChange() {
// 延迟执行以确保尺寸更新
setTimeout(() => {
detectDevice();
// 重新计算布局
const event = new Event('resize');
window.dispatchEvent(event);
// 滚动到顶部(防止方向变化后位置错乱)
if (window.scrollY > 100) {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
}, 100);
}
// 优化键盘弹出时的布局
function handleKeyboard() {
if (!isMobile) return;
const originalHeight = window.innerHeight;
let keyboardOpen = false;
window.addEventListener('resize', function() {
const currentHeight = window.innerHeight;
const heightDifference = originalHeight - currentHeight;
// 键盘弹出(高度减少超过150px)
if (heightDifference > 150 && !keyboardOpen) {
keyboardOpen = true;
document.body.classList.add('keyboard-open');
// 隐藏导航栏(为输入框腾出空间)
const navbar = document.getElementById('navbar');
if (navbar) {
navbar.style.transform = 'translateY(-100%)';
}
// 隐藏返回顶部按钮
const backToTop = document.getElementById('back-to-top');
if (backToTop) {
backToTop.style.display = 'none';
}
}
// 键盘收起
else if (heightDifference <= 150 && keyboardOpen) {
keyboardOpen = false;
document.body.classList.remove('keyboard-open');
// 恢复导航栏
const navbar = document.getElementById('navbar');
if (navbar) {
navbar.style.transform = '';
}
// 恢复返回顶部按钮
const backToTop = document.getElementById('back-to-top');
if (backToTop) {
backToTop.style.display = '';
}
}
});
}
// 性能优化
function optimizePerformance() {
// 使用 Intersection Observer 优化动画
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-visible');
}
});
}, {
threshold: 0.1,
rootMargin: '50px'
});
// 观察所有动画元素
document.querySelectorAll('[class*="animate-"]').forEach(el => {
if (!el.classList.contains('animate-visible')) {
observer.observe(el);
}
});
}
// 移动端减少动画
if (isMobile) {
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
if (mediaQuery.matches) {
document.body.classList.add('reduce-motion');
}
}
}
// 添加调试信息(开发环境)
function addDebugInfo() {
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
const debugInfo = document.createElement('div');
debugInfo.style.cssText = `
position: fixed;
top: 70px;
right: 10px;
background: rgba(0,0,0,0.8);
color: white;
padding: 8px;
border-radius: 4px;
font-size: 12px;
z-index: 10000;
font-family: monospace;
`;
function updateDebugInfo() {
const { isMobile, isTablet, currentOrientation } = detectDevice();
debugInfo.innerHTML = `
${window.innerWidth}×${window.innerHeight}
${isMobile ? 'Mobile' : isTablet ? 'Tablet' : 'Desktop'}
${currentOrientation}
`;
}
updateDebugInfo();
document.body.appendChild(debugInfo);
window.addEventListener('resize', updateDebugInfo);
window.addEventListener('orientationchange', updateDebugInfo);
}
}
// 初始化移动端优化
function init() {
// 检测设备类型
detectDevice();
// 添加移动端样式
addMobileStyles();
// 优化触摸体验
optimizeTouch();
// 处理屏幕方向变化
window.addEventListener('orientationchange', handleOrientationChange);
window.addEventListener('resize', () => {
setTimeout(detectDevice, 100);
});
// 页面加载完成后的优化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
optimizeImages();
handleKeyboard();
optimizePerformance();
addDebugInfo();
}, 500);
});
} else {
setTimeout(() => {
optimizeImages();
handleKeyboard();
optimizePerformance();
addDebugInfo();
}, 500);
}
// 监听页面加载完成事件
document.addEventListener('pageLoaded', () => {
setTimeout(() => {
optimizeImages();
optimizePerformance();
}, 100);
});
}
// 提供外部接口
window.MobileOptimize = {
detectDevice,
isMobile: () => isMobile,
isTablet: () => isTablet,
getCurrentOrientation: () => currentOrientation,
optimizeImages,
optimizePerformance
};
// 初始化
init();
})();