Posizionamento fisso iOS 5 e tastiera virtuale


138

Ho un sito Web mobile che ha un div appuntato nella parte inferiore dello schermo tramite posizione: fisso. Tutto funziona bene su iOS 5 (sto testando su un iPod Touch) fino a quando non sono su una pagina con un modulo. Quando tocco in un campo di input e appare la tastiera virtuale, improvvisamente la posizione fissa del mio div viene persa. Il div ora scorre con la pagina finché la tastiera è visibile. Dopo aver fatto clic su Fine per chiudere la tastiera, il div torna alla sua posizione nella parte inferiore dello schermo e obbedisce alla posizione: regola fissa.

Qualcun altro ha sperimentato questo tipo di comportamento? È previsto? Grazie.


Sì, sembra che Apple non l'abbia pensata così bene per IOS5. Qualsiasi elemento di posizione fissa diventa relativo alla pagina non appena viene visualizzata la tastiera virtuale. Probabilmente sarebbe OK se gli elementi tornassero in una posizione assoluta in quanto ciò non spezzerebbe il layout. Sfortunatamente il posizionamento effettivo di questi elementi è molto meno prevedibile. Ho questo esatto problema con la mia intestazione fissa su [REDATTO]. Scorri la pagina verso il basso, quindi fai clic sulla casella di ricerca e fai scoppiare ... layout rotto. Ho anche provato a risolverlo ripristinando il posizionamento assoluto sull'evento focus, che funziona ma poi ho perso
John Williams,

2
Ho riscontrato questo stesso problema. Qualcuno ha segnalato un bug con Apple per vedere come risolvere questo problema? Inoltre, qualcun altro ha visto continuare questo comportamento in iOS6?
Robert Hui,

1
Sto riscontrando lo stesso problema con iOS6.
Redtopia,

24
Lo stesso problema sembra ancora esistere in iOS7!
Ria Weyprecht,

5
Non sembra essere stato risolto in iOS 8 ...
contactmatt

Risposte:


49

Ho avuto questo problema nella mia domanda. Ecco come ci sto lavorando:

input.on('focus', function(){
    header.css({position:'absolute'});
});
input.on('blur', function(){
    header.css({position:'fixed'});
});

Sto solo scorrendo verso l'alto e posizionandolo lì, quindi l'utente iOS non nota nulla di strano. Avvolgere questo nel rilevamento di alcuni agenti utente in modo che altri utenti non ottengano questo comportamento.


Letteralmente inciampato su questo problema oggi e questo sembrava il più ragionevole, +1.
Daniel

3
Funziona abbastanza bene. Lo chiamo solo per dispositivi iOS: var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
Redtopia,

8
Ho anche rimosso $ (window) .scrollTop (0) ... Non credo sia necessario e abbia causato uno scorrimento indesiderato.
Redtopia,

1
O semplicemente document.body.scrollTop = 0se non stai usando jQuery e non stai prendendo di mira i browser più recenti.
Langdon,

Su moduli più lunghi, l'impostazione $(window).scrollTop(0);può causare lo spostamento dell'ingresso focalizzato fuori dallo schermo, ad esempio un ingresso più in basso nella pagina o se un iPhone è in verticale. Una soluzione migliore è sul set di messa a fuoco header.css({position:'absolute',top:window.pageYOffset+'px'});e sul set di sfocatura header.css({position:'fixed',top:0});.
robocat,

16

Ho avuto un problema leggermente diverso con l'ipad in cui la tastiera virtuale ha spostato il mio viewport fuori dallo schermo. Quindi dopo che l'utente ha chiuso la tastiera virtuale il mio viewport era ancora fuori schermo. Nel mio caso ho fatto qualcosa di simile al seguente:

var el = document.getElementById('someInputElement');
function blurInput() {
    window.scrollTo(0, 0);
}
el.addEventListener('blur', blurInput, false);

3
Non mi aiuta :(
Dmitry

@Altaveron. mi dispiace sentirlo. Era per un problema specifico che stavo riscontrando su iOS6 e dispositivi inferiori. Non ho rivisitato da allora.
ds111,

14

Questo è il codice che usiamo per risolvere il problema con ipad. Fondamentalmente rileva discrepanze tra offset e posizione di scorrimento, il che significa che "riparato" non funziona correttamente.

$(window).bind('scroll', function () {
    var $nav = $(".navbar")
    var scrollTop = $(window).scrollTop();
    var offsetTop = $nav.offset().top;

    if (Math.abs(scrollTop - offsetTop) > 1) {
        $nav.css('position', 'absolute');
        setTimeout(function(){
            $nav.css('position', 'fixed');
        }, 1);
    }
});

Viene dal plugin jquery.timers. Puoi invece usare window.setTimeout.
Covata del

anche l'attivazione di questa stessa funzione su sfocatura e messa a fuoco in ingresso sarà di aiuto.
Blowsie,

Genio - scavalo davvero. Inoltre +1 al suggerimento di @ Blowsie di usare questo di messa a fuoco e sfocatura invece di scorrere.
Skone,

12

Gli elementi con posizione fissa semplicemente non aggiornano la loro posizione quando la tastiera è alzata. Ho scoperto che inducendo Safari a pensare che la pagina sia stata ridimensionata, tuttavia, gli elementi si riposizioneranno. Non è perfetto, ma almeno non devi preoccuparti di passare a 'position: absolute' e il monitoraggio cambia te stesso.

Il seguente codice ascolta solo quando è probabile che l'utente stia usando la tastiera (a causa di un input focalizzato), e fino a quando non sente uno sfocato ascolta solo gli eventi di scorrimento e quindi esegue il trucco del ridimensionamento. Sembra funzionare abbastanza bene per me finora.

    var needsScrollUpdate = false;
    $(document).scroll(function(){
        if(needsScrollUpdate) {
            setTimeout(function() {
                $("body").css("height", "+=1").css("height", "-=1");
            }, 0);
        }
    });
    $("input, textarea").live("focus", function(e) {
        needsScrollUpdate = true;
    });

    $("input, textarea").live("blur", function(e) {
        needsScrollUpdate = false;
    });

Questo in realtà non ha funzionato per me sull'iPad. Ho finito per cambiare la posizione del piè di pagina fisso in relativo e ho il piè di pagina nella parte inferiore della pagina fino a quando non è stato rilevato l'evento di sfocatura di input quando ho cambiato la posizione in fisso.
Akrikos,

6
Non funziona più, iOS probabilmente risolto qualunque bug abbia funzionato
Kevin,

6

Nel caso in cui qualcuno accada su questo thread come ho fatto durante la ricerca di questo problema. Ho trovato utile questa discussione per stimolare il mio pensiero su questo problema.

Questa è stata la mia soluzione per questo su un recente progetto. Devi solo cambiare il valore di "targetElem" in un selettore jQuery che rappresenta la tua intestazione.

if(navigator.userAgent.match(/iPad/i) != null){

var iOSKeyboardFix = {
      targetElem: $('#fooSelector'),
      init: (function(){
        $("input, textarea").on("focus", function() {
          iOSKeyboardFix.bind();
        });
      })(),

      bind: function(){
            $(document).on('scroll', iOSKeyboardFix.react);  
                 iOSKeyboardFix.react();      
      },

      react: function(){

              var offsetX  = iOSKeyboardFix.targetElem.offset().top;
              var scrollX = $(window).scrollTop();
              var changeX = offsetX - scrollX; 

              iOSKeyboardFix.targetElem.css({'position': 'fixed', 'top' : '-'+changeX+'px'});

              $('input, textarea').on('blur', iOSKeyboardFix.undo);

              $(document).on('touchstart', iOSKeyboardFix.undo);
      },

      undo: function(){

          iOSKeyboardFix.targetElem.removeAttr('style');
          document.activeElement.blur();
          $(document).off('scroll',iOSKeyboardFix.react);
          $(document).off('touchstart', iOSKeyboardFix.undo);
          $('input, textarea').off('blur', iOSKeyboardFix.undo);
      }
};

};

C'è un po 'di ritardo nella correzione che prende piede perché iOS interrompe la manipolazione del DOM mentre scorre, ma fa il trucco ...


Funziona alla grande fino a iOS 7. Qualcun altro ha problemi con l'elemento posizionato correttamente ma scompare?
Rona Kilmer,

@RonaKilmer Cambia initin una funzione normale (non auto-invocante; si accende troppo presto). Quindi chiama iOSKeyboardFix.init();subito prima della fine ifdell'istruzione.
cfr.

@cfree Grazie, l'ho implementato un po 'indietro ma non è un mio problema. C'è qualcos'altro che sta succedendo. Uno dei miei elementi fissi scompare quando viene riposizionato. L'altro no. Non posso biasimarlo sulla correzione della tastiera poiché non sta accadendo dappertutto. Non ho visto che anche qualcun altro ha lo stesso problema, quindi dovrò scavare più a fondo.
Rona Kilmer,

4

Nessuna delle altre risposte che ho trovato per questo bug ha funzionato per me. Sono stato in grado di risolverlo semplicemente scorrendo la pagina di 34px, la quantità di Safari mobile la scorre verso il basso. con jquery:

$('.search-form').on('focusin', function(){
    $(window).scrollTop($(window).scrollTop() + 34);
});

Questo ovviamente avrà effetto in tutti i browser, ma impedisce che si rompa in iOS.


4

Questo problema è davvero fastidioso.

Ho combinato alcune delle tecniche sopra menzionate e ho trovato questo:

$(document).on('focus', 'input, textarea', function() {
    $('.YOUR-FIXED-DIV').css('position', 'static');
});

$(document).on('blur', 'input, textarea', function() {
    setTimeout(function() {
        $('.YOUR-FIXED-DIV').css('position', 'fixed');
        $('body').css('height', '+=1').css('height', '-=1');
    }, 100);
});

Ho due navbar fissi (intestazione e piè di pagina, usando Twitter Bootstrap). Entrambi si sono comportati in modo strano quando la tastiera è alzata e di nuovo strana dopo che la tastiera è abbassata.

Con questa correzione temporizzata / ritardata funziona. Ogni tanto trovo ancora un problema tecnico, ma sembra essere abbastanza buono da mostrarlo al cliente.

Fammi sapere se questo funziona per te. Altrimenti potremmo trovare qualcos'altro. Grazie.


2
Non sembra che tu abbia bisogno di quel timeout (almeno funzionava bene per me senza), e se succede anche su elementi selezionati, a parte questo, questa soluzione funziona alla grande.
Phillip Gooch,

3

Ho riscontrato lo stesso problema con iOS7. Gli elementi fissi inferiori incasinerebbero la mia vista non focalizzata correttamente.

Tutto ha iniziato a funzionare quando ho aggiunto questo meta tag al mio HTML.

<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no,height=device-height" >

La parte che ha fatto la differenza è stata:

height=device-height

Spero che aiuti qualcuno.


Grazie @pasevin. Questo risolto il mio problema in iOS 9.3.2
stillatmylinux

3

Ho preso Jory Cunningham risposta e l' migliorata:

In molti casi, non è solo un elemento a impazzire, ma diversi elementi posizionati fissi, quindi in questo caso targetElemdovrebbe essere un oggetto jQuery che ha tutti gli elementi fissi che si desidera "correggere". Ho, questo sembra far sparire la tastiera iOS se scorri ...

Inutile menzionare che è necessario utilizzare questo evento del documento DOPODOM ready o appena prima del </body>tag di chiusura .

(function(){
    var targetElem = $('.fixedElement'), // or more than one
        $doc       = $(document),
        offsetY, scrollY, changeY;

    if( !targetElem.length || !navigator.userAgent.match(/iPhone|iPad|iPod/i) )
        return;

    $doc.on('focus.iOSKeyboardFix', 'input, textarea, [contenteditable]', bind);

    function bind(){
        $(window).on('scroll.iOSKeyboardFix', react);
        react();
    }

    function react(){
        offsetY = targetElem.offset().top;
        scrollY = $(window).scrollTop();
        changeY = offsetY - scrollY;

        targetElem.css({'top':'-'+ changeY +'px'});

        // Instead of the above, I personally just do:
        // targetElem.css('opacity', 0);

        $doc.on('blur.iOSKeyboardFix', 'input, textarea, [contenteditable]', unbind)
            .on('touchend.iOSKeyboardFix', unbind);
    }

    function unbind(){
        targetElem.removeAttr('style');
        document.activeElement.blur();

        $(window).off('scroll.iOSKeyboardFix');
        $doc.off('touchend.iOSKeyboardFix blur.iOSKeyboardFix');
    }
})();

2
@vsync si scusa, non avevo idea che fossi un 'maestro'
Mike

quando è selezionato, l'input focus in quel momento l'header si sta spostando verso l'alto (non visibile). Voglio correggere il div dell'intestazione quando focalizziamo select e input fileds. qualcuno per favore aiutami
VK Chikkadamalla

2

Ho una soluzione simile a @NealJMD tranne che la mia viene eseguita solo per iOS e determina correttamente l'offset di scorrimento misurando lo scollTop prima e dopo lo scorrimento della tastiera nativa, nonché utilizzando setTimeout per consentire lo scorrimento nativo:

var $window = $(window);
var initialScroll = $window.scrollTop();
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
  setTimeout(function () {
    $window.scrollTop($window.scrollTop() + (initialScroll - $window.scrollTop()));
  }, 0);
}

1

Ho corretto la posizione fissa del contenuto principale del mio iPad in questo modo:

var mainHeight;
var main = $('.main');

// hack to detects the virtual keyboard close action and fix the layout bug of fixed elements not being re-flowed
function mainHeightChanged() {
    $('body').scrollTop(0);
}

window.setInterval(function () {
    if (mainHeight !== main.height())mainHeightChanged();
    mainHeight = main.height();
}, 100);

Questo ha funzionato davvero bene per me in una complessa finestra di dialogo dell'interfaccia utente di JQUery e sulla tastiera su schermo che ha lasciato il mio layout a metà dello schermo quando i dialoghi e la tastiera sono chiusi contemporaneamente, anche se con un paio di modifiche: var main = $ (' body div '). first (); ... e ... funzione mainHeightChanged () {$ (top) .scrollTop (0); }
Awerealis,

1
setInterval... veramente? è meglio solo stare con il bug piuttosto che farlo
vsync

1

Ho avuto un problema simile a @ ds111 s. Il mio sito Web è stato spostato verso l'alto dalla tastiera ma non si è spostato verso il basso quando la tastiera è stata chiusa.

Per prima cosa ho provato la soluzione @ ds111 ma avevo due inputcampi. Ovviamente, prima la tastiera scompare, quindi si verifica la sfocatura (o qualcosa del genere). Quindi il secondoinput era sotto la tastiera, quando la messa a fuoco passava direttamente da un ingresso all'altro.

Inoltre, il "salto in alto" non è stato abbastanza buono per me poiché l'intera pagina ha solo le dimensioni dell'iPad. Quindi ho reso la pergamena liscia.

Alla fine, ho dovuto collegare l'ascoltatore di eventi a tutti gli input, anche quelli, che erano attualmente nascosti, quindi il live .

Tutti insieme posso spiegare il seguente frammento javascript come: Allegare il seguente listener di eventi di sfocatura al presente e a tutti i futuri inpute textarea(= live): attendere un periodo di grazia (= window.setTimeout(..., 10)) e scorrere senza problemi verso l'alto (= animate({scrollTop: 0}, ...)) ma solo se "nessuna tastiera è mostrato "(= if($('input:focus, textarea:focus').length == 0)).

$('input, textarea').live('blur', function(event) {
    window.setTimeout(function() {
        if($('input:focus, textarea:focus').length == 0) {
            $("html, body").animate({ scrollTop: 0 }, 400);
        }
    }, 10)
})

Tenere presente che il periodo di tolleranza (= 10) potrebbe essere troppo breve o la tastiera potrebbe comunque essere visualizzata anche se non è attiva inputo textareaè attiva. Naturalmente, se si desidera lo scorrimento più veloce o più lento, è possibile regolare la durata (= 400)


1

ha davvero lavorato duramente per trovare questa soluzione alternativa, che in breve cerca focus e sfocatura degli eventi sugli input, e lo scorrimento per cambiare selettivamente il posizionamento della barra fissa quando si verificano gli eventi. Questo è antiproiettile e copre tutti i casi (navigazione con <>, scorrimento, pulsante Fine). Nota id = "nav" è il mio div footer fisso. Puoi facilmente portarlo su js standard o jquery. Questo è dojo per coloro che usano utensili elettrici ;-)

define (["dojo / ready", "dojo / query",], function (ready, query) {

ready(function(){

    /* This addresses the dreaded "fixed footer floating when focusing inputs and keybard is shown" on iphone 
     * 
     */
    if(navigator.userAgent.match(/iPhone/i)){
        var allInputs = query('input,textarea,select');
        var d = document, navEl = "nav";
        allInputs.on('focus', function(el){
             d.getElementById(navEl).style.position = "static";
        });

        var fixFooter = function(){
            if(d.activeElement.tagName == "BODY"){
                d.getElementById(navEl).style.position = "fixed";
            }
        };
        allInputs.on('blur', fixFooter);
        var b = d.body;
        b.addEventListener("touchend", fixFooter );
    }

});

}); // fine definire


Questo potrebbe essere fantastico ... porting su jQuery / js e riporteremo indietro. A parte questo, prevedibilmente, le soluzioni nelle scelte del linguaggio di scripting di nicchia che richiedono il porting o l'aggiunta di strumenti non standard a un progetto non saranno ritenute universalmente utili.
ericpeters0n,

Questo non funzionerà per tutti i casi perché ti farà scorrere nella posizione "statica" dell'elemento, che potrebbe essere a miglia di distanza dalla posizione originale dell'input, specialmente se si trova in un contenitore fisso. Se il contenitore ha una overflow:hiddenregola, non vedrai affatto il tuo input in quanto è ora fuori dagli schemi.
James M. Lay

1

Questo è un problema difficile da ottenere "giusto". Puoi provare a nascondere il piè di pagina sul focus dell'elemento di input e mostrarlo sulla sfocatura, ma ciò non è sempre affidabile su iOS. Ogni tanto (una volta su dieci, diciamo, sul mio iPhone 4S) l'evento focus sembra non riuscire a sparare (o forse c'è una condizione di gara) e il footer non viene nascosto.

Dopo molte prove ed errori, ho trovato questa soluzione interessante:

<head>
    ...various JS and CSS imports...
    <script type="text/javascript">
        document.write( '<style>#footer{visibility:hidden}@media(min-height:' + ($( window ).height() - 10) + 'px){#footer{visibility:visible}}</style>' );
    </script>
</head>

In sostanza: utilizzare JavaScript per determinare l'altezza della finestra del dispositivo, quindi creare dinamicamente una query multimediale CSS per nascondere il piè di pagina quando l'altezza della finestra si riduce di 10 pixel. Poiché l'apertura della tastiera ridimensiona la visualizzazione del browser, ciò non fallisce mai su iOS. Poiché utilizza il motore CSS anziché JavaScript, è anche molto più veloce e fluido!

Nota: ho scoperto che usando "visibilità: nascosto" è meno glitch di "display: none" o "position: static", ma il tuo chilometraggio può variare.


1
Potrebbe essere necessario alternare tra altezza e larghezza per risolvere il problema sia in modalità verticale che orizzontale.
Neil Monroe,

1

Per me va bene

if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    $(document).on('focus', 'input, textarea', function() {
        $('header').css({'position':'static'});
    });
    $(document).on('blur', 'input, textarea', function() {
        $('header').css({'position':'fixed'});
    });
}

1

Nel nostro caso, questo si risolverebbe non appena l'utente scorre. Quindi questa è la correzione che abbiamo usato per simulare uno scorrimento blursu qualsiasi inputo textarea:

$(document).on('blur', 'input, textarea', function () {
    setTimeout(function () {
        window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
    }, 0);
});

1

La mia risposta è che non si può fare.

Vedo 25 risposte ma nessuna funziona nel mio caso. Ecco perché Yahoo e altre pagine nascondono l'intestazione fissa quando la tastiera è attiva. E Bing rende l'intera pagina non scorrevole (overflow-y: nascosto).

I casi discussi sopra sono diversi, alcuni hanno problemi durante lo scorrimento, alcuni sulla messa a fuoco o sfocatura. Alcuni hanno piè di pagina fisso o intestazione. Non posso testare ora ogni combinazione, ma potresti finire per rendermi conto che non può essere fatto nel tuo caso.


Questo non risponde alla domanda.
Neofita,

4
Lo fa, poiché la risposta è che non esiste soluzione.
Szalai Laci,

0

Ho trovato questa soluzione su Github.

https://github.com/Simbul/baker/issues/504#issuecomment-12821392

Assicurati di avere contenuti scorrevoli.

// put in your .js file
$(window).load(function(){
    window.scrollTo(0, 1);
});

// min-height set for scrollable content
<div id="wrap" style="min-height: 480px">
  // website goes here
</div>

La barra degli indirizzi si piega come bonus aggiuntivo.


0

Nel caso qualcuno volesse provare questo. Ho ottenuto il seguente lavoro per me su un piè di pagina fisso con un campo di input in esso.

<script>
    $('document').ready(
        function() {
            if (navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)
                  || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i)) {
                var windowHeight = $(window).height();
                var documentHeight = $(document).height();

                $('#notes').live('focus', function() {
                    if (documentHeight > windowHeight) {
                        $('#controlsContainer').css({
                            position : 'absolute'
                        });
                        $("html, body").animate({
                            scrollTop : $(document).height()
                        }, 1);
                    }
                });
                $('#notes').live('blur', function() {
                    $('#controlsContainer').css({
                        position : 'fixed'
                    });
                    $("html, body").animate({
                        scrollTop : 0
                    }, 1);
                });
            }
        });
</script>

0

Ho lo stesso problema. Ma mi sono reso conto che la posizione fissa è solo ritardata e non rotta (almeno per me). Attendere 5-10 secondi e vedere se il div si adatta alla parte inferiore dello schermo. Credo che non sia un errore ma una risposta ritardata quando la tastiera è aperta.


0

Ho provato tutti gli approcci da questo thread, ma se non hanno aiutato, hanno fatto anche peggio. Alla fine, ho deciso di forzare il dispositivo a perdere la messa a fuoco:

$(<selector to your input field>).focus(function(){
    var $this = $(this);
    if (<user agent target check>) {
        function removeFocus () {
            $(<selector to some different interactive element>).focus();
            $(window).off('resize', removeFocus);
        }
        $(window).on('resize', removeFocus);
    }
});

e ha funzionato come un incantesimo e risolto il mio appiccicoso modulo di accesso.

Si prega NOTA:

  1. Il codice JS sopra è solo per presentare la mia idea, per eseguire questo frammento si prega di sostituire i valori tra parentesi angolari (<>) con i valori appropriati per la propria situazione.
  2. Questo codice è progettato per funzionare con jQuery v1.10.2

0

Questo è ancora un grosso bug per tutte le pagine HTML con modali Bootstrap più alti in iOS 8.3. Nessuna delle soluzioni proposte sopra ha funzionato e dopo aver ingrandito qualsiasi campo sotto la piega di un modale alto, Mobile Safari e / o WkWebView spostavano gli elementi fissi in cui si trovava lo scroll del corpo HTML, lasciandoli disallineati rispetto a dove effettivamente si trovavano trovavano disposte.

Per risolvere il problema, aggiungi un listener di eventi a qualsiasi input modale come:

$(select.modal).blur(function(){
  $('body').scrollTop(0);
});

Immagino che funzioni perché forzare l'altezza di scorrimento del corpo HTML riallinea la vista effettiva con il punto in cui iOS 8 WebView prevede che i contenuti del div modale fisso siano.


0

Se qualcuno stava cercando un percorso completamente diverso (come se non stessi nemmeno cercando di aggiungere questo div "piè di pagina" mentre scorri, ma vuoi solo che il div rimanga nella parte inferiore della pagina), puoi semplicemente impostare la posizione del piè di pagina come parente.

Ciò significa che anche se la tastiera virtuale viene visualizzata sul tuo browser mobile, il tuo piè di pagina rimarrà ancorato alla fine della pagina, non tentando di reagire allo spettacolo o alla chiusura della tastiera virtuale.

Ovviamente su Safari sembra migliore se la posizione è fissa e il piè di pagina segue la pagina mentre scorri verso l'alto o verso il basso ma a causa di questo strano bug su Chrome, abbiamo finito col passare a rendere relativo il piè di pagina.


0

Nessuna delle soluzioni di scorrimento sembrava funzionare per me. Invece, ciò che ha funzionato è impostare la posizione del corpo su fissa mentre l'utente sta modificando il testo e quindi ripristinarlo su statico quando l'utente ha terminato. Ciò impedisce a Safari di scorrere i tuoi contenuti su di te. Puoi farlo sia su focus / sfocatura degli elementi (mostrati sotto per un singolo elemento ma potrebbe essere per tutti gli input, textareas), o se un utente sta facendo qualcosa per iniziare la modifica come l'apertura di un modale, puoi farlo su quell'azione (es. apertura / chiusura modale).

$("#myInput").on("focus", function () {
    $("body").css("position", "fixed");
});

$("#myInput").on("blur", function () {
    $("body").css("position", "static");
});

0

iOS9 - stesso problema.

TLDR - fonte del problema. Per soluzione, scorrere verso il basso

Avevo un modulo in un position:fixediframe con id = 'iscriviti-popup-frame'

Come per la domanda originale, sull'input focus l'iframe andrebbe nella parte superiore del documento rispetto alla parte superiore dello schermo.

Lo stesso problema non si è verificato in modalità Safari Safari con l'agente utente impostato su un dispositivo. Quindi sembra che il problema sia causato dalla tastiera virtuale iOS quando viene visualizzata.

Ho avuto un po 'di visibilità su ciò che stava accadendo tramite la console registrando la posizione dell'iframe (ad es. $('#subscribe-popup-frame', window.parent.document).position()) E da lì ho potuto vedere iOS sembrava impostare la posizione dell'elemento su {top: -x, left: 0}quando è spuntata la tastiera virtuale (cioè focalizzata sull'elemento input).

Quindi la mia soluzione era quella di prendere quel fastidioso -x , invertire il segno e quindi usare jQuery per aggiungere quella topposizione all'iframe. Se esiste una soluzione migliore, mi piacerebbe ascoltarla ma dopo aver provato una dozzina di approcci diversi è stata l'unica che ha funzionato per me.

Svantaggio: avevo bisogno di impostare un timeout di 500ms (forse meno avrebbe funzionato ma volevo essere sicuro) per essere sicuro di aver catturato la finalex valore dopo che iOS aveva fatto la sua malizia con la posizione dell'elemento. Di conseguenza, l'esperienza è molto brusca. . . ma almeno funziona

Soluzione

        var mobileInputReposition = function(){
             //if statement is optional, I wanted to restrict this script to mobile devices where the problem arose
            if(screen.width < 769){
                setTimeout(function(){
                    var parentFrame = $('#subscribe-popup-frame',window.parent.document);
                    var parentFramePosFull = parentFrame.position();
                    var parentFramePosFlip = parentFramePosFull['top'] * -1;
                    parentFrame.css({'position' : 'fixed', 'top' : parentFramePosFlip + 'px'});
                },500);
            }    
        }   

Quindi chiama semplicemente mobileInputRepositionqualcosa come $('your-input-field).focus(function(){})e$('your-input-field).blur(function(){})

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.