在`.exitFullscreen()`之后阻止Firefox移动

时间:2017-02-26 14:42:53

标签: javascript jquery css firefox fullscreen

Firefox出现此行为(错误?)是在退出完整屏蔽<img>后发生的,其中用户最终位于用户刚刚全屏查看的<img>上方的元素。简而言之,我的问题是:

  

如何在退出全屏模式后阻止Firefox向上滚动?

由于SO的严格安全措施,作为Snippet发布的MCVE无法运行,因此我提供了plunker。所有细节都在Snippet和Plunker中进行了评论。此外,我添加了一个简单的界面,不仅可以重现问题,还可以更改布局以测试不同的组合。感谢您宝贵的时间。

SNIPPET (不起作用 - 请点击此plunker

/* Several attempts to use the .focus() method
|| and focus events did not work for me, neither
|| has tabindex and anchors. If it appears that
|| my implementation is wrong (a strong possibility)
|| please inform me.
*/
$('a').click(function(e) {
  var tgt = $(this).prev();
  fs(tgt[0]);
  $(this).focus();
});
/* This function is for the MCVE 
|| It enables the ~select~ to remove and re-insert
|| the test elements. By doing so, we can see
|| how the test elements behave in different
|| combinations. What I found out about FF is
|| that when exiting a full screened ~img~ that's
|| positioned last is that it will lose focus 
|| and the viewport is scrolled up to the element 
|| above it.
*/
$('#sel1').on('change', function(e) {
  var V = $(this).val();
  var first = $('#' + V).find(':first').attr('id');
  if ($('#' + V).hasClass('media')) {
    $('#' + V).fadeOut('#' + first);
  } else {
    $('#' + V).fadeIn('#' + first);
  }
  $('#' + V).toggleClass('media');
});

/* These 2 functions are responsible for 
|| full screen. Please inform me if there's a 
|| better way, or if anything is outdated. I
|| have researched the Fullscreen API and I
|| haven't found any updates of any use. I've
|| used these functions for the last 3 years
|| so maybe I might've missed something 
|| critical.
*/ // There's no ms prefixes because I'm not concerned about IE.

var isFullScreen = function() {
  return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement);
}

function fs(target) {

  if (!isFullScreen()) {
    if (target.requestFullscreen) {
      target.requestFullscreen();
    } else if (target.webkitRequestFullscreen) {
      target.webkitRequestFullscreen();
    } else if (target.mozRequestFullScreen) {
      target.mozRequestFullScreen();
    }
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    }
  }
}
/* These styles are here for the demo itself 
|| and are not a cause of the problem at hand
*/

* {
  margin: 0;
  padding: 0
}

body {
  font: 400 16px/1.3 Consolas;
  height: 100%;
  width: 100%;
  background: #333;
  color: #fed
}

a {
  margin: 0 auto 50px;
  display: block;
  width: 48px;
  height: 48px;
  text-align: center;
  cursor: pointer;
  background-size: contain;
}

.vid,
.img,
.gif,
.svg {
  display: block;
  margin: 20px auto;
}

.expand {
  background: url(http://imgh.us/expand_2.svg)no-repeat;
}

header {
  padding: 15px 10px;
  margin: 15px auto;
}

fieldset {
  border: 10px solid tomato;
  width: 20ch
}

legend {
  font-size: 1.2em;
}

dt {
  text-decoration: underline;
  font: 1.1em;
}

dd {
  margin-left: 20px
}

.note,
dt {
  color: #ffcc33
}

.demo {
  width: 450px;
  padding: 10px;
  counter-reset: step;
}

.demo li::before {
  counter-increment: step;
  content: "» " counter(step) ". ";
  text-indent: -150px;
  margin-left: 30px;
  color: cyan;
}

.fs:-webkit-full-screen {
  max-width: 100%;
  height: auto;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
  <title>Prevent Firefox from Moving After .exitFullscreen()</title>
  <style>

  </style>
</head>

<body>
  <header>
    <dl>
      <dt>Objective</dt>
      <dd>Prevent Firefox from Moving After .exitFullscreen()</dd>
      <dt>Behavior</dt>
      <dd><b class='note'>Expected: </b>When exiting fullscreen mode, we should be at the same position that we were at before</dd>
      <dd><b class='note'>Experienced: </b>In FF, when exiting fullscreen mode, we are scrolled up as if the element above has a higher tab priority or more than likely is that tab index and focus are being ignored by FF.</dd>
      <dt>Question</dt>
      <dd><b><mark>How can I prevent Firefox from scrolling up after exiting fullscreen mode?</mark></b></dd>
    </dl>
  </header>
  <section>
    <ol class='demo'>
      <li>To reproduce issue, use the &lt;select&gt; to remove items C, D, E, and F.</li>
      <li>Next, fullscreen item B by clicking the icon below it.</li>
      <li>Then exit full screen mode by hitting <kbd>ESC</kbd>.</li>
      <li>Notice we have jumped up the page.</li>
    </ol>
  </section>
  <!--This ~select~ is for the MCVE - details are
commented below in the ~script~ block-->

  <section>
    <fieldset>
      <legend>Remove and Re-insert Elements</legend>
      <select id='sel1'>
         <option value="">----</option>
         <option value='A'>&lt;video&gt; src=MP4</option>
         <option value='B'>&lt;img&gt; src=PNG</option>
         <option value='C'>&lt;video&gt; poster=GIF</option>
         <option value='D'>&lt;img&gt; src=SVG</option>
         <option value='E'>&lt;div&gt; &amp;nbsp;</option>
         <option value='F'>&lt;iframe&gt; srcdoc="&lt;DIV&gt;&lt;div&gt;"</option>
      </select>
    </fieldset>

    <!--I tried using the ~a~nchors, -id-, -name-, and -tabindex- 
FF was ignoring my attempts to keep or get focus. Using named or 
id ~a~nchors failed since the distance between desired spot
and the spot FF ends up at is short.-->
    <div id='A' class='media'>
      <video id="vid1" class="vid fs" src="http://html5demos.com/assets/dizzy.mp4" controls></video>
      <a href='#/' class='expand' tab-index='1'></a>
    </div>
    <div id='B' class='media'>
      <img id='img1' class='img fs' src='http://imgh.us/Lenna.png'>
      <a href='#/' class='expand' tab-index='1'></a>
    </div>
    <div id='C' class='media'>
      <video id='gif1' class='gif fs' poster='http://imgh.us/gir_zim.gif' width='300' height='300'></video>
      <a href='#/' class='expand' tab-index='1'></a>
    </div>
    <div id='D' class='media'>
      <img id='svg1' class='svg fs' src='http://www.clker.com/cliparts/j/g/8/S/V/O/test.svg' width='auto' height='500'>
      <a href='#/' class='expand' tab-index='1'></a>
    </div>

    <!--Subjects E and F were added to see if a "dummy"
element were to be the last element so that FF
would exit fullscreen on the last ~img~ correctly.
I got mixed results.-->
    <div id='E' class='media'>
      <div id='div1' class='fs'>&nbsp;</div>
      <a href='#/' class='expand' tab-index='1' height='1' width='1'></a>
    </div>
    <div id='F' class='media'>
      <iframe id='ifm1' class='fs' srcdoc="<div style='color:lime'>iframe srcdoc</div><div style='color:cyan'>2 divs</div>" allowfullscreen></iframe>
      <a href='#/' class='expand' tab-index='1' height='1' width='1'></a>
    </div>
    <footer class='bottom'> </footer>
  </section>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
  <script>
  </script>
</body>

</html>

2 个答案:

答案 0 :(得分:1)

最初定义变量。

var sx,sy;

在进入全屏

之前保存滚动条位置
var d= document, r= d.documentElement, b= d.body;
sx= r.scrollLeft || b.scrollLeft || 0;
sy= r.scrollTop  || b.scrollTop  || 0;

当玩家退出全屏时,

window.scrollTo(sx,sy);

希望这有帮助!

答案 1 :(得分:0)

这个答案完全归功于@Kaido,如果Kaido发布答案,我会立即取代这个答案。

我尝试使用滚动方法不起作用是因为当我应该一直在听onmozfullscreenchange

时,我正在听点击事件

Plunker

演示

&#13;
&#13;
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">

  <title>Prevent Firefox from Moving After .exitFullscreen()</title>
  <style>
    button {
      display: block;
      padding: 0;
      width: 32px;
      height: 32px;
      text-align: center;
      cursor: pointer;
      background-size: contain;
    }
    
    .expand {
      background: url(http://imgh.us/expand_2.svg)no-repeat;
    }
  </style>
</head>

<body>

  <div id='A' class='media'>A
    <video id="vid1" class="vid fs" src="http://html5demos.com/assets/dizzy.mp4" controls></video>

  </div>
  <div id='B' class='media'>B
    <img id='img1' class='img fs' src='http://imgh.us/Lenna.png'>
    <button class='expand'></button>
  </div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
  <script>
    $('button').click(function(e) {
      e.preventDefault();
      var tgt = $(this).prev();
      fs(tgt[0]);

    });
    /* This function is for the MCVE 
    || It enables the ~select~ to remove and re-insert
    || the test elements. By doing so, we can see
    || how the test elements behave in different
    || combinations. What I found out about FF is
    || that when exiting a full screened ~img~ that's
    || positioned last is that it will lose focus 
    || and the viewport is scrolled up to the element 
    || above it.
    */

    $('#sel1').on('change', function(e) {
      var V = $(this).val();
      var first = $('#' + V).find(':first').attr('id');
      if ($('#' + V).hasClass('media')) {
        $('#' + V).fadeOut('#' + first);
      } else {
        $('#' + V).fadeIn('#' + first);
      }
      $('#' + V).toggleClass('media');
    });

    /* These 2 functions are responsible for 
    || full screen. 
    */ // There's no ms prefixes because I'm not concerned about IE.

    var isFullScreen = function() {
      return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement);
    }
    // SOLUTION XXXXXXXXXX]START[XXXXXXXXXXXXXXX
    var yOffset;
    document.onmozfullscreenchange = function() {
      if (!isFullScreen()) {
        window.scrollTo(0, yOffset);
      }

    };
    // SOLUTION XXXXXXXXXXX]END[XXXXXXXXXXXXXXXX
    function fs(target) {

      if (!isFullScreen()) {
        yOffset = pageYOffset;
        if (target.requestFullscreen) {
          target.requestFullscreen();
        } else if (target.webkitRequestFullscreen) {
          target.webkitRequestFullscreen();
        } else if (target.mozRequestFullScreen) {
          target.mozRequestFullScreen();
        }
      } else {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen();
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
        }

      }
    }
  </script>
</body>

</html>
&#13;
&#13;
&#13;