当滚动条可见时打开模态会导致页面移动

时间:2014-01-13 14:53:18

标签: twitter-bootstrap-3

这里是Bootstrap演示的模态代码:

<!-- Button trigger modal -->
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
  Launch demo modal
</button>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

如果页面上没有滚动条,则打开模态可以正常工作(尽管它会覆盖右侧不必要的滚动条):

http://jsfiddle.net/ujGh4/1/

但是,如果有一个滚动条可见,那么打开一个模态会导致页面移动看起来很糟糕:

http://jsfiddle.net/ujGh4/2/

我不知道这种情况是否发生在所有浏览器中,但我在Windows 7上使用了最新版本的Chrome,这里有一个视频:

http://www.screencast.com/t/vLlwtWiAsdQ0

如何解决这个非常难看的页面转换?

1 个答案:

答案 0 :(得分:1)

我想我遇到了同样的问题,虽然我无法100%确定它完全一样。无论如何,我通过猴子修补他们的javascript并添加一些CSS规则来修复它。这对我来说是最好的选择,所以我不必直接更改他们的源代码。

以下是CSS规则:

// Make bootstrap's normal 'modal-open' class have no effect, 
// since we're going to use our own 'custom-modal-open' class

.modal-open {
  overflow: auto;
}

// Define our own custom class that we'll apply to the body element
// at the appropriate time (to prevent the shifting).

.custom-modal-open {
  overflow: hidden;
}

// Also override the overflow value for the modal 'class'.  
// Bootstrap has it set to "scroll" which causes it to appear when
// it's not needed, and also makes the shift tougher to fix.

.modal {
  overflow: auto;
}

这是coffeescript猴子补丁:

# Store bootstrap's 'modal' function for safe keeping,
# so we can use it within our custom version.

$.fn.old_modal = $.fn.modal
$.fn.modal = (option, related_target) ->

  # Call bootstrap's implementation.  It runs normally other
  # than the fact that the .modal-open rule has no effect.

  $(this).old_modal(option, related_target)
  modal_obj = $(this).data('bs.modal')

  # The 'modal' function can be called for other reasons, and 
  # we're only interested in the case of the modal being shown.

  if (modal_obj.options.show)
    $('body').addClass('custom-modal-open')
    $(this).on('hide.bs.modal', (e) =>

      # Super-hacky...copy the padding-right to the margin-right
      # so that we're responsible for removing it later.

      scroll_padding = $('body').css('padding-right')
      $('body').css('margin-right', scroll_padding)
      $(this).off('hide.bs.modal')
    )
$(this).on('hidden.bs.modal', (e) =>

  # The grand finale...remove the modal-open and right side padding
  # *gasp* at the SAME TIME.  Bad twitter. But thanks for having 
  # both the hide and hidden events to make this possible :)

  $('body').removeClass('custom-modal-open')
  $('body').css('margin-right', '')
  $(this).off('hidden.bs.modal')
)
祝你好运...希望这个解决方案也适合你。它对我来说似乎在Chrome和Firefox上运行得很好。