116 lines
2.8 KiB
JavaScript
116 lines
2.8 KiB
JavaScript
/**
|
||
* 简化版缩放适配工具
|
||
*/
|
||
class ZoomAdapter {
|
||
constructor() {
|
||
// ===== 可调整的配置参数 =====
|
||
this.maxZoom = 3 // 触发调整的缩放阈值(默认3倍)
|
||
this.targetZoom = 2 // 调整后的目标缩放(默认2倍)
|
||
this.isInitialized = false
|
||
}
|
||
|
||
init() {
|
||
if (typeof window === 'undefined' || typeof document === 'undefined')
|
||
return
|
||
if (this.isInitialized)
|
||
return
|
||
|
||
// 绑定事件
|
||
window.addEventListener('resize', () => this.checkZoom())
|
||
window.addEventListener('orientationchange', () => {
|
||
setTimeout(() => this.checkZoom(), 500)
|
||
})
|
||
|
||
// 防止双击缩放
|
||
let lastTouchEnd = 0
|
||
document.addEventListener('touchend', (event) => {
|
||
const now = Date.now()
|
||
if (now - lastTouchEnd <= 300) {
|
||
event.preventDefault()
|
||
}
|
||
lastTouchEnd = now
|
||
}, false)
|
||
|
||
this.checkZoom()
|
||
this.isInitialized = true
|
||
}
|
||
|
||
getCurrentZoom() {
|
||
return Math.max(
|
||
window.outerWidth / window.innerWidth,
|
||
window.devicePixelRatio,
|
||
window.screen.width / window.innerWidth,
|
||
)
|
||
}
|
||
|
||
checkZoom() {
|
||
const zoom = this.getCurrentZoom()
|
||
|
||
if (zoom > this.maxZoom) {
|
||
this.adjust(zoom)
|
||
}
|
||
else {
|
||
this.reset()
|
||
}
|
||
}
|
||
|
||
adjust(zoom) {
|
||
try {
|
||
// 计算调整比例:目标缩放 / 当前缩放
|
||
const ratio = this.targetZoom / zoom
|
||
|
||
// 应用调整
|
||
document.body.style.transform = `scale(${ratio})`
|
||
document.body.style.transformOrigin = 'top left'
|
||
document.body.style.width = `${100 / ratio}%`
|
||
document.body.style.height = `${100 / ratio}%`
|
||
}
|
||
catch (e) {
|
||
console.warn('缩放调整失败:', e)
|
||
}
|
||
}
|
||
|
||
reset() {
|
||
try {
|
||
document.body.style.transform = ''
|
||
document.body.style.transformOrigin = ''
|
||
document.body.style.width = ''
|
||
document.body.style.height = ''
|
||
}
|
||
catch (e) {
|
||
console.warn('缩放重置失败:', e)
|
||
}
|
||
}
|
||
|
||
addZoomStyles() {
|
||
const style = document.createElement('style')
|
||
style.id = 'zoom-adapter-styles'
|
||
style.textContent = `
|
||
.zoom-adaptive {
|
||
font-size: 16px !important;
|
||
line-height: 1.5 !important;
|
||
}
|
||
.zoom-adaptive input,
|
||
.zoom-adaptive button,
|
||
.zoom-adaptive select,
|
||
.zoom-adaptive textarea {
|
||
font-size: 16px !important;
|
||
min-height: 44px !important;
|
||
padding: 8px 12px !important;
|
||
}
|
||
.zoom-adaptive img {
|
||
max-width: 100% !important;
|
||
height: auto !important;
|
||
}
|
||
.zoom-adaptive table {
|
||
max-width: 100% !important;
|
||
overflow-x: auto !important;
|
||
}
|
||
`
|
||
document.head.appendChild(style)
|
||
}
|
||
}
|
||
|
||
export default new ZoomAdapter()
|
||
export { ZoomAdapter }
|