【vue hooks】useScreenOrientation-获取屏幕方向并支持低版本系统

为了解决vueuse的useScreenOrientation不支持低版本系统的问题,尤其是ios,索性自己写了个可兼容的版本。

代码

新建一个useScreenOrientation.js文件,代码如下

js 复制代码
import { shallowRef } from "vue";
import { useEventListener, useSupported } from "@vueuse/core";

// TypeScript dropped the inline types for these types in 5.2
// We vendor them here to avoid the dependency

// export type OrientationType = 'portrait-primary' | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary'
// export type OrientationLockType = 'any' | 'natural' | 'landscape' | 'portrait' | 'portrait-primary' | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary'

// export interface ScreenOrientation extends EventTarget {
//   lock: (orientation: OrientationLockType) => Promise<void>
//   unlock: () => void
//   readonly type: OrientationType
//   readonly angle: number
//   addEventListener: (type: 'change', listener: (this: this, ev: Event) => any, useCapture?: boolean) => void
// }

// export interface UseScreenOrientationReturn extends Supportable {
//   orientation: ShallowRef<OrientationType | undefined>
//   angle: ShallowRef<number>
//   lockOrientation: (type: OrientationLockType) => Promise<void>
//   unlockOrientation: () => void
// }

/**
 * Reactive screen orientation
 *
 * @see https://vueuse.org/useScreenOrientation
 *
 * @__NO_SIDE_EFFECTS__
 */
export function useScreenOrientation(options = {}) {
  const isSupported = useSupported(
    () => window && "screen" in window && "orientation" in window.screen
  );

  const screenOrientation = isSupported.value ? window.screen.orientation : {};

  const orientation = shallowRef(screenOrientation.type);
  const angle = shallowRef(screenOrientation.angle || 0);

  const isIOS = /iphone|ipad|ipod/.test(
    navigator.userAgent.toLocaleLowerCase()
  );
  const getLandscape = () => {
    if (isIOS && Object.prototype.hasOwnProperty.call(window, "orientation")) {
      return Math.abs(window.orientation) === 90;
    }
    return window.innerHeight / window.innerWidth < 1;
  };

  if (isSupported.value) {
    // 这部分是原代码
    useEventListener(
      window,
      "orientationchange",
      () => {
        orientation.value = screenOrientation.type;
        angle.value = screenOrientation.angle;
      },
      { passive: true }
    );
  } else {
    // 新增兼容低版本
    const landscapeChange = () => {
      orientation.value = getLandscape()
        ? "landscape-primary"
        : "portrait-primary";
    };
    landscapeChange();
    useEventListener(
      window,
      "orientationchange",
      () => {
        landscapeChange();
      },
      { passive: true }
    );
  }

  const lockOrientation = type => {
    if (isSupported.value && typeof screenOrientation.lock === "function")
      return screenOrientation.lock(type);

    return Promise.reject(new Error("Not supported"));
  };

  const unlockOrientation = () => {
    if (isSupported.value && typeof screenOrientation.unlock === "function")
      screenOrientation.unlock();
  };

  return {
    isSupported,
    orientation,
    angle,
    lockOrientation,
    unlockOrientation
  };
}
相关推荐
程序员Sunday5 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
志尊宝6 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
默_笙6 小时前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
思无邪667 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
福兮说9 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
可乐鸡翅yeah_10 小时前
video.js 集成 hls.js 开发 M3U8 播放器,新手高频踩坑
开发语言·前端·javascript·后端·ecmascript·m3u8·音视频在线播放
用户1179536547811 小时前
TRAE vs Claude Code 性能对比:从代码生成、多文件重构到底层吞吐,谁更适合你的日常开发?
javascript
kill52212 小时前
useRef
前端·javascript·react.js
米多科技12 小时前
我做了一个 3D 虚拟世界基底,在上面再搭 3D 世界或元宇宙,事半功倍
javascript·人工智能·github
霍营_托尼13 小时前
纯前端播 40GB 本地视频?我把浏览器改造成了「磁盘流式」播放器
前端·javascript·音视频开发