# IFrame: Pseudo-Fullscreen on iOS


On iOS devices, when entering fullscreen mode the browser uses the native fullscreen API, which can conflict with Kinescope player controls. This script solves the problem: it preserves the original controls and works correctly with dynamic watermarks.

## Who this article is for

* **Web application developers** — need to ensure correct fullscreen behavior on iOS
* **Content owners with watermarks** — need correct display of dynamic watermarks on iOS
* **Frontend developers** — need to configure player behavior on mobile devices

## When you need pseudo-fullscreen mode on iOS

Use this code if:

- **Dynamic watermarks on iOS** — watermarks must display correctly in fullscreen mode
- **Preserving player controls** — it's important that the original player controls remain accessible
- **Correct iOS behavior** — correct fullscreen behavior is needed on iOS devices (Safari, Chrome for iOS)

> **Информация:**

**Limitations:** Works only on iOS devices (Safari, Chrome for iOS). Not needed on other platforms — the native fullscreen API works correctly there.



## **How the script works (3 steps)**

1. **The player sends an event** — when the user enters or exits fullscreen mode, the player sends a `KINESCOPE_PLAYER_FULLSCREEN_CHANGE` event.
2. **The script handles the event** — saves the current iframe styles and applies fullscreen display styles (or restores the originals).
3. **Controls are preserved** — the original player controls remain accessible, dynamic watermarks work correctly.

Now let's go through how to set this up.

## **Setup: step 1 — adding the script to the page**

Place the script on the page where the Kinescope player is embedded, before the closing `</body>` tag or in the `<head>` section. The script will automatically handle all Kinescope player iframes on the page.

**Example placement in HTML:**

```html
<!DOCTYPE html>
<html>
<head>
  <title>Page with Kinescope Player</title>
</head>
<body>
  <!-- Your content -->
  <iframe src="https://kinescope.io/embed/pcFNnQGsD59CMKte2SQQaz" width="640" height="360" frameborder="0"></iframe>
  
  <!-- Script for iOS fullscreen mode -->
  <script>
    // Script code here
  </script>
</body>
</html>
```

> **Внимание:**

Make sure the script loads after the DOM is loaded, or use the `DOMContentLoaded` event for initialization if placing the script in `<head>`.



## **Setup: step 2 — the script code**

Here is the ready-to-use code for your page:

```javascript
window.addEventListener('message', (event) => {
  if (event.data.type && event.data.type === 'KINESCOPE_PLAYER_FULLSCREEN_CHANGE') {
    const frames = document.getElementsByTagName('iframe');
    for (let i = 0; i < frames.length; i++) {
      if (frames[i].contentWindow === event.source) {
        if (event.data.value) {
          // Save original styles
          if (!frames[i].dataset.originalStyles) {
            frames[i].dataset.originalStyles = frames[i].style.cssText;
          }
          // Apply fullscreen styles
          frames[i].style.cssText = `
            background: #000;
            border: none;
            position: fixed;
            z-index: 9999;
            width: 100%;
            height: 100%;
            bottom: 0;
            right: 0;
            top: 0;
            left: 0;`;
        } else {
          // Restore old styles if they were saved
          if (frames[i].dataset.originalStyles) {
            frames[i].style.cssText = frames[i].dataset.originalStyles;
            delete frames[i].dataset.originalStyles;
          } else {
            frames[i].style.cssText = '';
          }
        }
        break;
      }
    }
  }
});
```

## **How it works (in detail)**

Here's what happens when a user opens the page with the player:

1. **User opens the page** — the script starts tracking events from all iframes on the page.
2. **User enters fullscreen mode** — the Kinescope player sends a `KINESCOPE_PLAYER_FULLSCREEN_CHANGE` event with `value: true`.
3. **The script handles the event** — finds the right iframe by event source, saves its current styles, and applies fullscreen display styles.
4. **User exits fullscreen mode** — the player sends an event with `value: false`, the script restores the original iframe styles.

### **The `KINESCOPE_PLAYER_FULLSCREEN_CHANGE` event**

The Kinescope player automatically sends this event via `window.postMessage` when:

- User enters fullscreen mode (`event.data.value === true`)
- User exits fullscreen mode (`event.data.value === false`)

**Event format:**

```javascript
{
  type: 'KINESCOPE_PLAYER_FULLSCREEN_CHANGE',
  value: true  // or false
}
```

### **iframe style management**

**When entering fullscreen:**

1. Current iframe styles are saved in `dataset.originalStyles` (to restore later)
2. Fullscreen display styles are applied:
   - Fixed position (`position: fixed`) — iframe stays in place when scrolling
   - Full screen size (`width: 100%`, `height: 100%`) — occupies the entire screen
   - High z-index (`z-index: 9999`) — iframe on top of other elements
   - Black background (`background: #000`) — for correct display

**When exiting fullscreen:**

1. Original iframe styles are restored from `dataset.originalStyles`
2. Saved styles are deleted from `dataset`

### **Security**

The script verifies that the event originates from the correct iframe (`event.source` matches `iframe.contentWindow`). This ensures security when working with multiple iframes on the page — each iframe is handled independently.

**How it works:**

```text
1. Receive event from iframe
2. Check: event.source === iframe.contentWindow
3. If matched — handle the event
4. If not matched — ignore
```

## **Usage examples**

### **Example 1: Simple integration**

If you have one player on the page, the code above will work out of the box:

```html
<iframe src="https://kinescope.io/embed/pcFNnQGsD59CMKte2SQQaz" width="640" height="360" frameborder="0"></iframe>
<script>
  // Fullscreen handling code
</script>
```

### **Example 2: Multiple players on the page**

If there are multiple players on the page, the script will automatically handle each one independently:

```html
<iframe src="https://kinescope.io/embed/video1" id="player1" width="640" height="360"></iframe>
<iframe src="https://kinescope.io/embed/video2" id="player2" width="640" height="360"></iframe>
<script>
  // Code will handle both players independently
</script>
```

### **Example 3: Using with frameworks**

If you use React, Vue, or another framework, place the script in the component that mounts after DOM loading:

**React:**

```javascript
import { useEffect } from 'react';

function VideoPlayer() {
  useEffect(() => {
    // Fullscreen handling code
    // ... (insert code from step 2)
  }, []);

  return <iframe src="https://kinescope.io/embed/pcFNnQGsD59CMKte2SQQaz" />;
}
```

**Vue:**

```javascript
export default {
  mounted() {
    // Fullscreen handling code
    // ... (insert code from step 2)
  }
}
```

Done! Now fullscreen mode will work correctly on iOS devices, and player controls will be preserved.

## What's next?

1. **[Embedding](https://docs.kinescope.com/video-player/embedding/)** — basic player embedding
2. **[IFrame Player API](https://docs.kinescope.com/developer-guides/iframe-player-api/)** — programmatic player control
3. **[Dynamic watermarks](https://docs.kinescope.com/content-protection/watermarks/)** — configuring watermarks for content protection

Still have questions? Write to the support chat within the Kinescope interface — our specialists will help!

