Положение: исправлено в iOS5 Перемещается, когда ввод сфокусирован

У меня есть div в верхней части моего мобильного приложения, положение: исправлено, поэтому он останется в верхней части браузера (он прокручивается в ios 4 и ниже, что нормально). Когда ввод находится в фокусе и вызывает клавиатуру, div перемещается вниз к середине страницы. Смотрите скриншоты:

http://dbanksdesign.com/ftp/photo_2.PNG

Изменить: вот упрощенная тестовая страница: http://dbanksdesign.com/test/

<body>
<div class="fixed"><input type="text" /></div>
<div class="content"></div>
</body>

.fixed { position:fixed; top:0; left:0; width:100%; background:#ccc; }
.content { width:100%; height:1000px; background:#efefef; }

person dbanksdesign    schedule 08.11.2011    source источник
comment
какой у вас код css для элементов html, body и fixed?   -  person ScottS    schedule 09.11.2011


Ответы (6)


К сожалению, вам, вероятно, лучше всего использовать absolute позиционирование для ваших fixed элементов при работе с IOS. Да, IOS5 утверждает, что поддерживает позиционирование fixed, но все это рушится, когда у вас есть интерактивные элементы управления внутри этого фиксированного элемента.

У меня была такая же проблема с окном поиска на моем сайте switchitoff.net. В IOS5 фиксированный заголовок прыгал вниз по странице, если поле поиска получало фокус во время прокрутки страницы. Я пробовал различные обходные пути, и в настоящее время у меня есть <div>, который находится над окном поиска. При нажатии на этот <div> происходит следующее:

  1. Страница прокручивается вверх
  2. Заголовок fixed изменен на absolute
  3. <div>, закрывающий поле поиска, скрыт
  4. Поиск <input> сосредоточен

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

Есть еще одна сложная проблема с IOS5 и фиксированным позиционированием. Если у вас есть интерактивные элементы в области fixed, а за ними прокручиваются body элементы, это может нарушить ваши сенсорные события.

Например, на switchitoff.net кнопки в фиксированном заголовке становились недоступными для нажатия, когда за ними прокручивались интерактивные элементы. touchstart даже не срабатывал, когда нажимались эти кнопки. К счастью, onClick все еще работает, хотя это всегда крайняя мера для IOS из-за задержки.

Наконец, обратите внимание, как (в IOS5) вы можете щелкнуть фиксированный заголовок и прокрутить страницу. Я знаю, что это эмулирует то, как вы можете использовать колесо прокрутки над фиксированным заголовком в обычном браузере, но, конечно же, эта парадигма не имеет смысла для сенсорного интерфейса?

Надеюсь, Apple продолжит совершенствовать обработку фиксированных элементов, но пока что проще придерживаться absolute позиционирования, если у вас есть что-то интерактивное в фиксированной области. Это или вернуться к IOS4, когда все было намного проще!

person JohnW    schedule 01.12.2011

Используя рекомендацию JohnW использовать absolute вместо fixed, я придумал этот обходной путь:

Сначала настройте bind, чтобы определить, когда ввод находится в фокусе, прокрутите страницу вверх и измените элемент position на absolute:

$('#textinput').bind('focus',function(e) { 
  $('html,body').animate({
        scrollTop: 0
   });
  $('#textinput-container').css('position','absolute');
  $('#textinput-container').css('top','0px');
});

Обратите внимание, что я использую идентификатор textinput для ввода и textinput-container для верхней панели div, содержащей ввод.

Настройте другую привязку, чтобы определить, когда ввод больше не находится в фокусе, чтобы изменить положение div обратно на fixed

$('#textinput').bind('blur',function(e) { 
   $('#textinput-container').css('position','fixed');
  $('#textinput-container').css('top','0px');
});

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

person pablobart    schedule 01.11.2012
comment
Хорошо работает для меня, спасибо. Я немного изменил его, чтобы делать что-либо только в фокусе, если страница действительно прокручивалась, так как в противном случае у меня было мерцание. - person Ben Clayton; 04.04.2013

Модифицированная версия решения pablobart, но без прокрутки вверх:

// Absolute position
$('#your-field').bind('focus',function(e) { 
    setTimeout(function(){
        $('section#footer').css('position','absolute');
        $('section#footer').css('top',($(window).scrollTop() + window.innerHeight) - $('section#footer').height());
    }, 100);
});

// Back to fixed position
$('#your-field').bind('focusout',function(e) { 
    $('section#footer').removeAttr('style');
});

Простой CSS: section#footer *{ position:fixed; дно:0; слева:0; высота: 42 пикселя*

person Phil    schedule 07.04.2014

Это решение работает очень хорошо для меня. Все, что делает код, это ждет, пока пользователь не нажмет на текстовое поле, а затем изменяет положение элемента, идентифицированного параметром jQuerySelector, с «фиксированного» на «статическое». Когда текстовое поле теряет фокус (пользователь нажал на что-то еще), положение элемента снова меняется на «фиксированное».

// toggles the value of 'position' when the text field gains and looses focus
var togglePositionInResponseToInputFocus = function(jQuerySelector)
{
   // find the input element in question
   var element = jQuery(jQuerySelector); 

   // if we have the element
   if (element) {

      // get the current position value 
      var position = element.css('position'); 

      // toggle the values from fixed to static, and vice versa
      if (position == 'fixed') {
          element.css('position', 'static'); 
      } else if (position == 'static') {
          element.css('position', 'fixed'); 
      }
    }
}; 

И связанные обработчики событий:

var that = this; 

// called when text field gains focus
jQuery(that.textfieldSelector).on
(
    'focusin', 
    function()
    {
        togglePositionInResponseToInputFocus(that.jQuerySelector); 
    }
);

// called when text field looses focus
jQuery(that.textfieldSelector).on
(
   'focusout',
    function()
    {
        togglePositionInResponseToInputFocus(that.jQuerySelector); 
    }
 );
person Mark Mckelvie    schedule 28.02.2013

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

Если вы можете угадать, насколько сдвинулась кнопка (исходя из того, насколько сдвинулось содержимое), вы можете нажать на невидимую кнопку, и она будет нормально функционировать. Другими словами, если содержимое прокрутилось на 50 пикселей, щелкните на расстоянии 50 пикселей от кнопки, и она сработает.

Вы можете прокрутить содержимое вручную (даже на небольшую величину), и кнопки снова будут работать как положено.

person Cliff Harris    schedule 23.02.2012

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

person Hunt Burdick    schedule 04.02.2014