zoukankan      html  css  js  c++  java
  • typescript 实现浏览器全屏

    最近后台项目需要一个"全屏"的按钮, github了下, 发现都仅仅支持"开启全屏", 而没有"切换"/"监听全屏状态"等功能, 所以打算自己写一个(主要代码量不大, 嘿嘿).

    写代码之前说说逻辑

    所有现代浏览器(>IE11)都提供了"全屏"的api,只是不同浏览器有不同的api(基本就是前缀不同), 所以我们要做的就是判断浏览器, 然后执行正确的api.

    1. 判断当前浏览器支持的前缀, 比如"webkit".
    2. 根据前缀得出我们需要的4个api的名字.
    3. 通过api实现"全屏"/"退出"/"切换"/"监听".

    代码

    首先我发现ts自带的声明中, 对webkit或moz开头的这种api并没有声明类型, 所以我们需要自己补充一下.

    不然ts会提示找不到对应的方法.

    知识点: 在自己的.d.ts文件中可以对ts系统自带的interface进行声明合并(扩展).

    // global.d.ts
    interface htmlElement {
        // 进入全屏
        webkitRequestFullscreen(options?: FullscreenOptions): Promise<void>;
        webkitRequestFullScreen(options?: FullscreenOptions): Promise<void>;
        msRequestFullscreen(options?: FullscreenOptions): Promise<void>;
        mozRequestFullScreen(options?: FullscreenOptions): Promise<void>;
    
        // 监听全屏
        onwebkitfullscreenchange: ((this: Element, ev: Event) => any) | null;
        onmozfullscreenchange: ((this: Element, ev: Event) => any) | null;
        MSFullscreenChange: ((this: Element, ev: Event) => any) | null;
    }
    
    interface Document {
        // 当前全屏的元素
        readonly webkitFullscreenElement: Element | null;
        readonly msFullscreenElement: Element | null;
        readonly mozFullScreenElement: Element | null;
    
        // 退出全屏
        webkitExitFullscreen(): Promise<void>;
        msExitFullscreen(): Promise<void>;
        mozCancelFullScreen(): Promise<void>;
    }

    提示: requestFullscreen(options?: FullscreenOptions): Promise<void>;可以在node_modules/typescript/lib/lib.dom.d.ts中找到.

    资源搜索网站大全 https://www.renrenfan.com.cn 广州VI设计公司https://www.houdianzi.com

    功能实现

    功能其实很简单, 我都写了注释, 就不过分解读了, 好了看实现代码:

    type RFSMethodName = 'webkitRequestFullScreen' | 'requestFullscreen' | 'msRequestFullscreen' | 'mozRequestFullScreen';
    type EFSMethodName = 'webkitExitFullscreen' | 'msExitFullscreen' | 'mozCancelFullScreen' | 'exitFullscreen';
    type FSEPropName = 'webkitFullscreenElement' | 'msFullscreenElement' | 'mozFullScreenElement' | 'fullscreenElement';
    type ONFSCPropName = 'onfullscreenchange' | 'onwebkitfullscreenchange' | 'onmozfullscreenchange' | 'MSFullscreenChange';
    
    /**
     * caniuse
     * https://caniuse.com/#search=Fullscreen
     * 参考 MDN, 并不确定是否有o前缀的, 暂时不加入
     * https://developer.mozilla.org/zh-CN/docs/Web/API/Element/requestFullscreen
     * 各个浏览器
     * https://www.wikimoe.com/?post=82
     */
    const DOC_EL = document.documentElement;
    
    let RFC_METHOD_NAME: RFSMethodName = 'requestFullscreen';
    let EFS_METHOD_NAME: EFSMethodName = 'exitFullscreen';
    let FSE_PROP_NAME: FSEPropName = 'fullscreenElement';
    let ON_FSC_PROP_NAME: ONFSCPropName = 'onfullscreenchange';
    
    if (`webkitRequestFullScreen` in DOC_EL) {
        RFC_METHOD_NAME = 'webkitRequestFullScreen';
        EFS_METHOD_NAME = 'webkitExitFullscreen';
        FSE_PROP_NAME = 'webkitFullscreenElement';
        ON_FSC_PROP_NAME = 'onwebkitfullscreenchange';
    } else if (`msRequestFullscreen` in DOC_EL) {
        RFC_METHOD_NAME = 'msRequestFullscreen';
        EFS_METHOD_NAME = 'msExitFullscreen';
        FSE_PROP_NAME = 'msFullscreenElement';
        ON_FSC_PROP_NAME = 'MSFullscreenChange';
    } else if (`mozRequestFullScreen` in DOC_EL) {
        RFC_METHOD_NAME = 'mozRequestFullScreen';
        EFS_METHOD_NAME = 'mozCancelFullScreen';
        FSE_PROP_NAME = 'mozFullScreenElement';
        ON_FSC_PROP_NAME = 'onmozfullscreenchange';
    } else if (!(`requestFullscreen` in DOC_EL)) {
        throw `当前浏览器不支持Fullscreen API !`;
    }
    
    /**
     * 启用全屏
     * @param  {htmlElement} 元素
     * @param  {FullscreenOptions} 选项
     * @returns {Promise}
     */
    export function beFull(el: HTMLElement = DOC_EL, options?: FullscreenOptions): Promise<void> {
        return el[RFC_METHOD_NAME](options);
    }
    
    /**
     * 退出全屏
     */
    export function exitFull(): Promise<void> {
        return document[EFS_METHOD_NAME]();
    }
    
    /**
     * 元素是否全屏
     * @param {HTMLElement}
     */
    export function isFull(el: HTMLElement | EventTarget): boolean {
        return el === document[FSE_PROP_NAME]
    }
    
    /**
     * 切换全屏/关闭
     * @param  {HTMLElement} 目标元素
     * @returns {Promise}
     */
    export function toggleFull(el: HTMLElement = DOC_EL, options?: FullscreenOptions): Promise<void> {
        if (isFull(el)) {
            return exitFull();
        } else {
            return beFull(el, options)
        }
    }
    
    /**
     * 当全屏/退出时触发
     * @param  {HTMLElement} 元素
     * @param  {(isFull: boolean) => void} 返回"是否全屏"
     */
    export function watchFull(el: HTMLElement, callback: (isFull: boolean) => void) {
        const cancel = () => {
            el.onfullscreenchange = null;
        };
    
        const handler = (event: Event) => {
            if (null !== event.target) {
                callback(isFull(event.target));
            }
        }
    
        // 这里addEventListener不好使
        el[ON_FSC_PROP_NAME] = handler;
    
        return {
            cancel
        }
    }
  • 相关阅读:
    【LEETCODE】58、数组分类,适中级别,题目:238、78、287
    【LEETCODE】57、数组分类,适中级别,题目:969、442、695
    【LEETCODE】56、数组分类,适中级别,题目:62、63、1035
    【LEETCODE】55、数组分类,适中级别,题目:79、611、950
    【LEETCODE】54、数组分类,简单级别,题目:605、532
    【LEETCODE】53、数组分类,简单级别,题目:989、674、1018、724、840、747
    【LEETCODE】52、数组分类,简单级别,题目:717,661,746,628,643,849
    【LEETCODE】51、数组分类,简单级别,题目:581,830,1010,665
    【LEETCODE】50、数组分类,简单级别,题目:888,1013,896,485,448,697
    【LEETCODE】49、数组分类,简单级别,题目:566,1089
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/14124421.html
Copyright © 2011-2022 走看看