iOS 5 фиксированное позиционирование и виртуальная клавиатура

138

У меня есть мобильный веб-сайт, у которого есть div, прикрепленный к нижней части экрана через position: fixed. Все работает нормально в iOS 5 (тестирую на iPod Touch), пока я не нахожусь на странице с формой. Когда я нажимаю на поле ввода и появляется виртуальная клавиатура, внезапно фиксированная позиция моего div теряется. Теперь div прокручивает страницу, пока видна клавиатура. Когда я нажимаю «Готово», чтобы закрыть клавиатуру, div возвращается в свое положение в нижней части экрана и подчиняется правилу position: fixed.

Кто-нибудь еще испытывал подобное поведение? Ожидается ли это? Спасибо.

Jeffc
источник
Да, похоже, Apple не так хорошо продумала этот вариант для IOS5. Любые элементы с фиксированным положением становятся относительными к странице, как только появляется виртуальная клавиатура. Вероятно, было бы нормально, если бы элементы вернулись в абсолютное положение, поскольку это не нарушило бы макет. К сожалению, фактическое размещение этих элементов гораздо менее предсказуемо. У меня точно такая же проблема с моим фиксированным заголовком на [УДАЛЕНО]. Прокрутите страницу вниз, затем щелкните поле поиска и бац ... макет сломан. Я даже попытался исправить это, вернувшись к абсолютному позиционированию в событии фокуса, которое работает, но потом я проиграл
Джон Уильямс
2
Я столкнулся с той же проблемой. Кто-нибудь сообщил об ошибке в Apple, чтобы исправить это? Кроме того, кто-нибудь еще видел, что такое поведение продолжается в iOS6?
Роберт Хуэй,
1
У меня такая же проблема с iOS6.
Redtopia
24
Та же проблема, похоже, все еще существует в iOS7!
Риа Вейпрехт
5
Кажется, не исправлено в iOS 8 ...
contactmatt 01

Ответы:

49

У меня была эта проблема в моем приложении. Вот как я работаю над этим:

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

Я просто прокручиваю вверх и размещаю его там, чтобы пользователь iOS не заметил ничего странного. Оберните это в некотором обнаружении пользовательского агента, чтобы другие пользователи не видели такого поведения.

Ник Реталлак
источник
Буквально сегодня наткнулся на этот вопрос и это показалось наиболее разумным, +1.
Daniel
3
Это работает очень хорошо. Я называю это только для устройств iOS: var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
Redtopia
8
Я также удалил $ (window) .scrollTop (0) ... Я не думаю, что это нужно, и это вызвало нежелательную прокрутку.
Redtopia
1
Или просто, document.body.scrollTop = 0если вы не используете jQuery и ориентируетесь на новейшие браузеры.
Лэнгдон
В более длинных формах установка $(window).scrollTop(0);может привести к перемещению сфокусированного ввода за пределы экрана, например, ввод дальше вниз по странице или если iPhone находится в портретной ориентации. Лучшее решение - установить фокус header.css({position:'absolute',top:window.pageYOffset+'px'});и установить размытие header.css({position:'fixed',top:0});.
robocat
16

У меня была немного другая проблема с ipad, когда виртуальная клавиатура подтолкнула мое окно просмотра за пределы экрана. Затем, после того как пользователь закрыл виртуальную клавиатуру, мое окно просмотра все еще оставалось за кадром. В моем случае я сделал примерно следующее:

var el = document.getElementById('someInputElement');
function blurInput() {
    window.scrollTo(0, 0);
}
el.addEventListener('blur', blurInput, false);
ds111
источник
3
Мне не помогает :(
Дмитрий
@Altaveron. жаль это слышать. Это было связано с конкретной проблемой, с которой я столкнулся на устройствах iOS6 и ниже. С тех пор я не возвращался.
ds111
14

Это код, который мы используем для решения проблемы с ipad. Он в основном обнаруживает несоответствия между смещением и положением прокрутки, что означает, что «фиксированный» работает неправильно.

$(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);
    }
});
Люк
источник
Это из плагина jquery.timers. Вместо этого вы можете использовать window.setTimeout.
Hatch
запуск этой же функции для размытия ввода и фокусировки также поможет.
Blowsie
Гений - действительно копай. Также +1 к предложению @Blowsie использовать фокус и размытие вместо прокрутки.
Skone
12

Элементы с фиксированным положением просто не обновляют свое положение, когда клавиатура поднята. Я обнаружил, что, обманывая Safari, заставляя думать, что размер страницы изменился, элементы меняют свое положение. Это не идеально, но, по крайней мере, вам не нужно беспокоиться о переключении на «положение: абсолютное» и отслеживании изменений самостоятельно.

Следующий код просто прослушивает, когда пользователь, вероятно, будет использовать клавиатуру (из-за того, что ввод сфокусирован), и пока он не услышит размытие, он просто прослушивает любые события прокрутки, а затем выполняет трюк с изменением размера. Кажется, до сих пор у меня все работает хорошо.

    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;
    });
Райли Даттон
источник
На iPad это на самом деле не сработало. В итоге я изменил положение фиксированного нижнего колонтитула на относительное и оставил нижний колонтитул внизу страницы до тех пор, пока не было обнаружено событие размытия ввода, когда я изменил положение обратно на фиксированное.
Акрикос
6
Больше не работает, iOS, вероятно, исправила любую ошибку, из-за которой эта работа работала
Кевин
6

На всякий случай, если кто-то наткнется на эту тему, как это сделал я, исследуя эту проблему. Я нашел эту ветку полезной в стимулировании моих размышлений по этому вопросу.

Это было моим решением в недавнем проекте. Вам просто нужно изменить значение targetElem на селектор jQuery, который представляет ваш заголовок.

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);
      }
};

};

Есть небольшая задержка с фиксацией исправления, потому что iOS останавливает манипуляции с DOM во время прокрутки, но это помогает ...

Джори Каннингем
источник
Это прекрасно работает до iOS 7. У кого-нибудь еще есть проблемы с правильным позиционированием элемента, но с его исчезновением?
Рона Килмер
@RonaKilmer Измените initфункцию на обычную (не самозапускающуюся; срабатывает слишком рано). Тогда звоните iOSKeyboardFix.init();незадолго до окончания ifзаявления.
cfree
@cfree Спасибо, я реализовал это некоторое время назад, но это не моя проблема. Происходит что-то еще. Один из моих фиксированных элементов исчезает, когда он перемещается. Другой - нет. Я не могу винить в этом исправление клавиатуры, так как это происходит не везде. Я не видел, чтобы у кого-то еще была такая же проблема, поэтому мне придется копать глубже.
Рона Килмер
4

Ни один из других ответов, которые я нашел для этой ошибки, не помог мне. Я смог исправить это, просто прокрутив страницу вверх на 34 пикселя, количество, которое мобильное сафари прокручивает вниз. с jquery:

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

Это, очевидно, будет действовать во всех браузерах, но предотвращает нарушение работы iOS.

NealJMD
источник
4

Эта проблема действительно раздражает.

Я объединил некоторые из вышеупомянутых техник и пришел к следующему:

$(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);
});

У меня есть две фиксированные панели навигации (верхний и нижний колонтитулы, используя загрузку twitter). Оба вели себя странно, когда клавиатура поднята, и снова странно, когда клавиатура не работает.

С этим исправлением с задержкой / задержкой это работает. Время от времени я все еще нахожу сбой, но, похоже, он достаточно хорош, чтобы показать его клиенту.

Сообщите мне, работает ли это для вас. Если нет, мы можем найти что-нибудь еще. Спасибо.

сбежавший кот
источник
2
Кажется, вам не нужен этот тайм-аут (по крайней мере, у меня он отлично работал без него), а если также происходит с выбранными элементами, кроме этого, это решение отлично работает.
Филлип Гуч
3

У меня была такая же проблема с iOS7. Нижние фиксированные элементы испортили бы мой взгляд, не сфокусировавшись должным образом.

Все заработало, когда я добавил этот метатег в свой html.

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

То, что имело значение, было:

height=device-height

Надеюсь, это кому-то поможет.

Пасевин
источник
Спасибо @pasevin. Это
устранило
3

Я взял Jory Cunninghamответ и улучшил его:

Во многих случаях сходит с ума не один элемент, а несколько фиксированных позиционируемых элементов, поэтому в этом случае targetElemдолжен быть объект jQuery, который имеет все фиксированные элементы, которые вы хотите «исправить». Хо, похоже, клавиатура iOS исчезнет, ​​если вы прокрутите ...

Само собой разумеется, что вы должны использовать это событие ПОСЛЕ документа DOM readyили непосредственно перед закрывающим </body>тегом.

(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');
    }
})();
vsync
источник
2
@vsync извиняюсь, я понятия не имел, что вы «шеф-повар»
Майк
при выборе фокус ввода в этом заголовке времени перемещается вверх (не отображается). Я хочу исправить div заголовка при фокусировке полей выбора и ввода. любой, пожалуйста, помогите мне
VK Chikkadamalla
2

У меня есть решение, похожее на @NealJMD, за исключением того, что мое выполняется только для iOS и правильно определяет смещение прокрутки, измеряя scollTop до и после прокрутки собственной клавиатуры, а также с помощью setTimeout, чтобы разрешить собственную прокрутку:

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);
}
ChrisWren
источник
1

Я исправил фиксированное положение содержимого основного макета Ipad следующим образом:

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);
Бретт
источник
Это сработало для меня очень хорошо в сложной комбинации диалогового окна JQUery UI и экранной клавиатуры, в результате которой мой макет оставался на полпути вниз по экрану, когда диалоговое окно и клавиатура закрываются одновременно, хотя с парой правок: var main = $ (' тело div '). first (); ... и ... function mainHeightChanged () {$ (top) .scrollTop (0); }
Awerealis
1
setInterval... действительно? лучше просто остаться с ошибкой, чем делать это
vsync
1

У меня была аналогичная проблема с @ ds111 s. Клавиатура подтолкнула мой веб-сайт вверх, но не опустилась, когда клавиатура закрылась.

Сначала я попробовал решение @ ds111, но у меня было два inputполя. Конечно, сначала уходит клавиатура, потом происходит размытие (или что-то в этом роде). Итак, второйinput был под клавиатурой, когда фокус переключался напрямую с одного входа на другой.

Кроме того, «прыжок вверх» для меня был недостаточно хорош, так как вся страница имеет размер только ipad. Поэтому я сделал прокрутку плавной.

Наконец, мне пришлось прикрепить прослушиватель событий ко всем входам, даже к тем, которые в данный момент были скрыты, поэтому live .

Все вместе я могу объяснить следующий фрагмент javascript следующим образом: прикрепить следующий прослушиватель событий размытия к текущему и всем будущим inputи textarea(= live): подождать период отсрочки (= window.setTimeout(..., 10)) и плавно прокрутить вверх (= animate({scrollTop: 0}, ...)), но только если «нет клавиатуры показано "(= 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)
})

Имейте в виду, что период отсрочки (= 10) может быть слишком коротким или клавиатура все еще отображается, хотя она отсутствует inputили textareaнаходится в фокусе. Конечно, если вы хотите, чтобы прокрутка была быстрее или медленнее, вы можете настроить продолжительность (= 400)

Рауль Пинто
источник
1

действительно упорно трудился, чтобы найти этот обходной путь, который в короткие взгляды на фокус и размытия событий на входах и прокрутки, чтобы выборочно изменить позиционирование фиксированной панели, когда события происходят. Это пуленепробиваемое и охватывает все случаи (навигация с помощью <>, прокрутка, кнопка «Готово»). Обратите внимание: id = "nav" - это мой фиксированный div нижнего колонтитула. Вы можете легко перенести это на стандартный js или jquery. Это додзё для тех, кто пользуется электроинструментом ;-)

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 );
    }

});

}); // конец определения

httpete
источник
Это может быть круто ... перенос на jQuery / js и ответит. Кроме того, решения в выборе нишевых языков сценариев, которые требуют переноса или добавления нестандартных инструментов в проект, как и ожидалось, не будут сочтены универсально полезными.
ericpeters0n
Это не сработает для каждого случая, потому что при этом вы переместитесь в «статическое» положение элемента, которое может находиться в нескольких милях от исходной позиции вашего ввода, особенно если оно находится в фиксированном контейнере. Если у контейнера есть overflow:hiddenправило, вы вообще не увидите свой ввод, поскольку теперь он находится вне поля.
Джеймс М. Лэй
1

Это сложная проблема, чтобы решить ее "правильно". Вы можете попробовать скрыть нижний колонтитул при фокусе элемента ввода и показать при размытии, но это не всегда надежно на iOS. Время от времени (один раз из десяти, скажем, на моем iPhone 4S) кажется, что событие focus не срабатывает (или, возможно, есть состояние гонки), и нижний колонтитул не скрывается.

После долгих проб и ошибок я пришел к следующему интересному решению:

<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>

По сути: используйте JavaScript для определения высоты окна устройства, затем динамически создайте медиа-запрос CSS, чтобы скрыть нижний колонтитул, когда высота окна уменьшается на 10 пикселей. Поскольку открытие клавиатуры изменяет размер дисплея браузера, это никогда не перестает работать на iOS. Поскольку он использует движок CSS, а не JavaScript, он также намного быстрее и плавнее!

Примечание. Я обнаружил, что использование «visibility: hidden» менее проблемно, чем «display: none» или «position: static», но ваш пробег может отличаться.

Ричард Кеннард
источник
1
Возможно, вам придется переключаться между высотой и шириной, чтобы исправить это как для портретного, так и для ландшафтного режимов.
Нил Монро
1

Работает для меня

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

В нашем случае это исправится само, как только пользователь прокрутит страницу. Итак, это исправление, которое мы использовали для имитации прокрутки blurна любом inputили textarea:

$(document).on('blur', 'input, textarea', function () {
    setTimeout(function () {
        window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
    }, 0);
});
басарат
источник
1

Мой ответ - это невозможно.

Я вижу 25 ответов, но в моем случае ни один из них не работает. Вот почему Yahoo и другие страницы скрывают фиксированный заголовок при включенной клавиатуре. И Bing делает всю страницу не прокручиваемой (overflow-y: hidden).

Обсуждаемые выше случаи разные, у некоторых есть проблемы с прокруткой, у некоторых с фокусом или размытием. У некоторых есть фиксированный нижний колонтитул или верхний колонтитул. Я не могу сейчас проверить каждую комбинацию, но вы можете в конечном итоге понять, что в вашем случае это невозможно.

Салаи Лаци
источник
Это не отвечает на вопрос.
неофит
4
Да, потому что ответ таков: решения нет.
Szalai Laci
0

Нашел это решение на Github.

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

Убедитесь, что у вас есть прокручиваемый контент.

// 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>

Адресная строка складывается в виде дополнительного бонуса.

Ли Маккей
источник
0

На случай, если кто-то захочет попробовать это. Я получил следующую работу над фиксированным нижним колонтитулом с полем ввода в нем.

<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

У меня такая же проблема. Но я понял, что фиксированная позиция просто задерживается, а не нарушается (по крайней мере, для меня). Подождите 5-10 секунд и посмотрите, вернется ли div в нижнюю часть экрана. Я считаю, что это не ошибка, а задержка ответа при открытой клавиатуре.

Филип
источник
0

Я перепробовал все подходы из этой ветки, но если они не помогли, то стали еще хуже. В конце концов, я решил заставить устройство терять фокус:

$(<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);
    }
});

и это сработало как шарм и исправило мою липкую форму входа.

Пожалуйста Примечание:

  1. Приведенный выше код JS предназначен только для представления моей идеи. Чтобы выполнить этот фрагмент, замените значения в угловых скобках (<>) соответствующими значениями для вашей ситуации.
  2. Этот код предназначен для работы с jQuery v1.10.2
Антон Борицкий
источник
0

Это по-прежнему серьезная ошибка для любых HTML-страниц с более высокими модами Bootstrap в iOS 8.3. Ни одно из предложенных решений выше работали и после масштабирования на любом поле ниже складок высокого модальный, Mobile Safari и / или WkWebView будет двигаться неподвижными элементами , где прокручивать HTML тела располагались, оставляя их смещено с тем, где они на самом деле , где выложил.

Чтобы обойти ошибку, добавьте прослушиватель событий к любому из ваших модальных входов, например:

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

Я предполагаю, что это работает, потому что принуждение высоты прокрутки тела HTML повторно выравнивает фактическое представление с тем местом, где iOS 8 WebView ожидает фиксированного модального содержимого div.

глубинапервыйдизайнер
источник
0

Если кто-то искал совершенно другой маршрут (например, вы даже не хотите закреплять этот div «нижний колонтитул» при прокрутке, но вы просто хотите, чтобы этот div оставался внизу страницы), вы можете просто установить положение нижнего колонтитула как родственник.

Это означает, что даже если виртуальная клавиатура появится в вашем мобильном браузере, нижний колонтитул останется привязанным к нижней части страницы, не пытаясь реагировать на показ виртуальной клавиатуры или закрытие.

Очевидно, что в Safari лучше выглядит, если положение фиксировано, а нижний колонтитул следует за страницей при прокрутке вверх или вниз, но из-за этой странной ошибки в Chrome мы в конечном итоге переключились на относительный нижний колонтитул.

Терри Бу
источник
0

Ни одно из решений для прокрутки, похоже, не помогло мне. Вместо этого сработало то, что положение тела было зафиксировано, пока пользователь редактирует текст, а затем восстановлено статическое, когда пользователь закончит. Это удерживает сафари от прокрутки вашего контента на вас. Вы можете сделать это либо в фокусе / размытии элемента (ов) (показано ниже для одного элемента, но может быть для всего ввода, текстовых полей), либо если пользователь что-то делает, чтобы начать редактирование, например, открытие модального окна, вы можете сделать это действие (например, модальное открытие / закрытие).

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

$("#myInput").on("blur", function () {
    $("body").css("position", "static");
});
Скотт Семян
источник
0

iOS9 - такая же проблема.

TL; DR - источник проблемы. Для решения прокрутите вниз

У меня была форма в position:fixediframe с id = 'subscribe-popup-frame'

Согласно исходному вопросу, при фокусе ввода iframe переместится в верхнюю часть документа, а не в верхнюю часть экрана.

Та же проблема не возникала в режиме safari dev с пользовательским агентом, установленным на idevice. Кажется, проблема вызвана виртуальной клавиатурой iOS, когда она появляется.

Я получил некоторое представление о том, что происходило, когда консоль регистрировала позицию iframe (например $('#subscribe-popup-frame', window.parent.document).position()), и оттуда я мог видеть, что iOS, похоже, устанавливает позицию элемента, {top: -x, left: 0}когда виртуальная клавиатура появляется (т.е. фокусируется на элементе ввода).

Итак, моим решением было принять это надоедливое -x, поменять знак и затем использовать jQuery, чтобы добавить эту topпозицию обратно в iframe. Если есть лучшее решение, я хотел бы его услышать, но после того, как я испробовал десяток различных подходов, он оказался единственным, который у меня сработал.

Недостаток: мне нужно было установить тайм-аут в 500 мс (возможно, сработало бы меньше, но я хотел быть в безопасности), чтобы убедиться, что я зафиксировал окончательное xзначение после того, как iOS испортила положение элемента. В результате опыт очень отрывистый. . . но по крайней мере это работает

Решение

        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);
            }    
        }   

Тогда просто позвони mobileInputRepositionчто-нибудь вроде $('your-input-field).focus(function(){})и$('your-input-field).blur(function(){})

Martellalex
источник