| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // plugins/smart-flexible.client.js
- class ResponsiveAdapter {
- constructor() {
- this.isMobile = this.checkMobile()
- this.init()
- }
-
- checkMobile() {
- const ua = navigator.userAgent.toLowerCase()
- const mobileKeywords = [
- 'iphone', 'ipod', 'android.*mobile',
- 'windows.*phone', 'blackberry.*mobile',
- 'mobile', 'tablet'
- ]
-
- const isMobileUA = mobileKeywords.some(keyword =>
- new RegExp(keyword).test(ua)
- )
-
- const screenWidth = window.innerWidth
- const isSmallScreen = screenWidth <= 768
-
- return isMobileUA || isSmallScreen
- }
-
- init() {
- const docEl = document.documentElement
-
- if (this.isMobile) {
- // 移动端逻辑
- this.initMobile(docEl)
- } else {
- // PC 端逻辑
- this.initPC(docEl)
- }
-
- // 添加设备标识类
- this.addDeviceClass(docEl)
-
- // 监听窗口变化
- window.addEventListener('resize', () => {
- this.handleResize(docEl)
- })
- }
-
- initMobile(docEl) {
- const dpr = window.devicePixelRatio || 1
-
- // 设置 viewport meta
- this.setViewport(dpr)
-
- // 设置 rem
- const setRem = () => {
- const rem = docEl.clientWidth / 10
- docEl.style.fontSize = rem + 'px'
- }
-
- setRem()
- window.addEventListener('resize', setRem)
-
- // 存储方法供外部调用
- this.setRem = setRem
- }
-
- initPC(docEl) {
- // PC 端使用响应式 rem
- const setPCRem = () => {
- const width = docEl.clientWidth
-
- // 响应式断点
- let fontSize
- if (width >= 1920) {
- fontSize = 192 // 1920/10
- } else if (width >= 1600) {
- fontSize = 160 // 1600/10
- } else if (width >= 1440) {
- fontSize = 144 // 1440/10
- } else if (width >= 1366) {
- fontSize = 136.6 // 1366/10
- } else if (width >= 1200) {
- fontSize = 120 // 1200/10
- } else {
- fontSize = 100 // 小于1200时的基准
- }
-
- docEl.style.fontSize = fontSize + 'px'
- }
-
- setPCRem()
- window.addEventListener('resize', setPCRem)
-
- this.setPCRem = setPCRem
- }
-
- setViewport(dpr) {
- let viewport = document.querySelector('meta[name="viewport"]')
- if (!viewport) {
- viewport = document.createElement('meta')
- viewport.name = 'viewport'
- document.head.appendChild(viewport)
- }
-
- if (this.isMobile) {
- viewport.content = `width=device-width, initial-scale=${1/dpr}, maximum-scale=${1/dpr}, minimum-scale=${1/dpr}, user-scalable=no`
- } else {
- viewport.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'
- }
- }
-
- addDeviceClass(docEl) {
- docEl.classList.remove('is-pc', 'is-mobile')
- docEl.classList.add(this.isMobile ? 'is-mobile' : 'is-pc')
- }
-
- handleResize(docEl) {
- const wasMobile = this.isMobile
- this.isMobile = this.checkMobile()
-
- if (wasMobile !== this.isMobile) {
- // 设备类型发生变化
- this.addDeviceClass(docEl)
- if (this.isMobile) {
- this.initMobile(docEl)
- } else {
- this.initPC(docEl)
- }
- } else {
- // 同设备类型,只更新 rem
- if (this.isMobile && this.setRem) {
- this.setRem()
- } else if (!this.isMobile && this.setPCRem) {
- this.setPCRem()
- }
- }
- }
- }
-
- // 初始化
- export default defineNuxtPlugin(() => {
- if (process.client) {
- new ResponsiveAdapter()
- }
- })
|