iOS/Safariでiframe内にBootstrap3のModalを表示する時のアレ


<iframe> の中で Twitter Bootstrap3 の Modal を表示する際、スクロールを考慮した位置に正しく表示しようと思い下記のように$(this)topを変更したところ、iOS/Safari の環境でのみmodalの表示アニメーション完了と同時に画面が大きく下にスクロールしてしまい、Modalの表示位置もおかしくなる不具合が発生していました。

下記は現象発生時のjavascriptと(無理矢理)解決した方法です。

Environment

UserAgent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1

発生環境 発生バージョン
bootstrap 3.3.7
Device iPhone7
iOS 10.2.1

Buggy

$('.hoge-button').click(function(e) {
  e.preventDefault();
  var $modal = $('#hogeModal');
  $('#hogeModal').on('show.bs.modal', function (e) {
    var iframe = window.top.document.querySelector('iframe');
    if (iframe) {
      var rect = iframe.getBoundingClientRect();
      $(this).css('top', -rect.top); //set modal position
    }
  });
  $modal.modal();
});

Solved

$('.hoge-button').click(function(e) {
  e.preventDefault();
  var $modal = $('#hogeModal');
  var scrollPos = {x: window.parent.scrollX, y: window.parent.scrollY};
  $('#hogeModal').on('show.bs.modal', function (e) {
    var iframe = window.top.document.querySelector('iframe');
    if (iframe) {
      var rect = iframe.getBoundingClientRect();
      $(this).css('top', -rect.top); //set modal position
    }
  });
  $('#hogeModal').on('shown.bs.modal', function (e) {
    window.parent.scrollTo(scrollPos.x, scrollPos.y); // for iOS Safari Auto Scrolling bug
  });
  $modal.modal();
});