Learn typescript in practice - implement full screen browser (100 lines)

Posted by MadDawgX on Tue, 19 Nov 2019 09:11:31 +0100

Learning a new language, the fastest way is to look at the actual code!

At the beginning of learning ts, everyone will ask "is there any practical project that can be referred to?"

OK! To meet your needs, I plan to regularly use ts to do some common business plug-ins, and the code volume is as small as possible (controlled within 🦕 1kb), which is convenient for you to read the source code, and also convenient for you to have time to implement it

Browser full screen

Recently, the background project needs a "full screen" button. github found that it only supports "open full screen" instead of "switch" / "monitor full screen status". So it plans to write one by itself (the main code is not large, hehe)

Talk about logic before writing code

All modern browsers (> ie11) provide "full screen" APIs, but different browsers have different APIs (basically different prefixes), so what we have to do is judge the browser, and then execute the correct api

  1. Determine the prefixes supported by the current browser, such as "webkit"
  2. According to the prefix, we get the names of the four APIs we need
  3. Realize "full screen" / "exit" / "switch" / "monitor" through api

Code

Source code: https://github.com/any86/be-full

First of all, I found that in the declaration of ts, there is no declaration type for the api starting with webkit or moz, so we need to supplement it ourselves
Otherwise, ts will prompt that no corresponding method can be found

Knowledge points: in your own. d.ts file, you can declare and merge (extend) the interface of TS system

// global.d.ts
interface HTMLElement {
    // Full screen entry
    webkitRequestFullscreen(options?: FullscreenOptions): Promise<void>;
    webkitRequestFullScreen(options?: FullscreenOptions): Promise<void>;
    msRequestFullscreen(options?: FullscreenOptions): Promise<void>;
    mozRequestFullScreen(options?: FullscreenOptions): Promise<void>;

    // Monitor full screen
    onwebkitfullscreenchange: ((this: Element, ev: Event) => any) | null;
    onmozfullscreenchange: ((this: Element, ev: Event) => any) | null;
    MSFullscreenChange: ((this: Element, ev: Event) => any) | null;
}

interface Document {
    // Elements of the current full screen
    readonly webkitFullscreenElement: Element | null;
    readonly msFullscreenElement: Element | null;
    readonly mozFullScreenElement: Element | null;

    // Exit full screen
    webkitExitFullscreen(): Promise<void>;
    msExitFullscreen(): Promise<void>;
    mozCancelFullScreen(): Promise<void>;
}

Prompt: requestfullscreen (options?: fullscreenoptions): promise < void >; it can be found in node_modules/typescript/lib/lib.dom.d.ts

Function realization

In fact, the function is very simple. I wrote comments, but I just read them separately. Let's see the implementation code:

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
 * Refer to MDN, if you are not sure whether there is o prefix, do not add it temporarily
 * https://developer.mozilla.org/zh-CN/docs/Web/API/Element/requestFullscreen
 * Browsers
 * 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 `Current browser does not support Fullscreen API !`;
}

/**
 * Enable full screen
 * @param  {HTMLElement} element
 * @param  {FullscreenOptions} option
 * @returns {Promise}
 */
export function beFull(el: HTMLElement = DOC_EL, options?: FullscreenOptions): Promise<void> {
    return el[RFC_METHOD_NAME](options);
}

/**
 * Exit full screen
 */
export function exitFull(): Promise<void> {
    return document[EFS_METHOD_NAME]();
}

/**
 * Is the element full screen
 * @param {HTMLElement}
 */
export function isFull(el: HTMLElement | EventTarget): boolean {
    return el === document[FSE_PROP_NAME]
}

/**
 * Toggle full screen / off
 * @param  {HTMLElement} Target element
 * @returns {Promise}
 */
export function toggleFull(el: HTMLElement = DOC_EL, options?: FullscreenOptions): Promise<void> {
    if (isFull(el)) {
        return exitFull();
    } else {
        return beFull(el, options)
    }
}

/**
 * Triggered when full screen / exit
 * @param  {HTMLElement} element
 * @param  {(isFull: boolean) => void} Return to "full screen"
 */
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));
        }
    }

    // It's hard to use addEventListener here
    el[ON_FSC_PROP_NAME] = handler;

    return {
        cancel
    }
}

Source code: https://github.com/any86/be-full

typescript series

If you are interested in ts, welcome to my basic course

Lesson one, experience typescript

Lesson 2, basic and advanced types

Lesson three, generics

Lesson 4, interpreting advanced types

Lesson Five: what is a namespace

In particular, learn typescript - "is" in the source code of vue3

Lesson 6, what is a declaration file? Chapter of global declaration

summary

Write more, practice more, and get started soon. Put a few projects I wrote with ts as a reference, throw a brick to attract jade, come on!

Mobile / pc gesture library, support: tap/press/pan/swipe/rotate/pinch

https://github.com/any86/any-...

🍭 turn the vue component into a command like this.$xxx

https://github.com/any86/vue-...

🍔 full screen display of any element, supporting PC / mobile terminal, less than 1kb

https://github.com/any86/be-full

WeChat group

Thank you for your reading. If you have any questions, you can add me wechat, and I will pull you into wechat group (because Tencent has a limit of 100 wechat group members, you must pull in more than 100 people)

Topics: Javascript github TypeScript Mobile Vue