risposta-alla-domanda-sullo-sviluppo-web-bd.com

Twitter Bootstrap modal su dispositivi mobili

I mod di bootstrap non funzionano correttamente su Android e iOS. Il tracker dei problemi riconosce il problema ma non offre una soluzione funzionante:

I mod in 2.0 sono interrotti su mobile.

La finestra modale in 2.0 non si posiziona correttamente

Lo schermo si scurisce ma la modale stessa non è visibile nel viewport. È possibile trovarlo nella parte superiore della pagina. Il problema si verifica quando si scorre verso il basso sulla pagina.

Ecco una parte rilevante di 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;
}

C'è una correzione che posso applicare?

65
ty.

EDIT: An modifica modale Bootstrap non ufficiale è stata creata per risolvere i problemi di risposta/mobile. Questo è forse il modo più semplice e più semplice per porre rimedio al problema.

Da allora è stata trovata una correzione in uno dei problemi che hai discusso prima

in bootstrap-responsive.css

.modal { 
    position: fixed; 
    top: 3%; 
    right: 3%; 
    left: 3%; 
    width: auto; 
    margin: 0; 
}
.modal-body { 
    height: 60%; 
}

e in bootstrap.css

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

La risposta di Gil è promettente (la biblioteca a cui si è collegato), ma per il momento non funziona ancora quando si scorre sul dispositivo mobile.

Ho risolto il problema usando un frammento di CSS alla fine dei miei file CSS:

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

Il selettore #content è semplicemente un id che avvolge il mio html in modo da poter sovrascrivere la specificità di Bootstrap (impostato sul proprio id che include il proprio html modale).

Lo svantaggio: / Non è centrato verticalmente sui dispositivi mobili.

Il lato positivo: E 'visibile, e su dispositivi più piccoli, un modale di dimensioni ragionevoli occuperà gran parte dello schermo, quindi il "non centraggio" non sarà così evidente.

Perché funziona:

Quando si utilizzano dimensioni ridotte dello schermo con il CSS reattivo di Bootstrap, per i dispositivi con schermi più piccoli, imposta .modal.fade.in 'top' su 'auto'. Per qualche motivo i browser webkit mobili sembrano avere difficoltà a capire il posizionamento verticale con l'assegnazione "automatica". Quindi, basta riportarlo su un valore fisso e funziona benissimo. 

Poiché la modale è già impostata sulla posizione: assoluta, il valore è relativo all'altezza del viewport, non all'altezza del documento, quindi funziona indipendentemente dalla lunghezza della pagina o dal punto di scorrimento.

14
jlovison

La soluzione di niftylettuce in issue 2130 sembra risolvere le modal in tutte le piattaforme mobili ...

9/1/12 UPDATE: La correzione è stata aggiornata qui: Plugin jquery di bootstrap di Twitter

(il codice sotto è più vecchio ma funziona ancora)

// # 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
Gil Birman

Usiamo questo codice per centrare le finestre di dialogo modali Bootstrap quando si aprono. Non ho avuto alcun problema con loro su iOS durante l'utilizzo di questo, ma non sono sicuro che funzionerà per 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;
});
2
Jeradan

Certo, non ho provato nessuna delle soluzioni elencate sopra, ma alla fine ho provato un po 'di gioia quando ho provato il progetto Bootstrap-modal di jschr in Bootstrap 3 (collegato alla risposta principale). Il js mi stava dando problemi quindi l'ho abbandonato (forse il mio era un problema unico o funziona bene per Bootstrap 2) ma i file CSS da soli sembrano fare il trucco nel browser nativo 2.3.4 di Android.

Nel mio caso, ho fatto ricorso finora al rilevamento degli agenti utente (sub-ottimali) prima di utilizzare gli override per consentire il comportamento previsto nei telefoni moderni.

Ad esempio, se si desidera che tutti i telefoni Android ver 3.x e seguenti solo per utilizzare il set completo di hack, è possibile aggiungere una classe "oldPhoneModalNeeded" al corpo dopo il rilevamento degli agenti utente mediante javascript e quindi modificare le proprietà CSS di Bootstrap-modal di jschr in avere sempre .oldPhoneModalNeeded come antenato.

1

puoi aggiungere questa proprietà globalmente in 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);
 }
1
Hetdev

Per me solo $('[data-toggle="modal"]').click(function(){}); sta funzionando bene.

0

Trovato una soluzione molto hacky a questo problema, ma funziona . Ho aggiunto una classe al link che viene utilizzato per aprire il modale (Con il data-target), quindi usando Jquery, aggiunto un evento click a quella classe che ottiene il target dei dati, trova il modal che deve aprire e quindi lo apre tramite Javascript. Funziona bene per me. Ho anche aggiunto un controllo mobile sul mio in modo che venga eseguito solo su dispositivo mobile, ma non è necessario. 

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

Soprattutto il problema modale di Nexus 7, il modale stava scendendo dallo schermo

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

La mia soluzione ...

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');
}
0
infinito84

Anche se questa domanda è abbastanza vecchia, alcune persone potrebbero ancora inciampare su di essa quando cercano una soluzione per migliorare UX delle modali sui telefoni cellulari.

Ho fatto una lib per migliorare il comportamento dei modali Bootrsrap sui telefoni.

Bootstrap 3: https://github.com/keaukraine/bootstrap-fs-modal

Bootstrap 4: https://github.com/keaukraine/bootstrap4-fs-modal

0
keaukraine

OK, questo lo aggiusta. L'ho provato oggi, il 5 settembre 2012, ma devi essere sicuro di dare un'occhiata alla demo 

La soluzione di niftylettuce nel numero 2130 sembra risolvere le modali in tutto piattaforme mobili ...

AGGIORNAMENTO 9/1/12: la correzione è stata aggiornata qui: Plugin jquery per il bootstrap di Twitter

ecco il link al Demo Funziona benissimo ecco il codice che ho usato 

            title_dialog.modal();
            title_dialog.modalResponsiveFix({})
            title_dialog.touchScroll();
0
edgar