Браузер кнопка назад вне зоны по страничной навигации
До настоящего момента практически все приложения строились на базе одного экземпляра класса MainPage, производного от Page. В результате мы даже не замечали, что этот экземпляр MainPage задается свойству Content объекта типа Frame, а этот объект Frame задается свойству Content экземпляра класса Window. Эта иерархия сводится воедино в методе OnLaunched стандартного класса App. Код реализации (который будет приведен позднее) проверяет возможные ошибки и следит за тем, чтобы инициализация выполнялась только один раз, но по сути простейший случай выглядит так:
Класс Frame является производным от ContentControl, но свойство Content напрямую не задается. Вместо этого метод Navigate получает аргумент Type, который ссылается на класс, производный от Page. Метод Navigate() создает экземпляр этого типа (в данном случае MainPage); созданный, этот экземпляр становится свойством Content объекта Frame и основным центром взаимодействия с пользователем.
В ваших программах для перехода от одной страницы к другой будет использоваться метод Navigate. Он существует в двух версиях: версия в методе OnLaunched передает данные объекту Page, а другая версия этого не делает. (Вы увидите, как это работает, позднее.)
Класс Page определяет удобное свойство Frame, так что в классе, производном от Page, вызов Navigate может выглядеть так:
В многостраничном приложении метод Navigate часто вызывается многократно с разными аргументами типа. Во внутренней реализации класс Frame поддерживает стек посещенных страниц. Класс Frame также определяет методы GoBack и GoForward со свойствами CanGoBack и CanGoForward типа bool.
Проект SimplePageNavigation содержит уже не один, а два класса, производных от Page. В этом проекте также используется шаблон Blank App, так что класс MainPage, как обычно, создается Visual Studio. Чтобы добавить в проекте еще один класс, производный от Page, я выбрал команду Add New Item из меню Project, а затем выбрал в диалоговом окне Add New вариант Blank Page (не Basic Page!). Новому классу страницы было присвоено имя SecondPage.
Файл фонового кода использует переопределение OnNavigatedTo для установки и снятия блокировки кнопок перехода вперед и назад в зависимости от свойств CanGoForward и CanGoBack, определенных классом Frame. Три обработчика Click вызывают Navigate (со ссылкой на объект SecondPage), GoForward и GoBack:
Класс SecondPage содержит точно такой же код, за исключением того, что он использует метод OnGotoButtonClick для перехода к MainPage:
Кнопки перехода вперед и назад заблокированы. Если щелкнуть на кнопке «Перейти на вторую страницу», программа переходит к этой странице.
В этом случае в нашей программе метод OnNavigatedTo становится лишним, но любая программа, реализующая страничную навигацию, обычно использует этот метод в других целях - как и его «родственника» OnNavigatedFrom.
Эксперименты с SimplePageNavigation - нажатия различных кнопок для перехода вперед, назад, ввод символов в полях TextBox - выявляют одну очень важную особенность навигации. При переходе от одной странице к другой - посредством вызова Navigate, GoForward или GoBack - поле TextBox изначально пусто. Это означает, что для каждого нажатия кнопки создается новый экземпляр MainPage или SecondPage. Данные, введенные в текстовом поле на предыдущей странице, теряются, потому что экземпляр Page, содержащий этот экземпляр TextBox, уничтожается.
Класс Page определяет три виртуальных метода, упрощающих задачу организации навигации. Это методы с именами OnNavigatingFrom, OnNavigatedFrom (обратите внимание на различия в именах!) и OnNavigatedTo. Если зарегистрировать вызовы этих трех методов, а также вызовы конструктора классов Page и выдачу событий Loaded и Unloaded, определяется следующая последовательность действий при переходе от одной страницы к другой:
Старая страница | Новая страница |
---|---|
OnNavigatingFrom | |
Конструктор | |
OnNavigatedFrom | |
OnNavigatedTo | |
Loaded | |
Unloaded |
Эта последовательность происходит независимо от того, происходит ли переход в результате Navigate, GoForward или GoBack.
До этой статьи мы рассматривали экземпляр MainPage так, словно он существует на всем протяжении жизненного цикла приложения - и это действительно так, если это единственный класс, производный от Page. Но в многостраничных приложениях приходится учитывать возможность создания и уничтожения экземпляров классов, производных от Page. Постарайтесь проектировать свои классы, производные от Page, так, чтобы назначение обработчиков событий и получение ресурсов выполнялось во время OnNavigatedTo или Loaded, а отсоединение обработчиков и освобождение ресурсов - во время OnNavigatedFrom или Unloaded.
Если вы хотите, чтобы при каждом переходе к странице создавался новый экземпляр вашего класса, производного от Page, - считайте, что вам повезло, потому что именно это происходит по умолчанию. Если вы предпочитаете иное поведение, есть две альтернативы - одна простая, другая посложнее.
Простая альтернатива - задание свойству NavigationCacheMode объекта Page значения, отличного от используемого по умолчанию члена перечисления Disabled. Например:
Также возможен вариант Required, но в этой программе Enabled и Required работают одинаково. Когда вы задаете для объекта Page режим Enabled или Required, в приложении создается и кэшируется только один экземпляр каждого класса, производного от Page. Этот экземпляр используется повторно при каждом переходе к странице независимо от того, произошел ли он из-за Navigate, GoForward или GoBack. Последовательность вызовов методов и событий остается такой же, как в приведенной ранее таблице, при первом переходе к конкретному типу страницы; во всех последующих переходах используется та же последовательность, но без конструктора. Допускается задание разных значений NavigationCacheMode для разных классов Page.
Эта альтернатива может идеально подойти для архитектуры, в которой пользователь может от центральной страницы MainPage перейти к нескольким разным вторичным страницам, а потом снова вернуться к MainPage. Различие между режимами Enabled и Required заключается в том, что Enabled может разрешить уничтожение созданных экземпляров в том случае, если количество кэшированных страниц превысит свойство CacheSize объекта Frame, которое по умолчанию равно 10, но может быть изменено.
Однако в общем случае вы, вероятно, захотите создавать новый экземпляр для вызова Navigate, но использовать существующие экземпляры для GoForward и GoBack. Этот вариант не реализуется простым заданием свойства, но вскоре я покажу, как это делается.
Стек возврата
В доисторические времена у браузеров была кнопка Back, но не было кнопки Forward. Браузер реализовал функциональность кнопки Back очень простым способом: посещенные страницы сохранялись в хорошо знакомой структуре данных, называемой стеком. В контексте браузера он назывался стеком возврата (back stack): каждый раз, когда браузер переходил к новой странице, предыдущая страница заносилась в стек. Когда пользователь нажимал кнопку Back, браузер извлекал страницу из стека и переходил к ней. Если стек оставался пустым, кнопка Back становилась недоступной.
Реализация кнопки Forward несколько усложняет этот процесс. Вместо стека для хранения информации о посещенных страницах браузеру приходится использовать упорядоченный список (который, впрочем, по традиции часто называют стеком возврата). В этот список входит текущая страница. Каждый раз, когда браузер переходит к новой странице» он добавляет ее в конец списка. Но когда пользователь нажимает кнопку Back, текущая страница не удаляется из списка, а остается в нем на случай, если пользователь нажмет кнопку Forward.
Очевидно, при помощи кнопок Back и Forward пользователь может как угодно переходить между этими шестью страницами. Когда текущая страница достигает нижней позиции, кнопка Back блокируется. Когда она занимает верхнюю позицию списка, блокируется кнопка Forward.
Кнопка Forward становится недоступной. Блокировка будет снята только тогда, когда пользователь нажмет кнопку Back.
Класс Frame ведет внутренний стек возврата посещенных страниц. Приложение не может напрямую обращаться к этому стеку и даже получить его размер. Впрочем, можно узнать позицию текущей страницы в стеке возврата из свойства BackStackDepth, доступного только для чтения. Когда приложение только начинает выполняться и переходит к исходной странице, BackStackDepth возвращает значение 0. В четырех примерах, приведенных выше, значение BackStackDepth равно 5, 1, 2 и 3 соответственно.
Свойство BackStackDepth содержит важную информацию — оно позволяет конкретному классу страницы однозначно идентифицировать свой конкретный экземпляр. Давайте посмотрим, как это делается.
События навигации и восстановление страниц
Как правило, когда программа вызывает GoBack или GoForward для возвращения к конкретной странице, пользователь должен увидеть содержимое ранее посещенной страницы. Вы уже знаете, что эта функциональность не реализуется автоматически: когда свойство NavigationCacheMode имеет значение по умолчанию Disabled, вызовы GoBack и GoForward всегда приводят к созданию нового экземпляра класса Page. В режиме Enabled или Required существующие экземпляры класса Page используются повторно, но они также используются повторно и для вызова Navigate.
Как упоминалось ранее, класс Page определяет три виртуальных метода, связанных с навигацией. Метод OnNavigatingFrom используется нечасто. Аргументы события относятся к типу NavigatingCancelEventArgs, позволяющему отменить переход.
Во время перехода от одной страницы к другой (в результате вызова Navigate, GoBack или GoForward) за вызовом OnNavigatedFrom первой страницы следует вызов OnNavigatedTo второй страницы. Оба эти метода имеют аргументы типа NavigationEventArgs. Эти аргументы также используются в других контекстах (например, в классе WebView), так что некоторые их свойства не актуальны в этих переопределениях. Свойства, играющие важную роль для событий навигации, перечислены ниже:
Свойство Parameter типа object — задается по необязательному второму аргументу метода Navigate и используется для передачи данных между страницами. Вскоре этот процесс будет рассмотрен более подробно.
Свойства Content и SourcePageType всегда относятся к странице, на которую осуществляется переход. Объект Content содержит фактический экземпляр класса, производного от Page, a SourcePageType определяет тип этого экземпляра — иначе говоря, первый аргумент вызова Navigate, используемого для создания этой страницы. Эта информация представляет реальную ценность только в переопределении OnNavigatedFrom. В переопределении OnNavigatedTo свойство Content равно this, а свойство SourcePageType равно результату вызова GetType.
Свойство NavigationMode содержит значение из перечисления NavigationMode, состоящего из членов New, Refresh, Back и Forward. Значения New и Refresh относятся к переходам, выполняемым методом Navigate. Значение Refresh относится к обновлению страницы, выполняемому посредством перехода со страницы на себя. Значения Back и Forward относятся к переходам по методам GoBack и GoForward соответственно.
Свойство NavigationMode играет ключевую роль в реализации архитектуры, в которой для вызова Navigate создается новое содержимое страницы (если свойство NavigationMode равно New), но не в том случае, когда страница посещалась ранее, а переход осуществляется кнопками Back или Forward.
Все начинается с того, что класс, производный от Page, определяет поле для сохранения и восстановления своего состояния:
Словарь используется практически так же, как словарь ApplicationData.LocalSettings, который я впервые представил в программе PrimitivePad в одной из предыдущих статей. Однако вместо сохранения настроек приложения по событию Application.Suspending и их восстановлению при повторном запуске приложения состояние страницы сохраняется в словаре в переопределении OnNavigatedFrom и восстанавливается в OnNavigatedTo.
Что такое «состояние страницы»? Совокупность данных, введенных пользователем, и всего, что этим вводом обусловлено: состояние флажков, переключателей, ползунков и особенно текстовых полей. В нашем примере приложения единственным действительно важным компонентом состояния страницы является содержимое элемента TextBox. Мы можем сохранить его в обработчике OnNavigatedFrom с соответствующим ключом:
Состояние восстанавливается в OnNavigatedTo:
Возможно, есть и другие свойства TextBox, которые вам хотелось бы сохранить и восстановить (например, SelectionStart и SelectionLength), но пока мы не будем усложнять задачу. Процесс сохранения и восстановления состояния страницы в словаре абсолютно бесполезен, если для каждого события навигации будет создаваться новый экземпляр класса Page, потому что новый экземпляр pageState будет создаваться как часть новой страницы! Вам придется также добавить сохранение экземпляров этого словаря в другом словаре, определенного как статический, чтобы он совместно использовался всеми экземплярами этой страницы:
Значения в словаре представляют собой экземпляры типа Dictionary, который я назвал statePage. Ключи словаря являются значениями BackStackDepth, что позволяет связывать разные словари statePage с фиксированными позициями экземпляра страницы в стеке возврата.
Если в приложении используется несколько типов, производных от Page и использующих этот прием, вам стоит определить оба словаря в классе, производном о Page, который будет использоваться в качестве базового класса для других страниц. Статический словарь pages будет совместно использоваться всеми страницами приложения.
Посмотрим, как работает эта схема в контексте простого приложения. Программа VisitedPageSave определяет класс с именем SaveStatePage. Для создания этого класса я использовал простой шаблон Class; файл XAML с ним не связывается. Класс является производным от Page, а два словаря определяются как защищенные, чтобы к ним можно было обращаться из производных классов:
Экземпляр статического словаря создается в его определении (или в статическом конструкторе), в отличие от экземплярного словаря. Как вы вскоре увидите, экземпляр может создаваться в переопределении OnNavigatedTo, если свойство NavigationMode равно New.
Я создал класс SecondPage так же, как в приложении SimplePageNavigation, но и в файле XAML, и в файлах фонового кода MainPage и SecondPage базовый класс Page был заменен на SaveStatePage. В остальном файлы MainPage.xaml и SecondPage.xaml ничем не отличаются от файлов приложения SimplePageNavigation.
Два файла фонового кода практически одинаковы. Ниже приведен файл MainPage.xaml.cs с уже знакомыми реализациями обработчиков Click для кнопок:
Свойству NavigationCacheMode оставлено значение по умолчанию Disabled, так что по всем событиям навигации создается новый объект страницы.
В переопределении OnNavigatedTo в качестве целочисленного ключа статического словаря используется свойство BackStackDepth. Если режим NavigationMode отличен от New, метод просто использует этот ключ для получения словаря pageState, соответствующего этой позиции стека возврата, а затем использует словарь для инициализации страницы - в нашем примере поля TextBox:
Но если свойство NavigationMode равно New, значит, переход к странице был выполнен вызовом Navigate, и страница должна рассматриваться как новая и неинициализированная. Дополнительная логика выполняется в реализации метода OnNavigatedTo из SaveStatePage, который вызывается в конце переопределений OnNavigatedTo в MainPage и SecondPage. Этот код создает новый словарь pageState и добавляет его в статический словарь pages:
Однако из статического словаря pages также необходимо удалить все возможные элементы с равными или большими значениями ключей BackStackDepth. Эти элементы возникают из-за вызовов GoBack, не имеющих парных вызовов GoForward. Чтобы инструкция for, удаляющая эти элементы, стала более понятной, стоит учесть, что для существующего ключа метод Remove класса Dictionary возвращает false:
И в MainPage, и в SecondPage переопределение OnNavigatedFrom получается более простым; оно ограничивается сохранением состояния в существующем словаре pageState:
Также следует учесть, что словарь pageState может сохранять много других элементов - столько, сколько необходимо для воссоздания полного состояния всей страницы.
Если приостановить, а затем продолжить выполнение этого приложения из Visual Studio, вы увидите, что все данные восстанавливаются правильно. Однако приложение ничего не сохраняет при приостановке, поэтому если приложение будет завершено во время приостановки, при следующем запуске оно откроется в новом, несохраненном состоянии. Вероятно, это не то, на что вы рассчитывали, но проблема решается достаточно просто.
Примечание: статья посвящена обзору проблемы неработающей кнопки «назад» в браузере при использовании 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 приложения, которые могут снять с кредитной карточки сумму еще раз, если нажать кнопку «назад» в браузере.) Вес ответственности, который вы, в конечном счете, возложите на пользователя за его действия на сайте, будет зависеть от вашей корпоративной культуры, но почему бы не сделать его чуточку легче?
Спасибо всем, что читал, читает и будет читать мои переводы и статьи. Заранее хочу поблагодарить всех тех, что укажет на фактические неточности или ошибки в статье, а может быть, даст ссылки на дополнительную информацию.
Примечание. Если в настройках в разделе Дополнительно включена опция Переключать вкладки свайпом от края экрана , то листание будет переключать вас не между страницами истории просмотра, а между открытыми вкладками.
Просмотреть список открытых вкладок
Нажмите значок с количеством вкладок (, если открыто три вкладки).
Закрыть вкладку
Нажмите значок с количеством вкладок (, если открыто три вкладки).
Увеличить масштаб страницы
Если вы не нашли информацию в Справке или у вас возникает проблема в работе Яндекс.Браузера, опишите все свои действия по шагам. По возможности сделайте скриншот. Это поможет специалистам службы поддержки быстрее разобраться в ситуации.
Примечание. Для решения проблем в работе сервисов Яндекса обращайтесь в службу поддержки этих сервисов:
О проблемах Яндекс.Браузера на компьютере пишите прямо из браузера: → Дополнительно → Сообщить о проблеме или через форму.
О проблемах в работе приложения Яндекс — с Алисой пишите через форму.
Если вопрос касается главной страницы Яндекса (изменить тему оформления, настроить блоки главной страницы или иконки сервисов, найти Яндекс.Деньги и т. д.), пишите через форму. Выберите опцию Вопрос о главной странице Яндекса .
По вопросам работы Почты (отключить рекламу, настроить сбор писем с других ящиков, восстановить удаленные письма, найти письма, попавшие в спам и т. д.) пишите через форму.
По вопросам работы Поиска и выдачи (ранжирование сайта в результатах поиска, некорректные результаты поиска и т. д.) пишите через форму.
","prev_next":<"prevItem":<"disabled":false,"title":"Импорт истории и закладок","link":"/support/browser-mobile-android-phone/personal-settings/import.html">,"nextItem":>,"breadcrumbs":[,],"useful_links":null,"meta":,"voter":""prevItem":
","lang":>,"extra_meta":[>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>],"title":"Управление жестами - Яндекс.Браузер для смартфонов с Android. Справка","productName":"Яндекс.Браузер для смартфонов с Android","extra_js":[[,"mods":,"__func137":true,"tag":"script","bem":false,"attrs":,"__func67":true>],[,"mods":,"__func137":true,"tag":"script","bem":false,"attrs":,"__func67":true>],[,"mods":,"__func137":true,"tag":"script","bem":false,"attrs":,"__func67":true>]],"extra_css":[[],[,"mods":,"__func69":true,"__func68":true,"bem":false,"tag":"link","attrs":>],[,"mods":,"__func69":true,"__func68":true,"bem":false,"tag":"link","attrs":>]],"csp":<"script-src":[]>,"lang":"ru">>>'>"current":"ru","available":["ru","en"]>
Перейти на предыдущую или следующую страницу
Примечание. Если в настройках в разделе Дополнительно включена опция Переключать вкладки свайпом от края экрана , то листание будет переключать вас не между страницами истории просмотра, а между открытыми вкладками.
Просмотреть список открытых вкладок
Закрыть вкладку
Увеличить масштаб страницы
Если вы не нашли информацию в Справке или у вас возникает проблема в работе Яндекс.Браузера, опишите все свои действия по шагам. По возможности сделайте скриншот. Это поможет специалистам службы поддержки быстрее разобраться в ситуации.
Примечание. Для решения проблем в работе сервисов Яндекса обращайтесь в службу поддержки этих сервисов:
О проблемах в работе приложения Яндекс — с Алисой пишите через форму.
Если вопрос касается главной страницы Яндекса (изменить тему оформления, настроить блоки главной страницы или иконки сервисов, найти Яндекс.Деньги и т. д.), пишите через форму. Выберите опцию Вопрос о главной странице Яндекса .
По вопросам работы Почты (отключить рекламу, настроить сбор писем с других ящиков, восстановить удаленные письма, найти письма, попавшие в спам и т. д.) пишите через форму.
По вопросам работы Поиска и выдачи (ранжирование сайта в результатах поиска, некорректные результаты поиска и т. д.) пишите через форму.
Разработчики операционной системы андроид и производители телефонов часто прибегают к использованию различных кнопочных и жестовых навигационных систем для управления техникой. Жесты — это будущее, но пока что они не так функциональны, как обычные клавиши навигации. Еще эффективнее они становятся после их настройки. В связи с этим многие часто интересуются, как поменять кнопки местами на андроид и как убрать кнопки навигации на андроид полностью.
Настройка нижней панели навигации на Android
Настройка панели навигации на андроиде позволяет переназначить некоторые действия и добавить дополнительные клавиши для создания скриншотов, управления программами, а также многое другое.
Навигация с помощью кнопок очень удобная
Обратите внимание! Процесс конфигурирования может помочь в случае, если пропали кнопки внизу экрана андроид-устройства.
Если пользователь ищет ответ на вопрос, как поменять местами кнопки на андроид 9, необходимо выяснить, какими средствами он хочет пользоваться. Можно попробовать заменить назначение клавиш с помощью стандартного функционала, а можно изменить их внешний вид или вообще удалить навигацию через сторонние программные продукты.
Раздел, содержащий работу с навигацией
Как поменять кнопки местами на андроид
Прелесть экранных кнопок в том, что их можно поменять местами и переназначить. Процесс выглядит проще, чем работа с аналоговыми клавишами. В примере ниже дана инструкция для телефонов Huawei и Honor, но ее также можно применять и на других девайсах. Выглядит она следующим образом:
- Перейти в приложение «Настройки» («Параметры»).
- Открыть главный раздел конфигураций. Часто он называется «Система».
- Выбрать пункт «Системная навигация».
- Найти раздел «Навигация» или «Навигационные кнопки» и перейти в его параметры.
- Определить наиболее удобную комбинацию расположения клавиш.
- Применить изменения и сохранить настройки.
На некоторых версиях андроид соответствующие разделы и пункты могут называться по-другому, но находятся по аналогичному пути. Если найти их не получается, можно воспользоваться встроенным поиском по конфигурациям телефона.
Важно! Достаточно указать одно из следующих ключевых слов: «кнопки», «клавиши», «навигация». Далее просто выбирают подходящий пункт и работают в нем.
Сменить кнопки можно в стандартных настройках некоторых моделей
Как убрать кнопки навигации на Android
Часто пользователи интересуются вопросом, как скрыть кнопки навигации на андроид. Некоторые больше предпочитают управление жестами. Сделать это можно таким способом:
- Включить или разблокировать свой гаджет.
- Перейти в его главное меню и найти там «Настройки».
- Найти раздел параметров «Система» и подраздел «Системная навигация».
- Войти в конфигурацию «Навигационные кнопки», где осуществлялась настройка кнопок в предыдущем разделе.
- Перевести ползунок пункта «Скрыть навигационные клавиши» в состояние «Активно».
Есть и другой способ, основанный на использовании сторонних программ. Одна из самых популярных — GMD Full Screen Immersive Mode . Представляет собой утилиту, которая не только скрывает панель навигации операционной системы, но и работает с аналогичными настройками в пользовательских приложениях.
Обратите внимание! Основное ее преимущество заключается в том, что для работы не требуются рут-права, а сама система при этом нисколько не теряет в производительности. Достаточно войти в нее и добавить программу в автозагрузку.
Убрать нижнюю панель на андроид можно с помощью GMD Full Screen Immersive Mode
Как вернуть кнопки внизу экрана на андроид
Часто проблема с исчезнувшими кнопками решается очень просто. Достаточно перейти в раздел настроек телефона, в котором производилось отключение или переназначение, и активировать управление устройством с помощью навигационных клавиш. То есть необходимо следовать той же инструкции, что была дана выше, только выполнить деактивацию тумблера.
Иногда ситуация, когда пропала кнопка «Домой» на андроиде, случается непосредственно после обновления прошивки или каких-либо сбоев. Для решения проблемы потребуются ПК, специальные USB-драйвера, а также программы Android SDK и ADB, которая уже имеется в первом ПО.
Процесс выглядит следующим образом:
Что делать, если пропала кнопка «Домой»
Еще одна частая проблема заключается в том, что кнопка «Home» («Домой») на смартфоне или планшете может исчезать. Восстановить ее чаще всего можно без дополнительных средств, но все упирается в причину, вызвавшую неисправность.
Обратите внимание! Если виртуальная клавиша исчезла или перестала выполнять свои функции из-за изменения настроек, то следует вернуться в тот же пункт приложения «Параметры» и вернуть все как было или выполнить переназначение навигационных клавиш.
Часто пропажа кнопки «Домой» с дисплея мобильного устройства случается из-за критического бага операционной системы, который был вызван тем или иным сбоем в прошивке. В такой ситуации рекомендуют перепрошить девайс новой и стабильной версией ОС андроид или попытаться выполнить полный сброс до заводских параметров.
Второй вариант менее радикальный и часто помогает избавиться от последствий сбоев, которые могли быть вызваны конфликтами пользовательских и предустановленных программ.
Как скрыть верхнюю панель на андроиде
Если вопрос о том, как убрать панель навигации в Android, уже решен, то можно рассмотреть процедуру, позволяющую спрятать или полностью убрать верхнюю панель уведомлений. На новых телефонах для этого достаточно открыть шторку уведомлений, нажать на значок «Конфигурации», перейти в пункт «System UI Tuner» и деактивировать все параметры подраздела «Status bar».
На более старых смартфонах замена верхней и нижней панелей на время или навсегда осуществляется через сторонние программы. В качестве примера GMD Full Screen Immersive Mode.
К сведению! Приложение доступно для скачивания во многих проверенных сервисах, но из Google Play Market по неизвестным причинам было удалено. Несмотря на это, его можно спокойно найти на 4PDA.
После процесса загрузки и установки начинается работа. Для конфигурирования достаточно просто открыть программу, активировать режим GMD Immersive и выбрать один из трех вариантов отображения:
- без каких бы то ни было панелей;
- со всеми возможными панелями;
- только с панелью уведомлений.
Сразу же после этого выбранный интерфейс пользователя будет скрыт из операционной системы до тех пор, пока не захочет выполнить его возврат. Восстанавливать UI также просто: выбирают стиль GMD Immersive, который позволяет отобразить верхний прямоугольник уведомлений.
Возвращать внешний вид панели порой приходится только через сброс настроек
Настроить панель навигации можно не только стандартными настройками, но и специализированными программами. Они позволяют не только отключать панель полностью, но и изменять ее внешний вид. Иногда кнопки могут сами отказать работать. В этом случае рекомендуют перепрошить гаджет или выполнить сброс его настроек.
Сооснователь системы мобильной аналитики Mixpanel Сухаил Доши — о том, как измерять продукт.
Я основал Mixpanel, написав первую строку кода в октябре 2008 года. Мне тогда было лет 20, жил с родителями. И спустя десять лет в компании работало уже более 300 сотрудников. Получили немного денег. Сейчас у нас около 7000 платёжеспособных клиентов, и мы приближаемся к $100 млн годового дохода.
Мы создаём графики, помогаем измерять то, что происходит с продуктом, когда кто-то приглашает друга в приложение. Определяем воронку, уровень конверсии и удержания пользователей.
- Понятен ли пользователям ваш продукт? Первые полтора года мы в Mixpanel изрядно помучились над этим. Пришлось многое изменить.
- Хорошо, пользователи понимают продукт. Но начиная уже с первого дня пользования, считают ли они программу достаточно простой в обращении? Это бесконечная задача, которую вы берёте на себя, когда основываете компанию и начинаете поставлять свой продукт.
- И наконец, пользуются ли люди вашим продуктом снова?
- Количество посетителей.
- Сколько пользователей зарегистрировались.
- Сколько поняли ценность продукта.
- Удержание клиента.
- Количество пользователей, поделившихся продуктом.
Это и есть ваши рычаги управления.
Но даже крупные и средние компании допускают ошибки в определении этих показателей.
Так, например, выглядела главная страница Mixpanel в 2009 году. Наш логотип с тех пор изменился. Дизайн создан мной. В тексте на сайте масса ошибок, орфография всегда была моей проблемой.
Почему-то я думал, что я знаю, каким должен быть слоган: «Метрики, которые заставят вас пускать слюни». Подозреваю, потому что эти графики и диаграммы казались мне такими привлекательными по сравнению со всем остальным. Я считал, именно это будет ценностью продукта нашей компании.
Конечно это неправильно. Тогда у меня не было пользователей, я не знал, кому нужен мой продукт. Я нацеливался на все рынки сразу. Все ошибки, которые можно сделать в лендинге, были и в моём сайте. Единственное, что я сделал правильно, — кнопку регистрации.
После огромной работы, многих итераций, разговоров с клиентами и измерений страница превратилась в это. Тут я сделал правильный логотип. Кнопка подписки огромная и жёлтая. К этому времени мы перешли от «Метрик, которые заставят вас пускать слюни» к «Действия говорят громче, чем просмотры страниц».
Вы видите, как велика разница. Причина в том, что нам как компании нужно было ответить на главную претензию пользователей: «Круто, но я не понимаю, чем вы отличаетесь от Google Analytics». Вышло так, что новый слоган на главной странице продержался в течение следующих пяти лет. Он выделял нашу компанию как место, где мы измеряем вовлечённость.
Мы сделали что-то новое. Google — больше про просмотры, мы — про то, что люди делали в вашем приложении, и это сработало. Потом мы пытались стимулировать клиентов оценивать пользу своего сайта.
Как определить ясность продукта:
Обычно на старте разработчики тратят много сил, чтобы создать множество функций, которые, по их мнению, будут важны и удобны для пользователей.
Но если вы своим основным инструментом не попали в точку, то шанса продемонстрировать остальные «фишки» просто не будет. Например, молодому сайту просто не нужна кнопка «Забыл пароль», так как зарегистрировавшихся пользователей ещё очень мало.
Однажды я разговаривал с экспертом YC Робби Уолкером. Он сказал, что в PowerPoint раньше не было даже кнопки «Сохранить», потому что никто из пользователей не спрашивал: «Слушайте, а могу я это сохранить?». То есть они хотели сначала посмотреть, будет ли кто-то вообще пользоваться презентациями PowerPoint.
И первые полтора года у нас в Mixpanel не было кнопки «Забыл пароль», потому что это было не в приоритете.
Со временем мы стали получать много запросов от пользователей. Когда я проверил журнал действий, то увидел, что люди переходили на вкладку регистрации раз пять. Меня это удивило. Я подумал, что это потому, что они не могут зарегистрироваться. В итоге мы сделали кнопку. Если бы не ввели эту функцию, то просто потеряли бы клиентов.
К слову, некоторые даже после этого не нажимали кнопку «Забыл пароль», они продолжали попытки ввода. Для этого мы сделали как в Facebook — после третьего неудачного раза входа на сайт на почту приходит письмо: «Перейдите по ссылке, чтобы зарегистрироваться. Не беспокойтесь за пароль или смену пароля, просто залогиньтесь».
Прекрасный пример удобного в использовании продукта — Google. Вы открываете сайт, печатаете и сразу же получаете результат.
Более сложный пример — Airbnb. Там потребуется около десяти шагов, чтобы найти желаемое. Мы работали с Airbnb какое-то время, помогали им оптимизировать сайт для пользователя.
У них сложная структура: надо заполнить форму, вам выдают результаты, затем надо выбрать среди результатов наиболее подходящий, сравнить цены, интерьер и прочее, в конце — забронировать место.
Airbnb нужно было понять:
- как описать предложение, что людям полезно;
- как сделать процесс отбора и бронирования быстрее и легче.
Сейчас сайт Airbnb выглядит так. Теперь достаточно ответить на простые вопросы на главной странице — и всё.
Это выглядит просто, но понять, что такой подход — то, что нужно, — действительно трудно. Чтобы прийти к сегодняшнему решению, компания, возможно, меняла дизайн раз 50.
Воронка — главный инструмент для измерения удобства сайта. Вы можете оценить, как много людей переходят от лендинга к подписке, смотрят видео на сайте, открывают поиск и так далее.
Последнее — скорость. Как быстро пользователь «войдёт» в продукт. Это многие не проверяют. Этот показатель зависит от вида бизнеса. Иногда медленно — это хорошо. В Mixpanel мы над этим долго думали.
Это одна из метрик, которую часто игнорируют большинство стартапов. Из-за этого умирают многие компании. Продемонстрирую на графике.
Я называю его эффектом плавника акулы, потому что кривая похожа на рыбий плавник в воде.
Когда вы начинаете продвигать свой продукт в Facebook или Instagram, получаете массу пользователей — вроде бы всё хорошо. Проблема в том, что зачастую компании не думают об удержании и так же быстро теряют клиентов, как и получили. А получить новых пользователей становится сложнее, а если вы потеряете всех — останется только перезапускать продукт.
Важно отслеживать вернувшихся пользователей за длительные периоды времени: месяц и более. Полезна и следующая метрика — количество ежедневных активных пользователей.
Сколько продуктов вы используете каждый день? Если вы просто посмотрите на телефон и различные приложения на экране, то поймёте, что это очень жёсткая метрика. Мы заметили, что есть чёткая связь между этим показателем и количеством отказов — пользователи перестают платить за продукт.
Если ваш отток выручки составляет 7% в месяц, вы можете подумать: «Здорово, у меня остаётся 93% всей суммы». Проблема в том, что это 7% только ежемесячного оттока, и если вы посчитаете отток за 12 месяцев, то окажется, что вы теряете 58% своего дохода в год.
Как только ваш основной доход достигает высокого уровня, становится действительно сложно успевать всё, и у вас выходит такая длинная дуга, похожая на эффект плавника акулы. В итоге получается медленный рост на протяжении четырёх или пяти лет, если компания способна получать новых пользователей.
Когда у нас было около десяти клиентов, я их всех просто добавил в общий чат в Google+. Сейчас можно использовать любой другой мессенджер. Тогда мы использовали вертикальную воронку продаж, но обратили внимание на конкурентов, у которых воронка горизонтальная.
Чтобы решить, какой вариант лучше, я сделал грубые версии нескольких интерфейсов и опросил пользователей в чате. Большинство проголосовало за горизонтальную воронку.
Также с помощью отзывов мы поняли, что наши основные пользователи — это стартапы. У нас не было продукта, который мы можем предложить крупным компаниям, поэтому работали только с целевой аудиторией.
Для этого я применял одну уловку. Мы предоставляли сервис за деньги. Если клиент говорил, что продукт его не устраивает, то возвращали деньги, позволяя пользоваться бесплатно. Так как обратная связь была важнее прибыли.
Разговор с клиентами не всегда может помочь решить проблему, но порой от людей вы получите больше информации, чем от графиков и схем. Записывайте отзывы пользователей и анализируйте их.
Одна из самых больших ошибок, связанных с аналитикой, это всё усложнять. Например, ввести сложную систему аналитики с 30 показателями. У меня тоже был такой опыт, и это не сработало, в итоге ты просто не понимаешь, за чем следить. Такой подход только запутывает.
Метрика «полярной звезды», которую я выбрал в этом случае, — это сосредоточиться на одном показателе, который компания хочет достичь. Если этот показатель уходит южнее — компании грозит провал. Если показатель идёт вверх, вы сделаете огромную вмятину во вселенной.
Я не говорю, что вы должны придерживаться ей всегда, но попробуйте работать так полгода. Вы можете узнать, что на самом деле эта метрика вам не подходит, попробуете другую.
Распечатайте результаты и повесьте в офисе, пусть все смотрят и думают: «Показатель упал. Что нам с этим делать?». Понять это — самое сложное. Здесь вы начнёте измерять воронку и анализировать, что удерживает, привлекает пользователей. Но не пытайтесь объять необъятное.
Общественная онлайн-школа стартапов Russol открыла приём заявок стартапов на осенний поток акселерации и запись на публичные лекции. На лекциях узнаете, как и с чего стартовали ИТ-компании вроде YouDo, Kabanchik, «Флакон», Cinemood. Поймёте, где вы сами допускаете ошибку и какой опыт можно перенять, создавая и масштабируя бизнес, в том числе в другие страны. Подав заявку на экспертную прокачку, узнаете, что о вашей идее и стартапе думают эксперты, повысите шансы: получить инвестиции, стать зрелыми для фондов вроде Y Combinator, получить дополнительный PR, познакомиться с коллегами, найти ментора.
Читайте также: