2016-09-21 6 views
7

Протестировано в Safari и Chrome - тот же результат, поэтому я думаю, что это проблема с iOS.iOS Chrome/Safari - Нежелательная прокрутка при фокусировке ввода внутри модала

Это происходит только в том случае, если в модуле есть вход, и я нажимаю этот вход. В тот же момент этот вход становится фокусом и становится очевидной клавиатура iOS.

Приведенная ниже мода в данный момент автоматически прокручивается до 50% от ее высоты. Такое поведение совершенно нежелательно, и я не знаю, как предотвратить эту функцию iOS по умолчанию.

Демо:


UPDATE: исправление фиксации: limonte/sweetalert2/commit/4a2d36b

+0

У вас есть setTimeout или setInterval функции в вашем javascript? – poashoas

+0

Да, функция ввода автофокуса [работает с 'setTimeout()'] (https://github.com/limonte/sweetalert2/blob/bf1ee4299f3d52256ba049aa830dc16844fa220c/src/sweetalert2.js#L375-L382) из-за анимации –

+0

Это произошло только один раз в iOS Safari, и это не произошло после этого. Но в хроме это происходит каждый раз. – Prav

ответ

2

Мы сталкиваемся с аналогичной проблемой на работе, и я наткнулся на этот вопрос на вашей (отличной) демонстрационной странице.

Как вы упомянули, смещение всегда составляет ~ 50% от высоты страницы, что происходит независимо от того, где находится ваше начальное смещение.

В прошлом, когда я наблюдал подобные «прыжки» с более ранними версиями IOS (хотя, гораздо менее драматично прыжками), я обычно работал вокруг этого путем применения position: fixed (или relative) к body (this allows overflow: hidden to properly work).

Тем не менее, это приводит к непредвиденным последствиям перехода пользователя обратно в начало страницы, если они прокручиваются вниз.

Так что, если вы открыты для решения этой проблемы с некоторыми JavaScript, вот исправить/взломать я бросил вместе:

// Tapping into swal events 
onOpen: function() { 
    var offset = document.body.scrollTop; 
    document.body.style.top = (offset * -1) + 'px'; 
    document.body.classList.add('modal--opened'); 
}, 
onClose: function() { 
    var offset = parseInt(document.body.style.top, 10); 
    document.body.classList.remove('modal--opened'); 
    document.body.scrollTop = (offset * -1); 
} 

А что CSS выглядит следующим образом:

.modal--opened { 
    position: fixed; 
    left: 0; 
    right: 0; 
} 

Вот прокрутка вашей демонстрационной страницы, чтобы проиллюстрировать: https://jpattishall.github.io/sweetalert2/ios-bug.html

И для тех, кто ищет более общее исправление, вы можете сделать что-то вроде следующего ING при открытии/закрытии модального:

function toggleModal() { 
    var offset; 
    if (document.body.classList.contains('modal--opened')) { 
     offset = parseInt(document.body.style.top, 10); 
     document.body.classList.remove('modal--opened'); 
     document.body.scrollTop = (offset * -1); 
    } else { 
     offset = document.body.scrollTop; 
     document.body.style.top = (offset * -1) + 'px'; 
     document.body.classList.add('modal--opened'); 
    } 
} 

Edit: Одна вещь, чтобы отметить, что мы не применить исправление для всех устройств/платформ вслепую, только IOS Safari. Я заметил в вашем другом вопросе, что вы не поклонник переполнения: скрытый из-за смещения страницы, когда полоса прокрутки появляется/исчезает (с которой я полностью согласен). Я бы предложил просто применить JS к устройствам iOS.

+1

Ничего себе! Ваша демо работает! Наконец, рабочее решение! Ты - мой герой :) Позвольте мне попробовать реализовать это решение в sweetalert2 в приятной манере. На данный момент голосование, я отвечу на ваш ответ после тестирования. Спасибо! –

+0

какая ужасная ошибка! и это потрясающее решение. Я попытался добавить фиксированное тело, но, как вы сказали, он прокручивает страницу вверх. Выглядит действительно странно с прозрачным модальным фоном. Но отрицательная вершина работает! Кто-нибудь знает, если эта ошибка также появляется на устройствах Android? – nearpoint

0

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

Function.prototype.bind = function(parent) { 
    var f = this; 
    var args = []; 

    for (var a = 1; a < arguments.length; a++) { 
    args[args.length] = arguments[a]; 
    } 

    var temp = function() { 
    return f.apply(parent, args); 
    } 

    return(temp); 
} 


setTimeout(function() { 
    // your animation stuff here 
}.bind(this), 100); 
+0

Это выглядит как очень грязный хак. Даже если он работает, я бы не использовал его, [расширение родных объектов - плохая практика] (http://stackoverflow.com/a/14034242/1331425). –

+0

@limonte Вы правы, но не эта функция просто «копирует» себя? – poashoas

0

Одна вещь, которую я могу думать здесь, чтобы, вероятно, добавить Fast Click библиотеку кода. Некоторые проблемы с iOS и Android, такие как задержка 300ms, обрабатываются Fast Click. Это стоит сделать.