Files
ruoyi-vue/src/utils/mobile.js
2026-01-05 18:32:29 +08:00

231 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 移动端工具函数
*/
/**
* 检测是否为移动设备
*/
export function isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||
window.innerWidth < 768
}
/**
* 检测是否为iOS设备
*/
export function isIOS() {
return /iPad|iPhone|iPod/.test(navigator.userAgent)
}
/**
* 检测是否为Android设备
*/
export function isAndroid() {
return /Android/.test(navigator.userAgent)
}
/**
* 获取设备类型
*/
export function getDeviceType() {
if (isMobile()) {
if (isIOS()) return 'ios'
if (isAndroid()) return 'android'
return 'mobile'
}
return 'desktop'
}
/**
* 设置移动端视口
*/
export function setMobileViewport() {
if (isMobile()) {
const viewport = document.querySelector('meta[name="viewport"]')
if (viewport) {
viewport.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=5, minimum-scale=1, user-scalable=yes, viewport-fit=cover')
}
}
}
/**
* 防止iOS双击缩放
*/
export function preventDoubleTapZoom() {
if (isIOS()) {
let lastTouchEnd = 0
document.addEventListener('touchend', (event) => {
const now = Date.now()
if (now - lastTouchEnd <= 300) {
event.preventDefault()
}
lastTouchEnd = now
}, false)
}
}
/**
* 优化移动端滚动
*/
export function optimizeMobileScroll() {
if (isMobile()) {
// 添加平滑滚动
document.documentElement.style.scrollBehavior = 'smooth'
// 优化触摸滚动
const style = document.createElement('style')
style.textContent = `
* {
-webkit-overflow-scrolling: touch;
}
`
document.head.appendChild(style)
}
}
/**
* 设置安全区域适配iOS刘海屏
*/
export function setSafeArea() {
if (isIOS()) {
const style = document.createElement('style')
style.textContent = `
.safe-area-top {
padding-top: env(safe-area-inset-top);
}
.safe-area-bottom {
padding-bottom: env(safe-area-inset-bottom);
}
.safe-area-left {
padding-left: env(safe-area-inset-left);
}
.safe-area-right {
padding-right: env(safe-area-inset-right);
}
`
document.head.appendChild(style)
}
}
/**
* 移动端初始化
*/
export function initMobile() {
setMobileViewport()
preventDoubleTapZoom()
optimizeMobileScroll()
setSafeArea()
}
/**
* 格式化移动端表格数据为卡片数据
*/
export function formatTableToCards(tableData, columns) {
return tableData.map(row => {
const card = {}
columns.forEach(column => {
if (column.visible !== false) {
const value = column.prop ? getNestedValue(row, column.prop) : ''
card[column.prop || column.key] = {
label: column.label,
value: column.formatter ? column.formatter(row, column, value) : value,
type: column.type || 'text'
}
}
})
return {
...row,
_cardData: card
}
})
}
/**
* 获取嵌套对象值
*/
function getNestedValue(obj, path) {
return path.split('.').reduce((o, p) => o && o[p], obj)
}
/**
* 移动端表格列配置
*/
export function getMobileTableColumns(columns) {
return columns
.filter(col => col.visible !== false)
.map(col => ({
...col,
label: col.label || col.prop,
prop: col.prop || col.key
}))
}
/**
* 防抖函数
*/
export function debounce(func, wait) {
let timeout
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout)
func(...args)
}
clearTimeout(timeout)
timeout = setTimeout(later, wait)
}
}
/**
* 节流函数
*/
export function throttle(func, limit) {
let inThrottle
return function(...args) {
if (!inThrottle) {
func.apply(this, args)
inThrottle = true
setTimeout(() => inThrottle = false, limit)
}
}
}
/**
* 移动端图片懒加载
*/
export function lazyLoadImages() {
if ('IntersectionObserver' in window) {
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target
img.src = img.dataset.src
img.classList.remove('lazy')
imageObserver.unobserve(img)
}
})
})
document.querySelectorAll('img.lazy').forEach(img => {
imageObserver.observe(img)
})
}
}
export default {
isMobile,
isIOS,
isAndroid,
getDeviceType,
setMobileViewport,
preventDoubleTapZoom,
optimizeMobileScroll,
setSafeArea,
initMobile,
formatTableToCards,
getMobileTableColumns,
debounce,
throttle,
lazyLoadImages
}