Браузер кнопка назад показаны элементы с 1 по 5 всего элементов 29
Может кто-нибудь указать мне пример кросс-браузерного кода (Firefox, Opera, Safari, IE, . ), который решает эту проблему? Я знаком с pageshow событием Firefox, но, к сожалению, ни Opera, ни Safari не реализуют это.
@romkyns: ваш комментарий не имеет отношения к этому вопросу. Когда браузеры не восстанавливают состояние JS / DOM, они запускают событие загрузки.
Ребята, я обнаружил, что JQuery имеет только один эффект: страница перезагружается при нажатии кнопки назад. Это не имеет ничего общего с « готов ».
Как это работает? Ну, JQuery добавляет прослушиватель событий onunload .
По умолчанию это ничего не делает. Но почему-то это вызывает перезагрузку в Safari, Opera и Mozilla - независимо от того, что содержит обработчик событий.
Не можете в это поверить? Попробуй это:
Вы увидите похожие результаты при использовании JQuery.
Вы можете сравнить с этим без onunload
Очень хорошо . хотя это недокументированная функция / ошибка, хотя и может просто перестать работать в будущих версиях браузера, но это все еще интересно.
Это связано с тем, что браузер предполагает, что страница не кэшируется, если у нее есть onunload обработчик (страница уже все уничтожила; зачем ее кэшировать?).
Кажется, что ответ не работает в современных браузерах - проверено в последних версиях Chrome и Opera
load Событие не должно огня , когда страница загружается из этого bfcache. Например, если вы создали свой пользовательский интерфейс в обработчике «load», и событие «load» было запущено один раз при начальной загрузке и во второй раз, когда страница была перезагружена из bfcache, страница в итоге получит дубликаты элементов интерфейса.
По этой же причине добавление обработчика «unload» останавливает сохранение страницы в bfcache (что замедляет переход к ней) - обработчик unload может выполнять задачи очистки, которые могут привести страницу в нерабочее состояние.
Для страниц, которые должны знать, когда они перемещаются назад или обратно, Firefox 1.5+ и версия Safari с исправлением для ошибки 28758 поддерживают специальные события, называемые «pageshow» и «pagehide».
Это очень круто. Сейчас я нахожусь в ситуации, когда мои манипуляции с dom не сохраняются в bfcache. Есть ли ситуации, когда вы могли бы ожидать этого?
@Benson: возможные причины, по которым Firefox не будет сохранять вашу страницу в bfcache, перечислены на странице dev.mo, на которую я ссылался. Я не думаю, что возможно сохранить страницу в bfcache, но определенное состояние DOM не будет сохранено.
@Greg: вы имеете в виду разработчика, управляющего страницей? Запустите AJAX-запрос от слушателя страниц.
Я столкнулся с проблемой, что мой js не выполнялся, когда пользователь нажимал назад или вперед. Сначала я решил остановить кеширование браузера, но, похоже, это не проблема. Мой javascript был настроен на выполнение после загрузки всех библиотек и т. Д. Я проверил это с помощью события readyStateChange.
После некоторого тестирования я обнаружил, что readyState элемента на странице, где был нажат назад, не «загружен», а «завершен». Добавление || element.readyState == 'complete' к моему условному заявлению решило мои проблемы.
Просто подумал, что поделюсь своими выводами, надеюсь, они помогут кому-то еще.
Изменить для полноты
Мой код выглядел следующим образом:
В приведенном выше примере кода переменной сценария был недавно созданный элемент сценария, который был добавлен в DOM.
Где ты это добавил? И как вы получили что-нибудь, чтобы выстрелить после того, как пользователь отвечает? Пожалуйста, покажите нам код!
Я проверил это в Opera 9.5, IE7, FF3 и Safari, и это работает во всех из них.
Я не мог заставить приведенные выше примеры работать. Я просто хотел вызвать обновление определенных измененных областей div при возврате на страницу с помощью кнопки назад. Уловка, которую я использовал, состояла в том, чтобы установить скрытое поле ввода (называемое «грязным битом») в 1, как только области div изменились от оригинала. Скрытое поле ввода на самом деле сохраняет свое значение, когда я нажимаю назад, поэтому при загрузке я могу проверить этот бит. Если он установлен, я обновляю страницу (или просто обновляю div). Однако при первоначальной загрузке этот бит не установлен, поэтому я не трачу время на загрузку страницы дважды.
Если я правильно помню, то добавление события unload () означает, что страница не может быть кэширована (в прямом / обратном кэше) - потому что ее состояние изменяется / может измениться, когда пользователь уходит. Так что - небезопасно восстанавливать состояние последней секунды страницы при возврате к ней путем навигации по объекту истории.
Как перехватить событие возврата на страницу, чтобы можно было ее обновить?
Вам нужно не перехватывать "назад", а сохранять изменения на первой странице (на бэкенд, или на клиенте, в local storage или куки), и восстанавливать его при навигации назад.
@Qwertiy незапощенные ответы на SO сохраняет браузер, а на все остальное они забили из соображений простоты :)
Изменения на первой странице и так сохраняются (на сервере), но чтобы их восстановить - требуется перехватить событие возврата на страницу.
3 ответа 3
Раз пользователь может изменить вид страницы, значит, работает javascript. В нем надо при обработке пользовательских действий подменить последний элемент в истории браузера, чтобы возврат происходил уже на указанную вами страницу (или тот же адрес, но с параметрами).
В таком случае (обработка любого перехода по ссылке) лучше все-таки использовать replaceState , а не pushState . Иначе пользователю придется нажимать кнопку "назад" два раза, чтобы покинуть эту страницу.
В качестве примера приведен довольно глючный сайт, особенно под отладчиком он не хотел нормально работать, плюс куча минифицированного кода, в котором не разберешься. Но что интересно - нужный функционал там был. Правда, он был не в javascript, а в заголовке Cache-Control: no-cache, no-store, must-revalidate. У меня же было просто Cache-Control: no-cache.
В комментариях верно написали, что ответ кроется не в перехвате события "назад" у браузера, а сохранении состояния страницы
Например, пользователь может изменить тему страницы. Что бы при возвращении на эту страницу, была выбрана нужная тема, сохраним ее в localStorage
Дальше, при нужных вам событиях, вы просто сохраняете в localStorage нужные вам данные, а при загрузке страницы ( onload событие, например) выгружаете нужные данные и используете их
Перехватить событие возврата на страницу не получилось, задача решена другим способом.
При обновлении страницы по F5 также получаем с сервера самое последнее состояние страницы.
Если бы состояние хранилось не на сервере, пришлось бы дописать немного JavaScript-кода (для работы с localStorage или куками), но history.replaceState я бы использовать не стал. Вместо хранения состояния (на стороне клиента) в history, гораздо удобнее хранить то же самое состояние в localStorage.
Проблема может быть продемонстрирована просто. Все, что вам нужно, это функция, которая обновляет страницы в ответ на действия пользователя:
И маленькая заметка:
В реальной жизни, ваша веб-странице делала бы что-то более сложное, – например получение нового содержания с сервера через AJAX, но простого обновления достаточно для демонстрации концепции. Давайте посмотрим, что происходит, когда пользователь посещает страницу:
DoClick() функция может быть обновлена, для того чтобы воспользоваться преимуществом истории API. Каждый раз, когда страница обновляется, она также будет устанавливать location.hash:
Обновление состояния веб-страницы
Обновление истории является лишь частью проблемы, вы также должны обновить состояние страницы в соответствии с состоянием в истории. Так как вы являетесь тем, кто управляет историей, это ваша задача управлять состоянием страницы. Для того чтобы обновить страницу, в ответ меняется location.hash, и вы можете прослушать hashchange события:
DoClick() функция теперь только отвечает за обновление временных переменных и изменений хэш. Hashchange события находятся в окне объекта; когда это происходит, вы убедитесь, что хэш существует. В реальном приложении, вам также нужно было бы убедиться, что у него есть правильное значение. Далее, вы установите значение раз, чтобы быть номером в хэш. Наконец, вы обновите документ, чтобы он отображал правильное состояние страницы. Давайте посмотрим на этот новый код:
Использование location.hash
Но что касается состояния об информации, то только хеш позволяет хранить эту строку. Вы могли бы кодировать более сложный объект, но URL быстро станет длинным и громоздким и не будет запоминающимся для ваших пользователей. Если вам нужно сохранить более сложную информацию как часть истории, лучшим подходом было бы использовать хэш в качестве ключевого звена, чтобы вытянуть дополнительную информацию о состоянии из других хранилищ. Для этого HTML5 предоставил вам API с history.pushState() методом и popstate событием. Эти методы позволяют сохранить и перезагрузить сложные объекты.
Популярность отзывчивого веб-дизайна привела к широкому распространению формата длинных, состоящих из одной колонки веб-страниц. Причем это характерно не только для мобильных, но и для десктопных версий сайтов. В свою очередь, следствием такого дизайна стало появление так называемой кнопки возврата в начало страницы (back-to-top button), которая в один клик позволяла пользователям вернуться в верхнюю часть сайта.
Необходимость вернуться к началу сайта может возникнуть по разным причинам. Чаще всего пользователи возвращаются обратно, чтобы:
- открыть главное меню и выбрать новое направление поиска;
- воспользоваться возможностями системы фильтров и сортировки;
- ввести или изменить запрос в поле поиска.
Операционные системы и некоторые браузеры уже предлагают своим пользователям простые и быстрые способы вернуться к началу страницы: нажатием кнопки Home на клавиатуре, кликом по вкладке в Яндекс.Браузер, использованием команд из контекстного меню и пр.
Однако, хотя технически подкованные пользователи, скорее всего, уже давно осведомлены обо всех этих способах, большинство остается в неведении. Эти методы не столь очевидны для среднего пользователя Сети, который привык прокручивать страницу при помощи пальца или мыши.
Когда страница очень длинная (например, из-за бесконечного скроллинга), ее ручная прокрутка через экраны контента становится делом весьма утомительным. Таким образом, кнопка возврата к началу страницы оказывается очень и очень востребованной.
Ниже — 9 рекомендаций, в каких случаях следует использовать эту кнопку и как сделать ее действительно эффективной.
9 рекомендаций по созданию эффективных «back-to-top»-кнопок
1. Используйте эту кнопку на страницах, длина которых превышает 3-4 экрана. Для относительно коротких страниц такая кнопка будет излишней — люди смогут отмотать страницу и вручную без особых проблем. Не стоит загромождать интерфейс, если полоса прокрутки или простой тап существенно не усложнят опыт пользователя.
2. Разместите кнопку в правом нижнем углу страницы и сделайте ее постоянной (даже при скроллинге она не должна исчезать из виду). Это именно то место, где пользователи и ожидают ее увидеть — оно хоть и находится где-то в стороне от основного контента, но остается заметным. Размещение кнопки в другом месте обычно делает ее более незаметной.
3. Пометьте кнопку словом «Наверх» или фразой «Вернуться к началу». Если ограничитесь одной иконкой (например, стрелкой, указывающей вверх), можете оказаться непонятыми. Неоднозначное графическое исполнение может привести к ошибочной интерпретации назначения кнопки.
MedlinePlus.gov: предназначение одиноко стоящей стрелки слишком туманно. Текстовая надпись могла бы помочь преодолеть любое непонимание в данном контексте
Вариант, предложенный Вконтакте
4. Заведите одну постоянную кнопку для каждой страницы. Не стоит повторять эти кнопки в каждой секции одной и той же страницы (такое обычно встречается на страницах с анкорными ссылками). Согласно результатам юзабилити-исследований, люди игнорируют эти дублирующие друг друга ссылки, потому что они слишком предсказуемы.
5. Кнопки должны быть небольших размеров и не перекрывать важные элементы страницы. Однако, если речь идет о мобильной версии сайта, то кнопка должна быть достаточно большой, чтобы на нее было удобно кликать пальцем.
6. На фоне всей страницы кнопка должна выделяться. Если кнопка будет сливаться с окружающими элементами или фоном, маловероятно, что кто-нибудь заметит ее и использует.
7. Рассмотрите вариант использования отложенного появления кнопки, когда ссылка появляется только после того, как пользователь обнаружит свое желание отмотать страницу обратно (например, начинает перемещать ползунок полосы прокрутки вверх). Таким образом, кнопка будет появляться только тогда, когда в ней будет возникать необходимость, без риска закрыть собой какие-либо важные составляющие сайта.
8. Сделайте кнопку стационарной. Как только кнопка появилась, не позволяйте ей изменять свое положение. Движущиеся элементы сильно раздражают и отвлекают, поскольку глаза человека автоматически реагируют на каждое движение, происходящее на экране.
9. Позвольте людям контролировать прокрутку. Не делайте так, чтобы страница прокручивалась автоматически. Лучше ограничиться уведомлением и предоставить пользователю самостоятельно решить, стоит ли ему прокручивать страницу, чтобы посмотреть новый контент, или нет.
Альтернативы кнопке возврата к началу страницы
Есть множество альтернативных способов, как помочь людям попасть туда, куда они хотят. Кнопка «Вернуться к началу» — одно из средств достижения этой цели. Если вы сможете предвидеть то, в чем будут нуждаться пользователи, и предложить им это, будет даже лучше. Ниже приведены несколько идей.
1. Навигация в футере страницы может удовлетворить тех, кто хочет вернуться к началу, только чтобы открыть меню и выбрать другой раздел. Этот подход работает лучше, когда пользователи склонны прокручивать очень длинные страницы до самого футера.
2. Липкие меню иногда более элегантное решение, чем back-to-top-кнопки. Если основная цель прокрутки — перейти к другим разделам сайта, то липкое меню, которое будет всегда под рукой, просто избавит людей от необходимости возвращаться.
Аналогично, если цель прокрутки вверх — получить доступ к функциям, как правило, размещенным в верхней части сайта (системы фильтров и сортировки, поиск и т.д.), вы можете просто-напросто закрепить эти инструменты, так что они будут оставаться доступными всегда, либо появляться тогда, когда человек начинает прокручивать страницу вверх.
3. Кнопка «Домой» (Home) на социальных сайтах часто возвращает пользователя к началу его главной страницы, которая по сути является страницей с длинной лентой новостей (фидом). Большинство людей ассоциируют клик по кнопке Home с возвратом к началу этой ленты.
Хотя кнопка «Домой» и работает на социальных сайтах, на других типах веб-ресурсах на нее рассчитывать не стоит. На обычных сайтах, кликая по кнопке «Домой», люди будут ожидать возврата к главной странице сайта, а не к началу текущей страницы.
Заключение
Сегодня существует большое количество методов и техник быстрого возврата пользователей к верхним частям страницы. Прежде чем вы остановите свой выбор именно на back-to-top-кнопке, рассмотрите и другие варианты и постарайтесь понять, какой из них наиболее предпочтителен для вашей аудитории.
Примечание: статья посвящена обзору проблемы неработающей кнопки «назад» в браузере при использовании AJAX-методов для передачи содержания страниц от сервера к клиенту. В статье рассматриваются основные принципы работы AJAX и возможные пути решения заявленной проблемы. Курсивом даны мои комментарии.
Эта статья является первой из ряда материалов (вторая статья посвящена работе с закладками), направленных на устранение части критики, которую адресуют сейчас AJAX, и предоставляющих обзор полезных методов, которые помогут сделать ваши приложения и веб-страницы, использующие технику AJAX, немного лучше.
Суть проблемы
С самого начала в основе Веба лежала возможность поставить гиперссылку с одной страницы на другую. Ссылки между страницами была первично двунаправленными: это означало, что переход по ссылке со страницы А на страницу Б никаким образом не мог предотвратить ни переход по ссылке обратно на страницу А, ни использование кнопки «назад» в браузере. Цепочка таких страниц представляет собой историю посещения в браузере, с каждой из них связан уникальный URL. Если представить это с технической стороны, то такая цепочка реализуется в виде стека. В дальнейшем я буду использовать термин «горизонтальная» ссылка для обозначения связи между элементами такого стека.
Рисунок 1. Горизонтальные ссылки
Рисунок 2. Вертикальная ссылка между вторым URL'ом и сервером
Веб-сайт и веб-приложение
Подход, который стоит использовать для решения этой проблемы, напрямую зависит от того, что вы разрабатываете: веб-сайт или веб-приложение. Иногда тяжело разделить эти два понятия, но обычно веб-приложение можно отличить по следующим свойствам:
- Перед использованием требуется авторизация
- Серьезная работа с пользовательскими сессиями
- Процесс взаимодействия пользователя с приложением имеет вполне определенное начало и конец
В качестве примера веб-сайта можно рассмотреть Yahoo! Finance и E*TRADE — в качестве веб-приложения. С точки зрения пользователя я могу сказать, что не всегда возможно провести четкую границу между этими двумя типами. Однако, веб-разработчикам стоит с самого начала определиться, что же они собираются разрабатывать: сайт или приложения? Если вам это понять, то можно задать простой вопрос: в отсутствии интернета чем лучше всего описывается ваша разработка: это набор Word'овых документов или же настольное приложение? Рассматривайте веб-приложения наравне с настольными с той лишь разницей, что первым еще требуется браузер для нормальной работы. Другой вопрос, который можно себе задать, звучит так: «Вашей главной целью будет предоставление информации или обеспечение функциональности?».
Первое решение: не злоупотребляйте вертикальными ссылками
Если вы собираетесь создать веб-сайт для публичного доступа, я бы советовал вам использовать AJAX только в случаях крайней необходимости (не злоупотреблять им). Возможно, будет требоваться изменение URL'а страницы, чтобы обновить ее всю, но при этом, я полагаю, иделогия правильной работы кнопки «назад» в браузере будет соблюдена. Помните, что не все вызовы AJAX сильно связаны с вертикальными ссылками (прим.: как я понимаю, автор имеет в виду прежде всего изменение каких-либо малых частей страницы при неизменном основном содержимом).
Легче всего просто не принимать во внимание неработоспособность кнопки «назад» в браузере, но полностью этим пренебрегать нельзя. Вместо того, чтобы создавать целостное приложение, использующее большое количество вертикальных ссылок и привязанное к единственному URL'у, создайте некоторое количество горизонтальных ссылок в тех местах, где это действительно требуется. Другими словами, используйте горизонтальные ссылки для разделения частей вашего приложения, например, таким образом, как это делается в бумажной литературе (книга делится на части и главы). Используя разумную комбинацию традиционных горизонтальных ссылок с вертикальными, можно добиться баланса мощи AJAX и возможности использовать функционал перемещения по истории браузера.
Прим.: в качестве примера, пожалуй, можно привести некоторое количество современных сайтов, на которых AJAX используется только для предоставления некоторых дополнительных возможностей, в частности, это Хабрахабр и механизм голосования/добавления комментариев.
Второе решение: используйте специальную AJAX-библиотеку
Прим.: ниже сгруппированы основные методы создание псевдо-горизонтальных ссылок, я постарался дополнить их известными мне примерами, расширив список статьи-первоистоника.
-
Прим.: суть решения: при каждом вызове AJAX к URL'у страницы в качестве якоря добавляется текущий номер элемента в стеке «истории», фактически, просто увеличивающиеся числа. При нажатии кнопки «назад» в браузере, URL страницы меняется на предыдущий. Каждые 100 (200, 400, 1000) миллисекунд страница проверяет, не изменился ли у нее якорь в URL'е, если якорь изменился, то осуществляется подгрузка данных, соответствующих текущему якорю (=элементу в стеке «истории»).
Подход Brad Neuberg'а, эта библиотека пытается быть максимально кроссбраузерной без лишнего усложнения кода. Хорошо, что она доступна под BSD opensource лицензией. Brad опубликовал пошаговую инструкцию создания этой библиотеки, равно как и онлайн-демо.
Plex — AJAX framework с открытым кодом, который поддерживает очень много возможностей, в том числе, и эмуляцию кнопки «назад» в браузере.
Dojo — еще один AJAX framework с открытым кодом, обеспечивающий некоторую AJAX функциональность и эмуляцию кнопки «назад» в браузере.
Не могу также не упомянуть про неплохую обзорную статью Vladimira Kelmana, в которой обсуждаются часть вышеупомянутых решений.
Решение третье: обеспечьте пользователям удобную альтернативу кнопки «назад»
Традиционно, кнопка «назад» служила для реализации концепции: «Верните меня туда, откуда я пришел» Однако, при нажатии на нее многие пользователи, на самом деле, подразумевают «отмените то, что я только что сделал». Чтобы избавить их от сооблазна воспользоваться кнопкой «обратно» не по назначению, можно создать кнопки с функциями «Отменить» или «Шаг назад» в вашем веб-приложении, использующем AJAX. Например, если вы разрабатываете в Вебе расширенный текстовый редактор, создайте кнопку «Отменить», которая предотвратит потерю пользователями целого документа при неверном нажатии кнопки «назад» в браузере.
Однако, самим плохим решением из всех, которые я видел, является создание альтернативной кнопки «назад» в пределах самой веб-страницы, используя AJAX-методы. Многие пользователи с трудом смогли привыкнуть к границе между браузером и веб-страницей, смогли понять, где кончается браузер и начинается, собственно, сама страница. Нет никакой необходимости усиливать их неудобства. Ведь вы не можете гарантировать, что те пользователи, которые легко с этим справились, смогут привыкнуть еще к одной «инновации» и изменят свои привычки ради вашего сайта. Обеспечить пользователей альтернативной навигацией и функционалом будет вполне достаточно, но никак не создавать эту кнопку заново.
В заключении, если вы все же ограничиваете функционал стандартной истории в браузере при создании веб-приложения, пожалуйста, поставьте пользователей об этом в известность тем или иным способом. AJAX не является первым методом, который ограничивает этот функционал, и, скорее всего, пользователи впервые узнают об этом тоже не от вас. (Есть еще апплеты, Flash и eCommerce приложения, которые могут снять с кредитной карточки сумму еще раз, если нажать кнопку «назад» в браузере.) Вес ответственности, который вы, в конечном счете, возложите на пользователя за его действия на сайте, будет зависеть от вашей корпоративной культуры, но почему бы не сделать его чуточку легче?
Спасибо всем, что читал, читает и будет читать мои переводы и статьи. Заранее хочу поблагодарить всех тех, что укажет на фактические неточности или ошибки в статье, а может быть, даст ссылки на дополнительную информацию.
Читайте также: