Назад кнопка браузер кнопка назад
Почему же кнопки браузера не запускают свои собственные события !?
(Примечание: в соответствии с отзывами Шарки я включил код для обнаружения возврата)
Итак, я часто сталкивался с этими вопросами в SO, и недавно столкнулся с проблемой управления функциональностью кнопки возврата самостоятельно. После нескольких дней поиска лучшего решения для моего приложения (одностраничный с хэш-навигацией) я нашел простую, кросс-браузерную, безбиблиотечную систему для обнаружения кнопки «назад».
Большинство людей рекомендуют использовать:
Однако эта функция также будет вызываться, когда пользователь использует элемент на странице, который изменяет хэш расположения. Не лучший пользовательский опыт, когда ваш пользователь нажимает и страница перемещается назад или вперед.
Чтобы дать вам общее представление о моей системе, я заполняю массив предыдущими хэшами, когда мой пользователь перемещается по интерфейсу. Это выглядит примерно так:
Довольно прямо вперед. Я делаю это для обеспечения кросс-браузерной поддержки, а также поддержки старых браузеров. Просто передайте новый хеш функции, и он сохранит его для вас, а затем изменит хеш (который затем заносится в историю браузера).
Я также использую кнопку возврата на странице, которая перемещает пользователя между страницами с помощью lasthash массива. Это выглядит так:
Так что это переместит пользователя обратно к последнему хешу и удалит этот последний хеш из массива (у меня сейчас нет кнопки вперед).
Так. Как определить, использовал ли пользователь мою кнопку возврата на странице или кнопку браузера?
Сначала я посмотрел window.onbeforeunload , но безрезультатно - это вызывается, только если пользователь собирается менять страницы. Этого не происходит в одностраничном приложении, использующем хеш-навигацию.
Итак, после еще нескольких копаний я увидел рекомендации по установке переменной-флага. Проблема с этим в моем случае заключается в том, что я попытался бы установить его, но, поскольку все является асинхронным, он не всегда будет установлен вовремя для оператора if в изменении хеша. .onMouseDown не всегда вызывался в клике, и добавление его в onclick никогда не вызывало бы его достаточно быстро.
Это когда я начал смотреть на разницу между document , и window . Мое окончательное решение состояло в том, чтобы установить флаг, используя document.onmouseover , и отключить его, используя document.onmouseleave .
Что происходит, когда мышь пользователя находится внутри области документа (читай: отображаемая страница, но исключая фрейм браузера), мой логический параметр установлен на true . Как только мышь покидает область документа, логическое значение переходит на false .
Таким образом, я могу изменить свой window.onhashchange на:
Итак, вкратце, и для людей, которые не обязательно используют кнопку возврата на странице или массив для хранения истории:
Чтобы убедиться, что пользователь не использует backspace для запуска события back, вы также можете добавить следующее (спасибо @thetoolman по этому вопросу ):
+1 хорошая идея, но я думаю, что это потерпит неудачу, если пользователь использует любую комбинацию клавиш для «назад» (клавиша возврата на Firefox), в то время как его мышь находится в окне браузера
Примечание: статья посвящена обзору проблемы неработающей кнопки «назад» в браузере при использовании 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 приложения, которые могут снять с кредитной карточки сумму еще раз, если нажать кнопку «назад» в браузере.) Вес ответственности, который вы, в конечном счете, возложите на пользователя за его действия на сайте, будет зависеть от вашей корпоративной культуры, но почему бы не сделать его чуточку легче?
Спасибо всем, что читал, читает и будет читать мои переводы и статьи. Заранее хочу поблагодарить всех тех, что укажет на фактические неточности или ошибки в статье, а может быть, даст ссылки на дополнительную информацию.
Яндекс-браузер – веб-обозреватель от российского разработчика Yandex, построенный на базе Chromium. В программе реализовано множество удобных для пользователей компонентов, которые способны значительно повысить скорость работы в сети Интернет. Компания регулярно выпускает новые версии продукта и свежие патчи, однако некоторые элементы все же могут работать не совсем стабильно. В данной статье описано, почему не иногда не работает кнопка возврата назад в браузере от Яндекс, и представлено подробное руководство по решению этой неприятной проблемы.
Регулярные обновления
В отличие от многих своих конкурентов в Яндекс-браузере невозможно отключить функцию автообновления. Однако, к сожалению, это не означает, что у вас со 100% вероятностью будет самая последняя актуальная версия продукта. Загрузке и установке новых патчей может мешать установленная антивирусная программа, встроенный фаервол или действия различных вирусов. Иногда автоматическая закачка может быть запрещена системным администратором вашего офиса.
Поэтому вам следует удостовериться в том, что у вас стоит актуальная версия программы.
- Запустите обозреватель.
- Откройте панель управления с помощью символа в виде трех белых горизонтальных полосок на голубом фоне, расположенных слева от кнопок управления окном.
- Выберите категорию «Advanced» («Дополнительно»).
- В ниспадающем списке необходимо открыть пункт «About Yandex Browser» («О браузере Yandex»).
- В открывшейся закладке должна присутствовать надпись «Yandex is up to date» («Вы используете актуальную версию»).
Если данной информации там нет – то вам будет доступна специальная кнопка с названием «Update» («Обновить»). Нажмите на нее, что запустить процесс скачивания и инсталляции доступного обновления.
В случае если по какой-либо причине данная кнопка недоступна для нажатия – лучшим решением будет полная переустановка программы.
Ручная переустановка
Первым делом вам потребуется удалить обозреватель.
Запустите загруженный установочный файл и дождитесь окончания процедуры. Теперь у вас установлена самая свежая на данный момент версия программного обеспечения.
«Умная» кнопка
Объект обсуждения – значок «Стрелка влево», зачастую присутствующий во многих обозревателях, проводниках и текстовых редакторах. Эта стрелка служит для возврата назад, к предыдущей посещенной странице, директории и состоянию документа. Разработчики из Яндекс, находясь в стремлении сделать свой проект как можно более качественным, подключили к этому элементу еще несколько функций.
К тому же, на значок «навешена» функция перехода к истории последних посещений. При нажатии по символу ПКМ открывается ниспадающее контекстное меню, в котором расположены ссылки быстрого перехода на недавно открываемые сайты и окно работы с историей браузера.
Как известно, чем проще что-то устроено, тем сложнее ему выйти из строя. Подобные объекты требуют для своей работы большого количества проверок. Увеличение количества строчек исполняемого кода загромождает интерфейс, в результате чего функция может «привиснуть» во время срабатывания.
Изучите сочетания клавиш, чтобы быстрее и эффективнее пользоваться браузером Chrome.
Windows и Linux
Переместить вкладки вправо или влево с помощью клавиатуры
Ниже приведен список быстрых клавиш для работы с адресной строкой.
Действие | Сочетание клавиш |
Открыть параметры печати текущей страницы | Ctrl + P |
Открыть параметры сохранения текущей страницы | Ctrl + S |
Обновить текущую страницу | F5 или Ctrl + R |
Обновить текущую страницу без учета кешированного контента | Shift + F5 / Ctrl + Shift + R |
Остановить загрузку страницы | Esc |
Перейти от одного интерактивного элемента страницы к следующему | Tab |
Перейти от одного интерактивного элемента страницы к предыдущему | Shift + Tab |
Открыть сохраненный на компьютере файл в Chrome | Нажмите Ctrl + O и выберите файл |
Просмотреть HTML-код текущей страницы (без возможности редактирования) | Ctrl + U |
Добавить текущую веб-страницу в закладки | Ctrl + D |
Добавить все открытые вкладки в отдельную папку закладок | Ctrl + Shift + D |
Включить или отключить полноэкранный режим | F11 |
Увеличить масштаб страницы | Ctrl и + |
Уменьшить масштаб страницы | Ctrl и - |
Восстановить масштаб страницы по умолчанию | Ctrl + 0 |
Прокрутить веб-страницу вниз (одно нажатие – один экран) | Пробел / PgDn |
Прокрутить веб-страницу вверх (одно нажатие – один экран) | Shift + Пробел / PgUp |
Перейти к верхней части страницы | Home |
Перейти к нижней части страницы | End |
Прокрутить страницу по горизонтали | Удерживая Shift, прокрутите колесо мыши |
Установить курсор перед предыдущим словом в текстовом поле | Ctrl + Стрелка влево |
Переместить курсор к следующему слову | Ctrl + Стрелка вправо |
Удалить предыдущее слово в текстовом поле | Ctrl + Backspace |
Открыть домашнюю страницу в текущей вкладке | Alt + Home |
Восстановить исходный масштаб страницы | Ctrl + 0 |
Ниже перечислены быстрые клавиши, которые используются в сочетании с движениями мыши.
macOS
Навигация с помощью клавиатуры включена по умолчанию в системных настройках macOS Catalina и более поздних версий.
Совет. Чтобы выделить текстовые поля или пункты списка с помощью клавиатуры, нажмите ⌘ + F7.
Переместить вкладки вправо или влево с помощью клавиатуры
Включить выбор с помощью клавиатуры можно в разделе "Клавиатура" системных настроек macOS.
Ниже приведен список быстрых клавиш для работы с адресной строкой.
Нажмите на стрелку вниз, чтобы выделить нужную область, затем нажмите клавиши Shift + Fn + Delete
Используйте удаление вперед: на ноутбуке нажмите fn-Delete
Действие | Сочетание клавиш |
Открыть параметры печати текущей страницы | ⌘ + P |
Открыть параметры сохранения текущей страницы | ⌘ + S |
Открыть диалоговое окно "Параметры страницы" | ⌘ + Option + P |
Обновить текущую страницу без учета кешированного контента | ⌘ + Shift + R |
Остановить загрузку страницы | Esc |
Перейти от одного интерактивного элемента страницы к следующему | Tab |
Перейти от одного интерактивного элемента страницы к предыдущему | Shift + Tab |
Открыть сохраненный на компьютере файл в Google Chrome | Нажмите ⌘ + O и выберите файл |
Просмотреть HTML-код текущей страницы (без возможности редактирования) | ⌘ + Option + U |
Открыть консоль JavaScript | ⌘ + Option + J |
Добавить текущую веб-страницу в закладки | ⌘ + D |
Добавить все открытые вкладки в отдельную папку закладок | ⌘ + Shift + D |
Включить или отключить полноэкранный режим | ⌘ + Ctrl + F |
Увеличить масштаб страницы | ⌘ и + |
Уменьшить масштаб страницы | ⌘ и - |
Восстановить масштаб страницы по умолчанию | ⌘ + 0 |
Прокрутить веб-страницу вниз (одно нажатие – один экран) | Пробел |
Прокрутить веб-страницу вверх (одно нажатие – один экран) | Shift + пробел |
Искать в Интернете | ⌘ + Option + F |
Установить курсор перед предыдущим словом в текстовом поле | Option + Стрелка влево |
Установить курсор в начало следующего слова в текстовом поле | Option + Стрелка вправо |
Удалить предыдущее слово в текстовом поле | Option + Delete |
Открыть домашнюю страницу в текущей вкладке | ⌘ + Shift + H |
Восстановить исходный масштаб страницы | Command + 0 |
Ниже перечислены быстрые клавиши, которые используются в сочетании с движениями мыши.
Может кто-нибудь указать мне пример кросс-браузерного кода (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 () означает, что страница не может быть кэширована (в прямом / обратном кэше) - потому что ее состояние изменяется / может измениться, когда пользователь уходит. Так что - небезопасно восстанавливать состояние последней секунды страницы при возврате к ней путем навигации по объекту истории.
Читайте также: