PhoneGap — это платформа, которая позволяет разработчикам создавать мобильные приложения с использованием HTML, CSS и JavaScript. С его помощью вы можете создавать приложения для различных мобильных операционных систем, таких как Android, iOS и Windows Mobile. Доступно множество основных плагинов и API-хуков, и существует процветающая экосистема сообщества.
Например, с помощью cordova-plugin-geolocation вы можете получить местоположение пользователя, а с помощью cordova-plugin-vibration вы можете заставить устройство пользователя вибрировать. В этом уроке я собираюсь сосредоточиться на одном конкретном плагине, который не является частью основного пакета, «ThemeableBrowser» . Это форк основного плагина InAppBrowser, который позволяет открывать внешние веб-сайты в приложении, стилизовать браузер и добавлять настраиваемые действия.
К концу этого урока вы создадите простое мобильное приложение, которое отображает веб-сайт SitePoint вместе с некоторыми бонусными функциями.
Обратите внимание на значок гамбургера справа, логотип слева и название текущей веб-страницы в середине.
Вы можете найти код для этого урока на GitHub .
Создание приложения PhoneGap «Hello World»
Вам понадобятся Node и npm. Если вы этого еще не сделали, прочитайте краткий совет SitePoint, чтобы начать работу.
Теперь запустите следующее в своем терминале, чтобы установить PhoneGap:
npm install -g phonegap@latest
Теперь вы можете запустить:
phonegap create project-name
В командной строке создать новый проект и папку с именем проекта . Внутри этой папки находится папка www , содержащая ваше HTML-приложение.
Чтобы протестировать приложение в браузере, выполните:
phonegap serve
Или запустите приложение на эмуляторе (в данном случае iOS) или на устройстве с:
phonegap run ios
Вы можете создать тестовую версию приложения, используя команду phonegap build
. Если вы хотите подготовить версию к выпуску в соответствующем хранилище устройств (в данном случае Android), запустите phonegap build android --release --buildConfig fileWithKeyInformation.json
, передав данные сборки команды (например, хранилище ключей) в JSON файл.
Вам может понадобиться загрузить другие зависимости для создания мобильных приложений для разных устройств. Например, чтобы создать приложение для магазина Google Play, вам потребуется установить Android SDK , среду выполнения Java SE и Java Development Kit .
Установка и управление необходимыми плагинами
Вы можете увидеть, phonegap plugin list
плагины использует приложение, набрав phonegap plugin list
в папке проекта PhoneGap. Вы можете удалить ненужные плагины, используя phonegap plugin remove plugin-name
. Вы можете добавить плагины, используя phonegap plugin add plugin-name
. Хорошей практикой является удаление плагинов, в которых вам не нужно столько разрешений на использование, которые могут быть ненужными, и отпугивают потенциальных пользователей.
Чтобы объявить, что вы хотите использовать плагин ThemeableBrowser, запустите phonegap plugin add cordova-plugin-themeablebrowser
в папку проекта. Затем вы можете вызывать его методы в коде JavaScript, используя cordova.ThemeableBrowser
. Вам также необходимо добавить API преобразования текста в речь (tts) для использования в пользовательском браузере. Для этого запустите phonegap plugin add https://github.com/domaemon/org.apache.cordova.plugin.tts.git
и используйте navigator.tts
в коде JavaScript. Вы можете увидеть все доступные методы tts во включенном файле JavaScript .
Запуск собственного мобильного браузера
Поскольку код приложения содержит только HTML, CSS и JavaScript, вы можете использовать подходящую вам структуру файлов и папок. Приложение PhoneGap «Hello World» поставляется с файлом index.html (вы можете определить файл, из которого ваше приложение запускается в config.xml ), где вы можете добавить свою логику и загрузить другие ресурсы, которые требуются приложению, такие как файлы JavaScript.
Разделы кода используют JQuery, поэтому добавьте это как зависимость к index.html :
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
Откройте www / js / index.js, и вы заметите:
... bindEvents: function() { document.addEventListener('deviceready', this.onDeviceReady, false); }, ...
С PhoneGap лучше всего запускать логику приложения после того, как deviceready
событие deviceready
. Это событие возникает после загрузки всех API PhoneGap и готовности устройства выполнить дополнительный код. Если вы запускаете какой-либо код до его запуска и используете аппаратные API, например, Geolocation, существует вероятность сбоя приложения.
Вызовите метод, который откроет веб-сайт SitePoint с ThemeableBrowser внутри функции receiveEvent после получения уведомления о готовности устройства:
receivedEvent: function(id) { app.openPage("http://sitepoint.com"); ... }
Метод openPage
принимает URI, вызывает cordova.ThemeableBrowser.open
, передает ему URI и объект с параметрами и сохраняет ссылку на открытую веб-страницу в свойстве. Это свойство необходимо, если вы хотите перейти на другую страницу, когда пользователь просматривает эту страницу, или если вы хотите закрыть веб-браузер.
Создайте функцию в www / js / index.js :
... openPage: function(url) { var options = app.getBrowserOptions(); app.properties.ref = cordova.ThemeableBrowser.open(url, '_blank', options); app.addEventListeners(); }, ...
И связанная функция getBrowserOptions
которая передает параметры в функцию:
... getBrowserOptions: function() { var options = { ... } return options; }, ...
В объекте options
добавьте строку состояния и свойство панели инструментов, которое устанавливает высоту панели инструментов в 44 пикселя и добавляет цвет фона белого цвета:
var options = { statusbar: { color: '#ffffffff' }, toolbar: { height: 44, color: '#f0f0f0ff' }, }
Добавьте еще одно свойство, которое указывает, что вы хотите показать заголовок открытой веб-страницы в середине панели инструментов, и присвойте ему определенный цвет:
var options = { toolbar: { height: 44, color: '#f0f0f0ff' }, title: { color: '#003264ff', align: "center", showPageTitle: true } }
Добавьте свойство customButtons
которое содержит массив пользовательских кнопок для добавления в браузер. Чтобы добавить новую кнопку, вы передаете объект с функциями кнопки.
Для этой конкретной кнопки передайте объекту image
или свойство wwwImage
с URL-адресом к изображению кнопки. wwwImage
отличается от свойства image
тем, что путь к изображению при использовании wwwImage
начинается с папки www
тогда как image
ожидает изображения в собственном проекте. Вы можете найти изображения, использованные в примере здесь .
Совместите кнопку с левой стороной панели инструментов и скажите ThemeableBrowser, что вы хотите, чтобы событие с именем SitePointSitePressed
вызывалось при нажатии кнопки. Вы добавите событие позже.
... options.customButtons = [{ wwwImage: 'img/btns/sitepoint-logo.png', wwwImagePressed: 'img/btns/sitepoint-logo.png', wwwImageDensity: 1, align: 'left', event: 'SitePointSitePressed' }] ...
Добавьте меню на панель инструментов, создав свойство menu
, снова передав изображение. Выровняйте его вправо и добавьте свойство items
которое содержит массив различных пунктов меню и событие, которое будет вызываться при выборе.
... options.menu = { wwwImage: 'img/btns/menu.png', imagePressed: 'img/btns/menu-pressed.png', wwwImageDensity: 1, title: 'Effects', cancel: 'Cancel', align: 'right', items: [{ event: 'speakPostPressed', label: "Speak Post" }, { event: 'speakTitlesPressed', label: "Speak Titles" }, { event: 'stopSpeakingPressed', label: "Stop Speaking" }, { event: 'viewCodeBlocks', label: 'Toggle Only Code Blocks' }, { event: 'randomArticlePressed', label: 'Open a Random Article on the Page' } ] } ...
Теперь вам нужно добавить прослушиватели событий и функции. Для этого установите прослушиватели событий на cordova.ThemeableBrowser.open
вас ссылку на результат cordova.ThemeableBrowser.open
, то есть app.properties.ref
установленный ранее.
Эти прослушиватели событий, которые вызывают метод run
объекта, который будет обрабатывать логику приложения, передавая ему различные параметры для каждого события. Метод run
попытается вызвать метод, который вы передадите в качестве параметра.
addEventListeners: function() { app.properties.ref.addEventListener('viewCodeBlocks', function(e) { SitePointPostOptions.run("viewCodeBlocks"); }).addEventListener('speakPostPressed', function(e) { SitePointPostOptions.run("speakPost"); }).addEventListener(cordova.ThemeableBrowser.EVT_ERR, function(e) { console.error(e.message); }).addEventListener(cordova.ThemeableBrowser.EVT_WRN, function(e) { console.log(e.message); }).addEventListener("stopSpeakingPressed", function(e) { SitePointPostOptions.run("stopSpeaking"); }).addEventListener("speakTitlesPressed", function(e) { SitePointPostOptions.run("speakTitles"); }) .addEventListener("SitePointSitePressed", function(e) { SitePointPostOptions.run("logoClick"); }) .addEventListener("randomArticlePressed", function(e) { SitePointPostOptions.run("randomArticle"); }).addEventListener("loadstop", function(evt) { if (SitePointPostOptions.properties && SitePointPostOptions.properties.length) { SitePointPostOptions.properties.areCodeBlocksShown = false; } },
Следующий шаг имеет решающее значение. Добавьте дополнительный прослушиватель событий для события loadstop
свойства, которое содержит ссылку на открытую веб-страницу. Событие loadstop
запускается всякий раз, когда браузер заканчивает загрузку веб-страницы. Это может быть только что открывшаяся веб-страница или любая другая веб-страница, на которую пользователь переходит впоследствии.
В слушателе вернитесь из функции, если пользователь не находится на сайте SitePoint. Если это так, выполните код JavaScript на веб-странице, на которой находится пользователь.
Вызовите document.body.innerHTML
чтобы получить HTML-содержимое веб-страницы и добавить обратный вызов, который сохраняет содержимое в свойстве. Используя это свойство, вы можете просматривать и читать содержимое любой веб-страницы, на которую переходит пользователь.
addEventListeners: function() { app.properties.ref.addEventListener('viewCodeBlocks', function(e) { SitePointPostOptions.run("viewCodeBlocks"); }).addEventListener('speakPostPressed', function(e) { SitePointPostOptions.run("speakPost"); }).addEventListener(cordova.ThemeableBrowser.EVT_ERR, function(e) { console.error(e.message); }).addEventListener(cordova.ThemeableBrowser.EVT_WRN, function(e) { console.log(e.message); }).addEventListener("stopSpeakingPressed", function(e) { SitePointPostOptions.run("stopSpeaking"); }).addEventListener("speakTitlesPressed", function(e) { SitePointPostOptions.run("speakTitles"); }) .addEventListener("SitePointSitePressed", function(e) { SitePointPostOptions.run("logoClick"); }) .addEventListener("randomArticlePressed", function(e) { SitePointPostOptions.run("randomArticle"); }).addEventListener("loadstop", function(evt) { if (SitePointPostOptions.properties && SitePointPostOptions.properties.length) { SitePointPostOptions.properties.areCodeBlocksShown = false; } if (evt.url.indexOf("sitepoint.com") === -1) { return; } app.properties.ref.executeScript({ code: "document.body.innerHTML" }, function(values) { alert("The app's menu is now ready for use."); app.properties.pageContents = values; } ); }) },
Метод, который открывает случайную статью, показывает что-то интересное, как закрыть открытую веб-страницу и открыть новую. Он использует метод close
для свойства с открытой страницей и устанавливает прослушиватель для события выхода браузера. Всякий раз, когда браузер собирается завершить работу, подождите несколько секунд, пока он закроется, и откройте новую страницу, вызвав метод openPage
с новым URI. Новый URI — это случайный атрибут href
якорей всех статей на странице SitePoint, содержащей списки статей. Если на странице нет статей, всплывающее предупреждение.
Добавьте логику браузера в новый файл www / js / menuLogic / logic.js :
SitePointPostOptions = {}; SitePointPostOptions.properties = {}; SitePointPostOptions.properties.areCodeBlocksShown = false; SitePointPostOptions.run = function(type, options) { SitePointPostOptions[type].call(this, options); } SitePointPostOptions.randomArticle = function() { var articles = $(app.properties.pageContents[0]).find(".article .article_title a"); if (!articles.length) { alert("You are probably not on a SitePoint page with a list of articles!"); } var randomIndex = Math.floor(Math.random() * articles.length); var linkToFollow = articles[randomIndex].getAttribute("href"); app.properties.ref.addEventListener("exit", function() { setTimeout(function() { app.properties.ref = null; app.openPage(linkToFollow); }, 2000) }) app.properties.ref.close(); }
Ссылка на этот новый файл в index.html :
<script type='text/javascript' src='js/menuLogic/logic.js'></script>
Когда пользователь щелкает логотип (пользовательская кнопка добавлена слева), откройте веб-сайт SitePoint с помощью системного браузера по умолчанию. Чтобы открыть веб-страницу вне внутреннего браузера, передайте второй параметр методу cordova.ThemeableBrowser.open
со значением _system
.
Еще в www / js / menuLogic / logic.js добавьте:
SitePointPostOptions.logoClick = function() { cordova.ThemeableBrowser.open("http://sitepoint.com", "_system"); }
Следующий метод произносит заголовки веб-страниц, передавая текст всех элементов speakText
помощнику speakText
.
SitePointPostOptions.speakTitles = function() { //TODO: Speak only the tiles of the pages var titlesContents = $(app.properties.pageContents[0]).find("h1,h2,h3,h4,h5,h6"); if (!titlesContents.length) { alert("There is probably no title out there to speak aloud!"); } titlesContents = titlesContents.text(); SitePointPostOptions.speakText(titlesContents); }
Следующий метод говорит содержание сообщений, с сопровождающим методом, который останавливает речь:
SitePointPostOptions.speakPost = function() { //TODO: speak post var postContents = $(app.properties.pageContents[0]).find(".ArticleCopy").find("p,h1,h2,h3,h4,h5,h6"); if (!postContents.length) { alert("There is probably no post open to speak aloud."); } postContents = postContents.text(); SitePointPostOptions.speakText(postContents); } SitePointPostOptions.stopSpeaking = function() { navigator.tts.stop(function() { /*success callback*/ }, function() { /*err callback*/ }); navigator.tts.interrupt("", function() { /*success callback*/ }, function() { /*err callback*/ }); navigator.tts.shutdown(function() { /*successfully shut down tts*/ }, function() { /*err*/ }) }
Следующий метод переключает блоки кода в данной публикации SitePoint, вставляя определенные правила CSS в веб-страницу, которую просматривает пользователь:
SitePointPostOptions.viewCodeBlocks = function() { //TODO: filter only code blocks; if (SitePointPostOptions.properties.areCodeBlocksShown) { app.properties.ref.insertCSS({ code: ".ArticleCopy > *:not(pre) { display:block !important;}" }) SitePointPostOptions.properties.areCodeBlocksShown = false; return; } app.properties.ref.insertCSS({ code: ".ArticleCopy > *:not(pre) { display:none !important;}" }) SitePointPostOptions.properties.areCodeBlocksShown = true; }
Что еще?
Вы создали браузер мобильного приложения, наполненный вкусностями. Вы можете расширить их, чтобы включить пользовательский брендинг и функциональность, подходящую для вашего случая использования приложения.
Вы когда-нибудь реализовывали собственный мобильный браузер или чувствуете, что хотите что-то создать? Что это?