requestFullscreen больше не работает в обработчике событий сообщения

#google-chrome #firefox #postmessage #html5-fullscreen

#google-chrome #firefox #postmessage #html5-полноэкранный режим

Вопрос:

Пользователь нажимает кнопку, и в click обработчике событий мы postMessage переходим к iframe. Iframe обрабатывает это в message обработчике событий и вызывает element.requestFullscreen() . В старых браузерах это работало (например, в Chrome 65), но в текущем (72) это приводит к ошибкам с Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture. .

Есть ли способ передать флаг «инициированный жест» в postMessage вызове?

Обратите внимание, что у iframe есть allow="fullscreen" атрибут.

Ответ №1:

Как всегда с iframes, это зависит от того, где он размещен относительно родительского документа.

Если вы запускаете документ того же источника в этом фрейме, то вы можете просто вызвать requestFullScreen нужный элемент из основного документа:

 const frameDoc = frame.contentDocument;
frameDoc.getElementById('el-to-fs').requestFullscreen(); // assuming polyfill
  

jsfiddle Поскольку iframes, чрезмерно защищенные StackSnippets®, не разрешают доступ ни к полноэкранному режиму.


Но если бы это было так, у вас не было бы этой проблемы в Chrome (она все равно была бы в FF).

Потому что, хотя этот метод действительно требует пользовательского жеста, postMessage будучи достаточно быстрым, вы можете использовать его с фреймом того же происхождения в Chrome.

Что происходит в этом браузере, так это то, что документ с перекрестным происхождением, должно быть, получил пользовательский жест, прежде чем сможет вызвать requestFullscreen .
Как только фрейм с перекрестным исходным кодом будет помечен как взаимодействующий с пользователем, вы сможете вызывать его requestFullscreen даже из событий main-doc: jsfiddle (по-прежнему, только в Chrome).

Но для кроссбраузерного решения вам придется

  • загрузите это содержимое того же источника (например, с помощью прокси)
  • или использовать небольшой хак, где вы устанавливаете <iframe> полноэкранный режим и сообщаете внутреннему документу, что вы это сделали, чтобы он мог соответствующим образом оформить свой документ: jsfiddle
    main.js

     onclick = e => {
      frame.contentWindow.postMessage("you're going fullscreen", '*');
      frame.requestFullscreen();
    };
      

    frame.js

     onmessage = e => {
      if(message.data === "you're going fullscreen") {
        // trigger our special fullscreen CSS
        document.documentElement.classList.add('fullscreen');
        // do some DOM cleaning if needed
      }
      else if(message.data === "you're exiting fullscreen") {
        document.documentElement.classList.remove('fullscreen');
      }
    };
      

Комментарии:

1. В нашем случае это перекрестное происхождение. Спасибо за «небольшой взлом», который мог бы нам помочь.