Как реализовать свой собственный стек истории в одностраничном мобильном веб-приложении?
У меня одностраничное мобильное приложение, разработанное с помощью Backbone и Zepto.
Он корректно работает с кнопками "назад/вперед" в браузере.
Когда пользователь переходит на страницу, новое содержимое перемещается справа, так как старое содержимое перемещается влево (и из окна просмотра). Я хочу, чтобы то же самое произошло, если пользователь нажимает кнопку "вперед" браузера. Все это работает.
У меня есть класс, который я добавляю к элементу body navigate-back
, который перевернет это поведение, поэтому, когда пользователь перейдет обратно с помощью кнопки назад браузера, они видят, что содержимое сползает назад слева, а другое содержимое сдвигается вправо. В принципе, это просто противоположность идти вперед.
Мне нужно определить, перемещается ли пользователь назад, чтобы я мог вызвать альтернативное поведение. Я попытался реализовать свой собственный стек истории, но я столкнулся с множеством проблем, когда иногда он отмечает перемотку в качестве обратной навигации, которая разрушает визуальный сигнал. Теперь он спустился в клочок хаков и, вероятно, только смутил бы меня, если бы я разместил его.
Каков наилучший способ реализовать мой собственный стек истории, чтобы я мог определить, перемещается ли пользователь вперед/назад в контексте одностраничного мобильного приложения?
Ответы
Ответ 1
Я не знаю о backbone.js 1 но я помог разработать мобильное приложение, которое должно было реализовать именно такое поведение в html5, поэтому я могу дать хороший совет:
Прежде всего, хорошо знать, что существует функция history.pushState
. Большая проблема с этим заключается в том, что поддерживается до android 2.3, но не на Android от 3 до android 4.0.3. Как показывает kiranvj, это можно решить, используя популярную библиотеку history.js, которая предоставляет решение polyfill из-за отсутствия функциональности истории,
Теперь, дойдя до вашей реальной проблемы, способ, которым я реализовал анимацию направления истории, заключался в добавлении данных в функцию pushState
(history.pushState(data,title,url)
), с которой я идентифицировал логическую позицию страницы. В моем приложении я был ограничен не только горизонтальной полосой, но и в вашем случае вы будете отслеживать позицию, где любая новая загруженная страница получает позицию, которая выше, чем ваша текущая страница. Например.
History.pushState({position:History.getState().data.position+1},"Your title","Your URL");
Далее, когда триггеры событий window.onstatechange
или window.onanchorchange
вы наблюдаете, будет ли положение выше или ниже вашей текущей страницы (например, используя history.js History.getState()
, который я использовал выше), и в зависимости от этого вы решаете, в каком направлении двигаться (ниже слева, а выше - вправо), как показано на рисунке ниже:
![Illustration of history events]()
Вы также заметите, что я уже предполагал на первой странице, что у вас есть {position:1}
, тогда как обычно первая страница не будет иметь информации о состоянии. Способ, которым это может быть достигнуто, заключается в использовании history.replaceState
, который заменяет текущее пустое состояние более информативным состоянием. В качестве альтернативы вы также можете проверить наличие пустого состояния на любом из ранее упомянутых событий, и если он пуст, вы считаете его самым левым ({position:1}
).
Надеюсь, что это поможет, и если у вас возникнут дополнительные вопросы, не стесняйтесь спрашивать.
Обратите внимание, что в этом ответе предполагается, что вы используете history.js, и вам нужно будет слушать несколько разные события (например, onpopstate
) и используйте несколько разные структуры (history
, а не history
), если вы хотите создать собственное решение.
Также полезно отметить, что это можно создать с помощью собственного массива очереди, который дает вам намного больше контроля, но не будет работать в сочетании с кнопкой назад. Это большая проблема с сайтами браузера, однако это намного проще, если вы создаете cordova (aka phonegap).
1 Просто прочитайте об этом и, как представляется, выполните некоторую обработку , что может усложнить интеграцию описанной выше.
Ответ 2
У меня была такая же проблема при работе с Zepto на мобильных устройствах с одной страницей - несколько просмотров.
Первоначально я использовал html5 statechange и onhashchange. Все это имеет некоторые проблемы на одном или другом мобильном устройстве. Наконец я использовал плагин истории Zepto здесь https://github.com/browserstate/history.js
Он несколько решил большинство проблем. Попробуйте, это будет полезно, оно обрабатывает функции html4 и html5, где это возможно.
Ответ 3
Если вы работаете над истинным одностраничным приложением, почему бы вам не настроить массив для хранения URL-адресов истории в переменной js (вместо того, чтобы полагаться на что-то вроде history.pushState
и его поддержки)?
Всякий раз, когда на новую страницу перемещается, вы можете нажимать свой url в массив, всякий раз, когда нажимается кнопка "назад", вы можете получить требуемый url-адрес так далеко, как вы хотите. Это будет работать до тех пор, пока вы правильно отбросите URL-адреса, когда пользователь вернется на несколько шагов, а затем перейдет к новой ссылке.
Я никогда не пробовал внедрять это для использования в истории страниц, но это отлично работало для логики отмены-повтора на странице.
Обновление:
После дальнейших исследований вышеприведенный подход не будет работать для перезагрузки страницы, поскольку это будет действие, происходящее вне обработки истории, доступное через JS. Он по-прежнему будет работать для отслеживания переходов назад/вперед, но такая история будет потеряна при навигации по внешнему URL-адресу приложения или обновлению страницы. Ответ Дэвиду Малдеру, похоже, не хватает этого ограничения, полагаясь на историю уровня браузера, которая сохраняется за пределами области страницы.
Ответ 4
Используйте эту вещь в одностраничном мобильном приложении, это позволит истории и переместить пользователя обратно.
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}
Ответ 5
Отладка Sammy.js v.6.x(тот, который полагается только на изменения хеша) - это идеальный, самый простой, совместимый с браузером подход к истории отслеживания. Там история не отслеживается вообще, так как Сэмми просто наблюдает за хэхеем.
Опираясь на "#/slide/123", вы можете поддерживать жесткие перезагрузки страниц и упростить работу.
Снимите последнюю часть (номер слайда) на каждом просмотре страницы, нажмите на глобальную. На новом маршруте см., Если число больше или меньше того, что хранится в глобальном, и выполните правильную (левую или правую) анимацию. Если глобальное значение undefined, анимации нет.