Я использую jQuery Mobile, и у меня возникают проблемы с пониманием различий между классическим готовым документом и событиями страницы jQuery Mobile.
В чем реальная разница?
Почему следует
<!-- language: lang-js --> $(document).ready() { });
быть лучше чем
$(document).on('pageinit') { });
Каков порядок событий страницы при переходе с одной страницы на другую?
Как я могу отправить данные с одной страницы на другую и можно ли получить доступ к данным с предыдущей страницы?
javascript
jquery
html
jquery-mobile
cordova
user2001897
источник
источник
Ответы:
Обновление jQuery Mobile 1.4:
Моя оригинальная статья была предназначена для старого способа обработки страниц, в основном все, что было до jQuery Mobile 1.4. Старый способ обработки теперь устарел и будет оставаться активным до (включая) jQuery Mobile 1.5, поэтому вы все еще можете использовать все, что упомянуто ниже, по крайней мере, до следующего года и jQuery Mobile 1.6.
Старые события, включая pageinit, больше не существуют, они заменены виджетом pagecontainer . Pageinit полностью удален, и вместо этого вы можете использовать pagecreate, чтобы это событие не изменилось и не будет изменено.
Если вы заинтересованы в новом способе обработки событий страницы, взгляните сюда , в любом другом случае не стесняйтесь продолжать эту статью. Вы должны прочитать этот ответ, даже если вы используете jQuery Mobile 1.4 +, он выходит за рамки событий страницы, поэтому вы, вероятно, найдете много полезной информации.
Старый контент:
Эту статью также можно найти как часть моего блога ЗДЕСЬ .
$(document).on('pageinit')
против$(document).ready()
Первое, чему вы научитесь в jQuery, это вызвать код внутри
$(document).ready()
функции, чтобы все выполнялось, как только DOM загружен. Однако в jQuery Mobile Ajax используется для загрузки содержимого каждой страницы в DOM во время навигации. Из-за этого$(document).ready()
сработает перед загрузкой вашей первой страницы, и каждый код, предназначенный для манипулирования страницей, будет выполнен после обновления страницы. Это может быть очень тонкая ошибка. В некоторых системах может показаться, что он работает нормально, но в других это может привести к ошибкам, которые трудно повторить.Классический синтаксис jQuery:
Чтобы решить эту проблему (и поверьте мне, это проблема), разработчики jQuery Mobile создали страницы событий. В двух словах, события страницы - это события, запускаемые в определенной точке выполнения страницы. Одним из таких событий страницы является событие pageinit, и мы можем использовать его следующим образом:
Мы можем пойти еще дальше и использовать идентификатор страницы вместо селектора документов. Допустим, у нас есть страница jQuery Mobile с индексом id :
Чтобы выполнить код, который будет доступен только для индексной страницы, мы можем использовать этот синтаксис:
Событие Pageinit будет выполняться каждый раз, когда страница будет загружена и показана в первый раз. Он не сработает снова, если страница не обновлена вручную или загрузка страницы Ajax не отключена. Если вы хотите, чтобы код выполнялся при каждом посещении страницы, лучше использовать событие pagebeforeshow .
Вот рабочий пример: http://jsfiddle.net/Gajotres/Q3Usv/, чтобы продемонстрировать эту проблему.
Еще несколько заметок по этому вопросу. Независимо от того, используете ли вы 1 html несколько страниц или несколько парадигм HTML-файлов, рекомендуется разделить всю вашу пользовательскую обработку страниц JavaScript в один отдельный файл JavaScript. Это поможет улучшить ваш код, но у вас будет намного лучший обзор кода, особенно при создании мобильного приложения jQuery .
Есть еще одно специальное мероприятие jQuery Mobile, которое называется mobileinit . Когда запускается jQuery Mobile , он вызывает событие mobileinit для объекта документа. Чтобы переопределить настройки по умолчанию, свяжите их с mobileinit . Одним из хороших примеров использования mobileinit является отключение загрузки страниц Ajax или изменение поведения загрузчика Ajax по умолчанию.
Порядок перехода событий страницы
Сначала обо всех событиях можно узнать здесь: http://api.jquerymobile.com/category/events/
Допустим, у нас есть страница A и страница B, это порядок выгрузки / загрузки:
страница B - страница события перед созданием
страница B - событие pagecreate
страница B - событие страницы
страница A - страница события перед
страница А - событие удаление страницы
страница A - событие pagehide
страница B - страница события перед выставкой
страница B - событие страницы
Для лучшего понимания событий страницы прочитайте это:
pagebeforeload
,pageload
Иpageloadfailed
обжигают при подключении внешнего загрузки страницыpagebeforechange
,pagechange
Иpagechangefailed
события , изменения страниц. Эти события запускаются, когда пользователь перемещается между страницами в приложениях.pagebeforeshow
,pagebeforehide
,pageshow
Иpagehide
события , переходные страницы. Эти события запускаются до, во время и после перехода и имеют имена.pagebeforecreate
,pagecreate
Иpageinit
предназначены для инициализации страницы.pageremove
может быть запущен, а затем обработан, когда страница удалена из DOMПример загрузки страницы jsFiddle: http://jsfiddle.net/Gajotres/QGnft/
Запретить переход страницы
Если по какой-то причине переход страницы должен быть запрещен при некоторых условиях, это можно сделать с помощью этого кода:
Этот пример будет работать в любом случае, потому что он будет инициировать начало каждого перехода страницы, и, что наиболее важно, он предотвратит изменение страницы до того, как может произойти переход страницы.
Вот рабочий пример:
Предотвратить связывание / запуск нескольких событий
jQuery Mobile
работает не так, как классические веб-приложения. В зависимости от того, как вам удавалось связывать свои события каждый раз, когда вы посещаете какую-либо страницу, она будет связывать события снова и снова. Это не ошибка, это просто то, какjQuery Mobile
обрабатываются его страницы. Например, взгляните на этот фрагмент кода:Рабочий пример jsFiddle: http://jsfiddle.net/Gajotres/CCfL4/
Каждый раз, когда вы посещаете страницу #index, событие клика будет привязано к кнопке # test-button . Проверьте это, переходя от страницы 1 к странице 2 и обратно несколько раз. Есть несколько способов предотвратить эту проблему:
Решение 1
Лучшее решение будет использовать
pageinit
для привязки событий. Если вы посмотрите на официальную документацию, вы обнаружите, что онаpageinit
сработает ТОЛЬКО один раз, точно так же, как документ готов, так что события никак не будут связаны снова. Это лучшее решение, потому что у вас нет затрат на обработку, как при удалении событий методом off.Рабочий пример jsFiddle: http://jsfiddle.net/Gajotres/AAFH8/
Это рабочее решение сделано на основе предыдущего проблемного примера.
Решение 2
Удалить событие, прежде чем связать его:
Рабочий пример jsFiddle: http://jsfiddle.net/Gajotres/K8YmG/
Решение 3
Используйте селектор jQuery Filter, например:
Поскольку фильтр событий не является частью официальной среды jQuery, его можно найти здесь: http://www.codenothing.com/archives/2009/event-filter/
Короче говоря, если скорость - ваша главная задача, то Решение 2 намного лучше, чем Решение 1.
Решение 4
Новый, наверное, самый простой из всех.
Рабочий пример jsFiddle: http://jsfiddle.net/Gajotres/Yerv9/
Tnx к sholsinger для этого решения: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/
Причуды события pageChange - срабатывание дважды
Иногда событие pagechange может инициироваться дважды, и оно не имеет ничего общего с упомянутой ранее проблемой.
Причина, по которой событие pagebeforechange происходит дважды, связана с рекурсивным вызовом в changePage, когда toPage не является расширенным объектом DOM jQuery. Эта рекурсия опасна, так как разработчику разрешено изменять toPage внутри события. Если разработчик последовательно устанавливает toPage в строку, в обработчике события pagebeforechange, независимо от того, был ли это объект, будет бесконечный рекурсивный цикл. Событие pageload передает новую страницу как свойство страницы объекта данных (это следует добавить в документацию, в данный момент она не указана). Следовательно, событие загрузки страницы может использоваться для доступа к загруженной странице.
В двух словах это происходит потому, что вы отправляете дополнительные параметры через pageChange.
Пример:
Чтобы устранить эту проблему, используйте любое событие страницы, перечисленное в порядке перехода событий страницы .
Время смены страницы
Как уже упоминалось, при переходе с одной страницы jQuery Mobile на другую, обычно либо путем нажатия на ссылку на другую страницу jQuery Mobile, которая уже существует в DOM, либо путем ручного вызова $ .mobile.changePage, происходит несколько событий и последующих действий. На высоком уровне происходят следующие действия:
Это средний тест перехода страницы:
Загрузка и обработка страницы: 3 мс
Улучшение страницы: 45 мс
Переход: 604 мс
Общее время: 670 мс
* Эти значения указаны в миллисекундах.
Итак, как вы можете видеть, событие перехода потребляет почти 90% времени выполнения.
Управление данными / параметрами между переходами страниц
Можно передавать параметр / ы с одной страницы на другую во время перехода страницы. Это можно сделать несколькими способами.
Ссылка: https://stackoverflow.com/a/13932240/1848600
Решение 1:
Вы можете передавать значения с помощью changePage:
И читать их так:
Пример :
index.html
second.html
Решение 2:
Или вы можете создать постоянный объект JavaScript для хранения. Пока Ajax используется для загрузки страницы (и страница не перезагружается каким-либо образом), этот объект будет оставаться активным.
Пример: http://jsfiddle.net/Gajotres/9KKbx/
Решение 3:
Вы также можете получить доступ к данным с предыдущей страницы, например:
Объект prevPage содержит полную предыдущую страницу.
Решение 4:
В качестве последнего решения у нас есть отличная HTML-реализация localStorage. Он работает только с браузерами HTML5 (включая браузеры Android и iOS), но все сохраненные данные сохраняются при обновлении страницы.
Пример: http://jsfiddle.net/Gajotres/J9NTr/
Вероятно, лучшее решение, но оно выйдет из строя в некоторых версиях iOS 5.X. Это хорошо известная ошибка.
Не используйте
.live()
/.bind()
/.delegate()
Я забыл упомянуть (и tnx andleer для напоминания), использование on / off для привязки / отмены привязки событий, live / die и bind / unbind не рекомендуется.
Метод .live () jQuery был замечен как находка, когда он был представлен API в версии 1.3. В типичном приложении jQuery может быть много манипуляций с DOM, и это может быть очень утомительно, когда элементы приходят и уходят.
.live()
Метод позволил подключить событие для жизни приложения на основе его выбора. Отлично верно? Неправильно,.live()
метод очень медленный..live()
Метод фактически перехватывает свои события на объект документа, который означает , что необходимо событие пузыриться от элемента , который сгенерировал событие , пока он не достигнет документа. Это может быть удивительно много времени.Сейчас не рекомендуется. Люди из команды jQuery больше не рекомендуют его использовать, как и я. Даже если зацеплять и отсоединять события может быть утомительно, ваш код будет намного быстрее без
.live()
метода, чем с ним.Вместо
.live()
вас следует использовать.on()
..on()
примерно в 2-3 раза быстрее, чем .live () . Взгляните на этот тест привязки событий: http://jsperf.com/jquery-live-vs-delegate-vs-on/34 , оттуда все будет ясно.Бенчмаркинг:
Для тестирования событий на странице jQuery Mobile создан отличный скрипт . Его можно найти здесь: https://github.com/jquery/jquery-mobile/blob/master/tools/page-change-time.js . Но прежде чем что-то делать с этим, я советую вам удалить его
alert
систему уведомлений (каждая «страница изменений» будет показывать вам эти данные, останавливая приложение) и изменить ее наconsole.log
функционирование.По сути, этот скрипт будет регистрировать все события вашей страницы, и если вы внимательно прочитаете эту статью (описания событий страницы), вы узнаете, сколько времени jQm потратил на улучшения страницы, переходы страниц ....
Финальные заметки
Всегда, и я имею в виду всегда читать официальную документацию jQuery Mobile . Обычно он предоставляет вам необходимую информацию, и, в отличие от некоторой другой документации, этот документ достаточно хорош, с достаточным количеством пояснений и примеров кода.
Изменения:
источник
$().live()
было исключено в jQuery 1.7 и удалено в 1.9, поэтому оно действительно должно быть частью любого решения jQuery Mobile. Текущая минимальная версия ядра для jQM 1.7.pagecreate
событие запускается только один раз, когда страница впервые создается. поэтому, если мы свяжем события щелчка внутри,pagecreate
он не будет срабатывать несколько раз. Что-то, что я понял при разработке приложения. Но мы не всегда можемpagecreate
связывать события, поэтому предлагаемое вами решение является лучшим. +1 даноНекоторые из вас могут найти это полезным. Просто скопируйте и вставьте его на свою страницу, и вы получите последовательность событий в консоли Chrome ( Ctrl+ Shift+ I).
Вы не увидите выгрузку в консоли, так как она запускается, когда страница выгружается (когда вы уходите со страницы). Используйте это так:
И вы поймете, что я имею в виду.
источник
Это правильный путь:
Чтобы выполнить код, который будет доступен только для страницы индекса, мы могли бы использовать этот синтаксис:
источник
Простая разница между готовым документом и событием страницы в jQuery-mobile заключается в том, что:
Событие готовности документа используется для всей HTML-страницы,
Когда есть событие страницы, используйте для обработки определенного события страницы:
Вы также можете использовать документ для обработки события pageinit:
источник
Хотя вы используете .on (), это в основном живой запрос, который вы используете.
С другой стороны, .ready (как и в вашем случае) - это статический запрос. При его использовании вы можете динамически обновлять данные и не нужно ждать загрузки страницы. Вы можете просто передать значения в свою базу данных (если требуется), когда будет введено определенное значение.
Использование живых запросов распространено в формах, где мы вводим данные (учетную запись или сообщения или даже комментарии).
источник