移动设备上的 Twitter Bootstrap 模式

Posted

技术标签:

【中文标题】移动设备上的 Twitter Bootstrap 模式【英文标题】:Twitter Bootstrap modal on mobile devices 【发布时间】:2012-05-03 18:18:19 【问题描述】:

引导模式在 androidios 上无法正常工作。问题跟踪器承认问题,但不提供可行的解决方案:

Modals in 2.0 are broken on mobile.

Modal window in 2.0 not positioning properly

屏幕变暗,但模态本身在视口中不可见。可以在页面顶部找到它。当您在页面上向下滚动时会出现问题。

这是 bootstrap-responsive.css 的相关部分:

.modal 
    position:fixed;
    top:50%;
    left:50%;
    z-index:1050;
    max-height:500px;
    overflow:auto;
    width:560px;
    background-color:#fff;
    border:1px solid #999;
    -webkit-border-radius:6px;
    -moz-border-radius:6px;
    border-radius:6px;
    -webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
    -moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
    box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
    -webkit-background-clip:padding-box;
    -moz-background-clip:padding-box;
    background-clip:padding-box;
    margin:-250px 0 0 -280px;

我可以申请修复吗?

【问题讨论】:

【参考方案1】:

编辑:已构建 unofficial Bootstrap Modal modification 来解决响应式/移动问题。这可能是解决问题的最简单和最容易的方法。

此后在one of the issues you discussed earlier 中找到了一个修复程序

bootstrap-responsive.css

.modal  
    position: fixed; 
    top: 3%; 
    right: 3%; 
    left: 3%; 
    width: auto; 
    margin: 0; 

.modal-body  
    height: 60%; 

bootstrap.css

.modal-body  
    max-height: 350px; 
    padding: 15px; 
    overflow-y: auto; 
    -webkit-overflow-scrolling: touch; 
 

【讨论】:

修复了我在装有 ios 6 的 iPhone 上的问题(无论 Safari 是什么版本) .modal 中有错误。你有顶部:3%和底部:3%。如果您移除底部:3%,它会按预期工作。 仅供参考 @Maurice 我更新了答案以反映一个新的 Github 项目,该项目以更优雅的解决方案解决了这个问题。 我发现还需要添加底部:3%;在 .modal 类中的移动 css 版本中,以便在移动设备上,可以滚动到模式的最后。还要注意桌面版本的最大高度。为了避免在桌面版本中,模态框的主体非常小,并且模态框的页脚在主屏幕上,我将 max-height 添加到 1200 px;【参考方案2】:

Gil 的回答很有希望(他链接到的库) --- 但目前,在移动设备上向下滚动时它仍然无法正常工作。

我只在我的 CSS 文件末尾使用 CSS 的 sn-p 为自己解决了这个问题:

@media (max-width: 767px) 
  #content .modal.fade.in 
    top: 5%;
  

#content 选择器只是一个包装我的 html 的 id,因此我可以覆盖 Bootstrap 的特异性(设置为您自己的 id 包装您的模态 html)。

缺点:它不在移动设备上垂直居中。

优点:它是可见的,并且在较小的设备上,合理大小的模态将占据大部分屏幕,因此“非居中”不会那么明显。

为什么有效:

当您使用 Bootstrap 的响应式 CSS 处于低屏幕尺寸时,对于屏幕较小的设备,它会将 .modal.fade.in 的“顶部”设置为“自动”。出于某种原因,移动 webkit 浏览器似乎很难通过“自动”分配来确定垂直位置。因此,只需将其切换回固定值,它就可以很好地工作。

由于 modal 已经设置为 postition: absolute,该值是相对于视口的高度,而不是文档的高度,所以无论页面有多长或滚动到哪里,它都可以工作。

【讨论】:

【参考方案3】:

issue 2130 中的The solution by niftylettuce 似乎修复了所有移动平台中的模态...

9/1/12 更新:修复已在此处更新:twitter bootstrap jquery plugins

(下面的代码较旧但仍然有效)

// # Twitter Bootstrap modal responsive fix by @niftylettuce
//  * resolves #407, #1017, #1339, #2130, #3361, #3362, #4283
//   <https://github.com/twitter/bootstrap/issues/2130>
//  * built-in support for fullscreen Bootstrap Image Gallery
//    <https://github.com/blueimp/Bootstrap-Image-Gallery>

// **NOTE:** If you are using .modal-fullscreen, you will need
//  to add the following CSS to `bootstrap-image-gallery.css`:
//
//  @media (max-width: 480px) 
//    .modal-fullscreen 
//      left: 0 !important;
//      right: 0 !important;
//      margin-top: 0 !important;
//      margin-left: 0 !important;
//    
//  
//

var adjustModal = function($modal) 
  var top;
  if ($(window).width() <= 480) 
    if ($modal.hasClass('modal-fullscreen')) 
      if ($modal.height() >= $(window).height()) 
        top = $(window).scrollTop();
       else 
        top = $(window).scrollTop() + ($(window).height() - $modal.height()) / 2;
      
     else if ($modal.height() >= $(window).height() - 10) 
      top = $(window).scrollTop() + 10;
     else 
      top = $(window).scrollTop() + ($(window).height() - $modal.height()) / 2;
    
   else 
    top = '50%';
    if ($modal.hasClass('modal-fullscreen')) 
      $modal.stop().animate(
          marginTop  : -($modal.outerHeight() / 2)
        , marginLeft : -($modal.outerWidth() / 2)
        , top        : top
      , "fast");
      return;
    
  
  $modal.stop().animate( 'top': top , "fast");
;

var show = function() 
  var $modal = $(this);
  adjustModal($modal);
;

var checkShow = function() 
  $('.modal').each(function() 
    var $modal = $(this);
    if ($modal.css('display') !== 'block') return;
    adjustModal($modal);
  );
;

var modalWindowResize = function() 
  $('.modal').not('.modal-gallery').on('show', show);
  $('.modal-gallery').on('displayed', show);
  checkShow();
;

$(modalWindowResize);
$(window).resize(modalWindowResize);
$(window).scroll(checkShow);

【讨论】:

【参考方案4】:

我们使用此代码在 Bootstrap 模式对话框打开时将其置于中心。我在 iOS 上使用它时没有遇到任何问题,但我不确定它是否适用于 Android。

$('.modal').on('show', function(e) 
    var modal = $(this);
    modal.css('margin-top', (modal.outerHeight() / 2) * -1)
         .css('margin-left', (modal.outerWidth() / 2) * -1);
    return this;
);

【讨论】:

【参考方案5】:

诚然,我没有尝试过上面列出的任何解决方案,但是当我在 Bootstrap 3 中尝试 jschr's Bootstrap-modal project 时(最终)高兴得跳起来(链接到最佳答案)。 js 给我带来了麻烦,所以我放弃了它(也许我的问题是一个独特的问题,或者它适用于 Bootstrap 2),但 CSS 文件本身似乎可以在 Android 的原生 2.3.4 浏览器中解决问题。

就我而言,到目前为止,在使用覆盖来允许现代手机中的预期行为之前,我已经使用(次优)用户代理检测。

例如,如果您希望所有 3.x 及以下版本的 Android 手机仅使用全套 hack,您可以在使用 javascript 检测用户代理后向正文添加一个类“oldPhoneModalNeeded”,然后修改 jschr 的 Bootstrap-modal始终将 .oldPhoneModalNeeded 作为祖先的 CSS 属性。

【讨论】:

【参考方案6】:

您可以在 javascript 中全局添加此属性:

if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) 
    var styleEl = document.createElement('style'), styleSheet;
    document.head.appendChild(styleEl);
    styleSheet = styleEl.sheet;
    styleSheet.insertRule(".modal  position:absolute; bottom:auto; ", 0);
 

【讨论】:

【参考方案7】:

好的,这确实解决了问题,我在 2012 年 9 月 5 日至 2012 年 9 月今天尝试过,但您必须确保查看演示

niftylettuce 在 issue 2130 中的解决方案似乎完全修复了模态 移动平台...

9/1/12 更新:修复已在此处更新: twitter bootstrap jquery plugins

这里是Demo 的链接 我使用的代码很好用

            title_dialog.modal();
            title_dialog.modalResponsiveFix()
            title_dialog.touchScroll();

【讨论】:

【参考方案8】:

我的解决方案...

Ver en jsfiddle

//Fix modal mobile Boostrap 3
function Show(id)
    //Fix CSS
    $(".modal-footer").css("padding":"19px 20px 20px","margin-top":"15px","text-align":"right","border-top":"1px solid #e5e5e5");
    $(".modal-body").css("overflow-y","auto");
    //Fix .modal-body height
    $('#'+id).on('shown.bs.modal',function()
        $("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
        h1=$("#"+id+">.modal-dialog").height();
        h2=$(window).height();
        h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
        h4=h2-(h1-h3);      
        if($(window).width()>=768)
            if(h1>h2)
                $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
            
            $("#"+id+">.modal-dialog").css("margin","30px auto");
            $("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
            $("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);               
            if($("#"+id+">.modal-dialog").height()+30>h2)
                $("#"+id+">.modal-dialog").css("margin-top","0px");
                $("#"+id+">.modal-dialog").css("margin-bottom","0px");
            
        
        else
            //Fix full-screen in mobiles
            $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
            $("#"+id+">.modal-dialog").css("margin",0);
            $("#"+id+">.modal-dialog>.modal-content").css("border",0);
            $("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);   
        
        //Aply changes on screen resize (example: mobile orientation)
        window.onresize=function()
            $("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
            h1=$("#"+id+">.modal-dialog").height();
            h2=$(window).height();
            h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
            h4=h2-(h1-h3);
            if($(window).width()>=768)
                if(h1>h2)
                    $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
                
                $("#"+id+">.modal-dialog").css("margin","30px auto");
                $("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
                $("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);               
                if($("#"+id+">.modal-dialog").height()+30>h2)
                    $("#"+id+">.modal-dialog").css("margin-top","0px");
                    $("#"+id+">.modal-dialog").css("margin-bottom","0px");
                
            
            else
                //Fix full-screen in mobiles
                $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
                $("#"+id+">.modal-dialog").css("margin",0);
                $("#"+id+">.modal-dialog>.modal-content").css("border",0);
                $("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);   
            
        ;
    );  
    //Free event listener
    $('#'+id).on('hide.bs.modal',function()
        window.onresize=function();
    );  
    //Mobile haven't scrollbar, so this is touch event scrollbar implementation
    var y1=0;
    var y2=0;
    var div=$("#"+id+">.modal-dialog>.modal-content>.modal-body")[0];
    div.addEventListener("touchstart",function(event)
        y1=event.touches[0].clientY;
    );
    div.addEventListener("touchmove",function(event)
        event.preventDefault();
        y2=event.touches[0].clientY;
        var limite=div.scrollHeight-div.clientHeight;
        var diff=div.scrollTop+y1-y2;
        if(diff<0)diff=0;
        if(diff>limite)diff=limite;
        div.scrollTop=diff;
        y1=y2;
    );
    //Fix position modal, scroll to top.    
    $('html, body').scrollTop(0);
    //Show
    $("#"+id).modal('show');

【讨论】:

【参考方案9】:

找到了一个非常老套的解决方案来解决这个问题,但它确实有效。 我在用于打开模式的链接中添加了一个类(使用数据目标),然后使用 Jquery,向该类添加了一个单击事件以获取数据目标,找到它应该打开的模式,然后然后通过Javascript打开它。对我来说效果很好。我还在我的手机上添加了一个移动检查,以便它只能在移动设备上运行,但这不是必需的。

$('.forceOpen').click(function() 
  var id = $(this).attr('data-target');
  $('.modal').modal('hide');
  $(id).modal('show');
);

【讨论】:

【参考方案10】:

主要是 Nexus 7 模态问题,模态在屏幕下方显示

  .modal:before 
    content: '';
    display: inline-block;
    height: 50%; (the value was 100% for center the modal)
    vertical-align: middle;
    margin-right: -4px;
  

【讨论】:

【参考方案11】:

对我来说,$('[data-toggle="modal"]').click(function()); 工作正常。

【讨论】:

【参考方案12】:

尽管这个问题已经很老了,但有些人在寻找改善手机模态用户体验的解决方案时仍然可能会偶然发现它。

我制作了一个库来改善 Bootrsrap 模态在手机上的行为。

引导程序 3:https://github.com/keaukraine/bootstrap-fs-modal

引导程序 4:https://github.com/keaukraine/bootstrap4-fs-modal

【讨论】:

以上是关于移动设备上的 Twitter Bootstrap 模式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Twitter Bootstrap 使网站适合移动设备?

Twitter Bootstrap 弹出框/工具提示错误与移动设备?

Twitter Bootstrap (v2.2.1) 下拉链接在移动设备上不起作用

如何使用 Twitter Bootstrap API 检测您正在使用的设备视图?

Twitter Bootstrap 和移动导航栏

Twitter Bootstrap - 如何检测媒体查询何时开始