【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
  };
}
相关推荐
To_OC5 小时前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC5 小时前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
天渺工作室6 小时前
实现一个adblock/adblock plus等浏览器广告拦截器检测插件
前端·javascript
ZhengEnCi6 小时前
Q04-Vite禁用CSS代码分割-解决生产环境样式加载顺序混乱问题
前端·vue.js·vite
kyriewen13 小时前
2026 年了,还在用 Node.js?Bun 迁移实战:20 分钟搞定,附踩坑记录
前端·javascript·node.js
minglie19 小时前
一个置换问题
javascript
用户21366100357219 小时前
Vue2非父子通信与动态组件
前端·vue.js
默_笙19 小时前
🌀 别再手动写 Prompt 了!我让 AI 自己循环改到满意为止
javascript
To_OC1 天前
LC 994 腐烂的橘子:人人都说是 BFS 入门题,我却写了三遍才过
javascript·算法·leetcode
如果超人不会飞1 天前
脉络清晰的业务演进:TinyVue Timeline 时间线组件全方位实战指南
vue.js