Request FullScreen Functionality in Angular 2/4

For my new project in Angular 2/Angular 4, I need to incorporate an Enter FullScreen Button feature.

After researching, I came across this code:

  toggleFullScreen() {
    if (!document.fullscreenElement &&    
        !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement )
        {  
      if (document.documentElement.requestFullscreen) {
        document.documentElement.requestFullscreen();
      } else if (document.documentElement.msRequestFullscreen) {
        document.documentElement.msRequestFullscreen();
      } else if (document.documentElement.mozRequestFullScreen) {
        document.documentElement.mozRequestFullScreen();
      } else if (document.documentElement.webkitRequestFullscreen) {
        document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
      }
    } else {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      }
    }
  }

Although the FullScreen Button works when using "ng serve" to compile the application, I encounter the following errors:

ERROR in src/app/commom/breadcrumb/breadcrumb.component.ts(41,64): error TS2339: Property 'mozRequestFullScreen' does not exist on type 'HTMLElement'.
src/app/commom/breadcrumb/breadcrumb.component.ts(41,127): error TS2551: Property 'msRequestFullscreen' does not exist on type 'HTMLElement'. Did you mean 'requestFullscreen'?
src/app/commom/breadcrumb/breadcrumb.component.ts(42,56): error TS2339: Property 'mozCancelFullScreen' does not exist on type 'Document'.
src/app/commom/breadcrumb/breadcrumb.component.ts(42,111): error TS2551: Property 'msExitFullscreen' does not exist on type 'Document'. Did you mean 'exitFullscreen'?
src/app/commom/breadcrumb/breadcrumb.component.ts(44,41): error TS2339: Property 'mozFullScreenElement' does not exist on type 'Document'.
src/app/commom/breadcrumb/breadcrumb.component.ts(44,102): error TS2551: Property 'msFullscreenElement' does not exist on type 'Document'. Did you mean 'fullscreenElement'?
src/app/commom/breadcrumb/breadcrumb.component.ts(103,19): error TS2339: Property 'mozFullScreenElement' does not exist on type 'Document'.
src/app/commom/breadcrumb/breadcrumb.component.ts(103,90): error TS2551: Property 'msFullscreenElement' does not exist on type 'Document'. Did you mean 'fullscreenElement'?
src/app/commom/breadcrumb/breadcrumb.component.ts(107,43): error TS2551: Property 'msRequestFullscreen' does not exist on type 'HTMLElement'. Did you mean 'requestFullscreen'?
src/app/commom/breadcrumb/breadcrumb.component.ts(108,34): error TS2551: Property 'msRequestFullscreen' does not exist on type 'HTMLElement'. Did you mean 'requestFullscreen'?
src/app/commom/breadcrumb/breadcrumb.component.ts(109,43): error TS2339: Property 'mozRequestFullScreen' does not exist on type 'HTMLElement'.
src/app/commom/breadcrumb/breadcrumb.component.ts(110,34): error TS2339: Property 'mozRequestFullScreen' does not exist on type 'HTMLElement'.
src/app/commom/breadcrumb/breadcrumb.component.ts(112,9): error TS2554: Expected 0 arguments, but got 1.
src/app/commom/breadcrumb/breadcrumb.component.ts(112,66): error TS2339: Property 'ALLOW_KEYBOARD_INPUT' does not exist on type '{ new (): Element; prototype: Element; }'.
src/app/commom/breadcrumb/breadcrumb.component.ts(117,27): error TS2551: Property 'msExitFullscreen' does not exist on type 'Document'. Did you mean 'exitFullscreen'?
src/app/commom/breadcrumb/breadcrumb.component.ts(118,18): error TS2551: Property 'msExitFullscreen' does not exist on type 'Document'. Did you mean 'exitFullscreen'?
src/app/commom/breadcrumb/breadcrumb.component.ts(119,27): error TS2339: Property 'mozCancelFullScreen' does not exist on type 'Document'.
src/app/commom/breadcrumb/breadcrumb.component.ts(120,18): error TS2339: Property 'mozCancelFullScreen' does not exist on type 'Document'.

If anyone could provide assistance, I would greatly appreciate it. Thank you!

Answer №1

In the typings for HTMLElement and Element, certain properties like mozFullScreenElement and ALLOW_KEYBOARD_INPUT are not defined. This causes issues with the TypeScript compiler even though the generated JavaScript code functions correctly.

An easy fix is to simply cast problematic elements to <any>. A more refined approach would involve creating custom interfaces that extend HTMLElement and Element, as shown below:

interface MyHTMLElement extends HTMLElement {
  mozFullScreenElement?: boolean;
  webkitFullscreenElement?: boolean;
  // Add any other necessary properties here
}

Instead of casting elements to <any>, you can then cast them to your custom interfaces.

Note: I have modified this full-screen code to be more TypeScript-friendly for personal use:

interface FsDocument extends HTMLDocument {
  mozFullScreenElement?: Element;
  msFullscreenElement?: Element;
  msExitFullscreen?: () => void;
  mozCancelFullScreen?: () => void;
}

export function isFullScreen(): boolean {
  const fsDoc = <FsDocument> document;

  return !!(fsDoc.fullscreenElement || fsDoc.mozFullScreenElement || fsDoc.webkitFullscreenElement || fsDoc.msFullscreenElement);
}

interface FsDocumentElement extends HTMLElement {
  msRequestFullscreen?: () => void;
  mozRequestFullScreen?: () => void;
}

export function toggleFullScreen(): void {
  const fsDoc = <FsDocument> document;

  if (!isFullScreen()) {
    const fsDocElem = <FsDocumentElement> document.documentElement;

    if (fsDocElem.requestFullscreen)
      fsDocElem.requestFullscreen();
    else if (fsDocElem.msRequestFullscreen)
      fsDocElem.msRequestFullscreen();
    else if (fsDocElem.mozRequestFullScreen)
      fsDocElem.mozRequestFullScreen();
    else if (fsDocElem.webkitRequestFullscreen)
      fsDocElem.webkitRequestFullscreen();
  }
  else if (fsDoc.exitFullscreen)
    fsDoc.exitFullscreen();
  else if (fsDoc.msExitFullscreen)
    fsDoc.msExitFullscreen();
  else if (fsDoc.mozCancelFullScreen)
    fsDoc.mozCancelFullScreen();
  else if (fsDoc.webkitExitFullscreen)
    fsDoc.webkitExitFullscreen();
}

export function setFullScreen(full: boolean): void {
  if (full !== isFullScreen())
    toggleFullScreen();
}

I've tested this code on Chrome, Firefox, and Safari on macOS, and it performs well.

Answer №2

Big shoutout to @kshetline for the amazing solution that worked like a charm! I was so impressed that I decided to implement it into a Service

import {Injectable} from '@angular/core';

@Injectable()
export class FullscreenService {
  private doc = <FullScreenDocument>document;

  enter() {
    const el = this.doc.documentElement;
    if (el.requestFullscreen) el.requestFullscreen();
    else if (el.msRequestFullscreen) el.msRequestFullscreen();
    else if (el.mozRequestFullScreen) el.mozRequestFullScreen();
    else if (el.webkitRequestFullscreen) el.webkitRequestFullscreen();
  }

  leave() {
    if (this.doc.exitFullscreen) this.doc.exitFullscreen();
    else if (this.doc.msExitFullscreen) this.doc.msExitFullscreen();
    else if (this.doc.mozCancelFullScreen) this.doc.mozCancelFullScreen();
    else if (this.doc.webkitExitFullscreen) this.doc.webkitExitFullscreen();
  }

  toggle() {
    if (this.enabled) this.leave();
    else this.enter();
  }

  get enabled() {
    return !!(
      this.doc.fullscreenElement ||
      this.doc.mozFullScreenElement ||
      this.doc.webkitFullscreenElement ||
      this.doc.msFullscreenElement
    );
  }
}

interface FullScreenDocument extends HTMLDocument {
  documentElement: FullScreenDocumentElement;
  mozFullScreenElement?: Element;
  msFullscreenElement?: Element;
  webkitFullscreenElement?: Element;
  msExitFullscreen?: () => void;
  mozCancelFullScreen?: () => void;
  webkitExitFullscreen?: () => void;
}

interface FullScreenDocumentElement extends HTMLElement {
  msRequestFullscreen?: () => void;
  mozRequestFullScreen?: () => void;
  webkitRequestFullscreen?: () => void;
}

How to use the service:

@Component()
export class SomeComponent {
  constructor(private fullscreenService: FullscreenService) {}

  onToggleFullscreen() {
    this.fullscreenService.toggle();
  }
}

Answer №3

Since the properties mozFullScreenElement and msFullscreenElement are vendor-specific, they do not have a defined type. A workaround is to modify these properties to something like document['mozFullScreenElement']

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to include transitions in d3.js when adding or removing a context menu

I'm currently working on a project involving the creation of a Force-Directed Graph using D3.js version 6. When users interact with nodes by clicking on them, a context menu should appear. This menu should disappear when users click elsewhere in the S ...

What is the best method to transfer data into a popup window from a different component in Angular 4?

I'm currently working with Angular 4 and have two components: customer-list and customer-detail. The customer-list component is responsible for displaying a list of customers. Within this component: Clicking on "Create customer" will open the custo ...

Angular loop is unable to detect changes in the updated list

My Angular application is facing a peculiar issue that I can't seem to figure out. // Here are the class attributes causing trouble tenants: any[] = []; @Input() onTenantListChange: EventEmitter<Tenant[]>; ngOnInit(): void { this. ...

FormGroup believes it is necessary even without specifying any validators

Trying to create a form that includes a nested FormGroup: this.form = this.formBuilder.group({ kitType: [ '', [ Validators.required, ] ], diagnosisCode: [ '', [ Validators.required, ] ], delayKitSh ...

Angular 5 combined with the dynamic capabilities of Popper.JS

Launching a training project that requires Popper.Js in its features has been quite challenging. Despite following Bootstrap's documentation on how to implement Popper.Js, I have encountered difficulties. As per Bootstrap's docs, I tried initiat ...

Adjusting the ng-bootstrap carousel to fit within a div inside an ng-bootstrap modal

I have been struggling to correctly adjust the CSS properties in order to make a ng-bootstrap carousel image fit into a specific space (div) within a custom ng-bootstrap modal. Take a look at this modified StackBlitz code. In the provided example, the ima ...

Unable to locate a matching version of "@typescript-eslint/type-utils" for "5.31.0" in yarn

Currently working on a Node.js application that is utilizing Docker. Encountering an error during the image build process in the installation step. The installation works perfectly fine locally without any issues. We are using Nexus, but even when going ...

Create two separate subdirectories within the Angular project for each of the development projects

1-I recently deployed an Angular project to my hosting service and it is working fine. () 2-I decided to create a new folder on my host named '/magazine'. 3-In this new folder, I am developing another project, a magazine website. However, when ...

Discovering the Error Message within the Error Object transmitted by NodeJS to Angular

When handling errors in Nodejs functions using a try/catch scope, an error may be returned in cases such as when the user doesn't exist or when the database is unreachable. The code snippet below demonstrates this scenario: router.delete('/delete ...

Attaching dynamic data to a specific element within an array

I have successfully created a demo where elements can be dropped into a specific area and their top and left values are displayed. I have also added functionality to remove dropped items and move them between different blocks. However, I am encountering so ...

The TypeScript elusive bug is making me lose my mind: Struggling to exclude types using control statements

I encountered a recurring error that I managed to narrow down to a specific scenario which only occasionally replicates on the TypeScript Playground, but consistently fails when running tsc locally. type Result = { success: true, value: string, } | { ...

NSwag.MSBuild encountering problems with TypeScript versions

While working in NSwag Studio, I came across a flag that allows the use of a specific TypeScript version for generating TypeScript typings/code. However, when attempting to achieve the same functionality within my .csproj file, the approach seems to have n ...

Enhance existing functionalities in library with type augmentation strategy

I am interested in creating a library that includes a custom matcher function in TypeScript using Vitest. After following the documentation and adding a vitest.d.ts file with the necessary augmentations, everything appears to be working well. However, I ha ...

Connect twice with the Socket.IO client

Every time my socket io client connects to the server, it seems to happen twice. You can see what I mean by looking at this screenshot of the double connection. This project is built in Angular 2, so I'm coding in TypeScript: class Server { pr ...

NgFor conditional slice pipe

Is there a way to conditionally slice the output in an ngFor loop? Take a look at the snippet of HTML template below: <div *ngFor="let bucket of getBucketsWithValues(bucketName.criterium ? bucketName.criterium : bucketName) | orderBy:'key' ...

A guide to iterating over an array and displaying individual elements in Vue

In my application, there is a small form where users can add a date with multiple start and end times which are then stored in an array. This process can be repeated as many times as needed. Here is how the array structure looks: datesFinal: {meetingName: ...

The toggle-button's group property does not function properly when paired with ngIf

The group property is not functioning as expected when using ngIf in the toggle-group. Here is the code snippet: <mat-button-toggle-group *ngIf="query.noOfQuestions == 05" (change)="toggleChangeQuestion($event)" name="selectQue ...

Utilizing trackingjs as an external library in Ionic2

I have been attempting to incorporate the trackingjs library (https://www.npmjs.com/package/tracking) into my ionic2 project. Following the guidelines in the documentation (https://ionicframework.com/docs/v2/resources/third-party-libs/), I was able to suc ...

How can union types be used correctly in a generic functional component when type 'U' is not assignable to type 'T'?

I've been researching this issue online and have found a few similar cases, but the concept of Generic convolution is causing confusion in each example. I have tried various solutions, with the most promising one being using Omit which I thought would ...

Only map property type when the type is a union type

My goal is to create a mapping between the keys of an object type and another object, following these rules: Each key should be from the original type If the value's type is a union type, it should have { enum: Array } If the value's type is not ...