【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
  };
}
相关推荐
jjw_zyfx2 分钟前
css 点击显示并移动元素,再次点击移回元素并消失
前端·javascript·css
英俊潇洒美少年11 分钟前
Vue2 高德地图地址选择器完整实战(组件抽离+高并发优化+@amap/amap-jsapi-loader最佳实践)
前端·javascript·vue.js
晴天丨21 分钟前
🛡️ Vue 3 错误处理完全指南:全局异常捕获、前端监控、用户反馈
前端·vue.js
河阿里24 分钟前
Vue3:全流程开发
vue.js
threelab26 分钟前
从工厂模式到简化封装:三维引擎架构演进之路 threejs设计
javascript·3d·架构·webgl
白日梦想家68144 分钟前
实战避坑+性能对比,for与each循环选型指南
开发语言·前端·javascript
帅帅哥的兜兜1 小时前
猪齿鱼:实现table分页勾选
前端·javascript·vue.js
wicb91wJ61 小时前
手写一个Promise,彻底掌握异步原理
开发语言·前端·javascript
zs宝来了1 小时前
Next.js SSR/SSG:路由与渲染模式深度解析
前端·javascript·框架
谢尔登1 小时前
【Next】客户端组件和服务端组件
前端·javascript·react.js·架构