Это перевод статьи выложенной на сайте IBM. Автор — Michael Galpin, Software architect, eBay
Обобщение
Несколько лет веб-разработчики ожидали возможности, которые обещали появится в следующем поколении браузеров ориентированных на поддержку спецификации HTML 5. Вы можете быть удивлены, тем, сколько из них уже есть в браузерах. В этой статье вы узнаете, как определить, какие возможности предоставляются и как их можно применить к вашему приложению. Исследуем возможности HTML 5 такие как многопоточность,геолокация , встроенные базы данных, встроенное видео.
Введение
Многие возможности и стандарты стали частью HTML 5. После того как вы определите какие функции доступны в сегодняшних браузерах,вы можете использовать эти возможности в вашем приложении. В этой статье вы узнаете как определить эти возможности и использовать современные Веб-технологии путем разработки приложения на примере. Большинство кода в этой статье только HTML, JavaScript, и CSS— это ядро технологии любого Веб-разработчика.
Начало
Для того чтобы следовать примерам самое важное что от вас потребуется — наличие нескольких браузеров для проверки. последнии версии Mozilla Firefox, Apple Safari, и Google Chrome настоятельно рекомендуются. При написании статьи использовались Mozilla Firefox 3.6, Apple Safari 4.04, и Google Chrome 5.0.322. Вы можете так же попробовать протестировать мобильные браузеры. Например, последние Android и iPhone SDKs исопльзовались для тестирования браузеров в их эмуляторах.
Вы можете скачать исходный код используемый в этой статье.
Примеры включают подключение очень маленького back-end компонента написаного на Java™. JDK 1.6.0_17 и использующего Apache Tomcat 6.0.14. Смотрите ссылки в конце статьи для того чтобы скачать эти приложения.
Определение возможностей
Есть старая шутка о том, что веб-разработчики уделяют 20% времени написанию кода и оставшиеся 80% тратят на то чтобы он работал на всех браузерах. Говорить что веб-разработчики привыкли к отличиям браузеров — несколько неверно. С новой волной инноваций в браузерах эта грустаня действительность опять имеет место быть. Возможности поддерживаемые последними и лучшими из браузеров — постоянно меняются.
Однако позитивным моментом является то, что несколько возможностей превратились в Веб-стандарты, что дает нам шанс использовать эти возможности уже сейчас. Вы можете: расширять возможности при испольщовании старых технологий, предоставлять базовые возможности,проверить на поддержка продвинутых технологий , и затем уже расширить приложение используя расширенные возможности которые оно сможет использовать. Рассмотрим наконец, как можно определить эти возможности. Листинг 1 показывает простой скрипт определения возможностей браузера:
Листинг 1. Скрипт определения
function detectBrowserCapabilities(){ $("userAgent").innerHTML = navigator.userAgent; var hasWebWorkers = !!window.Worker; $("workersFlag").innerHTML = "" + hasWebWorkers; var hasGeolocation = !!navigator.geolocation; $("geoFlag").innerHTML = "" + hasGeolocation; if (hasGeolocation){ document.styleSheets[0].cssRules[1].style.display = "block"; navigator.geolocation.getCurrentPosition(function(location) { $("geoLat").innerHTML = location.coords.latitude; $("geoLong").innerHTML = location.coords.longitude; }); } var hasDb = !!window.openDatabase; $("dbFlag").innerHTML = "" + hasDb; var videoElement = document.createElement("video"); var hasVideo = !!videoElement["canPlayType"]; var ogg = false; var h264 = false; if (hasVideo) { ogg = videoElement.canPlayType('video/ogg; codecs="theora, vorbis"') || "no"; h264 = videoElement.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"') || "no"; } $("videoFlag").innerHTML = "" + hasVideo; if (hasVideo){ var vStyle = document.styleSheets[0].cssRules[0].style; vStyle.display = "block"; } $("h264Flag").innerHTML = "" + h264; $("oggFlag").innerHTML = "" + ogg; } |
Огромное число возможностей и стандартов слилось в стандарте HTML 5. Эта статья фокусируется только на некоторых из них. Скрипт в Листинге 1 определяет четыре возможности:
- Вебворкеры (многопоточность)
- Геолокация
- Хранилище базы данных
- Нативное воспроизведение видео
Скрипт начинается с отображения user agent пользовательского браузера. Это (обычно) строка уникального для каждого из браузеров, хотя она может легко быть изменена. Просто повторю, что определение юзерагента будет хорошо для вашего приложения. Следующий шаг — начало определения возможностей. Сначало, проверяем Web workers через поиск функции Worker
в глобальной области видимости (окно|window). Для этого используем одну идиому из JavaScript: double negation (двойное отрицание). Если функция Worker
не существует, то window.Worker
будет неопределенной, что будет значением «ложь» в JavaScript. Ввод одинарного отрицания перед ним превратит его в true, в вдойное отрицание превратит в false. После тестирования этого значения скрипт преобразует значение DOM структуры показанной в Листинге 2 для отображения результата теста.
Листинг 2. Определение DOM
<input type="button" value="Begin detection" onclick="detectBrowserCapabilities()"/> <div>Your browser's user-agent: <span id="userAgent"> </span></div> <div>Web Workers? <span id="workersFlag"></span></div> <div>Database? <span id="dbFlag"></span></div> <div>Video? <span id="videoFlag"></span></div> <div>Can play H.264? <span id="h264Flag"> </span></div> <div>Can play OGG? <span id="oggFlag"> </span></div> <div>Geolocation? <span id="geoFlag"></span></div> <div> <div>Latitude: <span id="geoLat"></span></div> <div>Longitude: <span id="geoLong"></span></div> </div> |
Листинг 2 это простая HTML структура испорльзуемая для отображения диагностической информации полученной после детектирования возможностей скриптом. Глядя на Листинг 1, мы видим, что следующая вещь определяемася скриптом — геолокация (geolocation). Техника двойного отрицания снова в ходу, но в этот раз проверяется выоз объекта (object) geolocation
который должен быть свойством объекта navigator
. Если это так, то используем его для получения объектов geolocation
через функцию getCurrentPosition
. Получение местоположения может замедлить процесс, так как обычно включает сканирование Wi-Fi сетей. На мобильных устройствах так же возможно будет включено сканирование сотовых сетей и подключение к GPS спутникам. Поскольку это может занять долгое время, то функция getCurrentPosition
является асинхронной и принимает функцию обратного вызова (callback
function) в качестве параметра. В этом случае используйте закрытие callback
для простого отображения метоположения (через череключение CSS) и записывание широты и долготы в документ через DOM.
Следующий шаг — проверка хранилища базы данных. Проверим на наличие глобальной функции openDatabase
, котрая используется для создания и доступа к клиентской части базы данных.
Наконец, проверим встроенное проигрывание видео. Используя DOM API создадим видео элемент. Сегодня, каждый браузер позволяет это сделать. В старых браузерах этот элемент будет верным DOM элементом, но не будет иметь никакого специального значения. Это было бы похоже на создание элемента зовущегося foo
(в данном контексте это можно перевести как — создания любого элемента с произвольным названием). В современных же браузерах это специализированный элемент, похожий при создании к примеру на элемент div
или table
. Этим будет заниматься функция canPlayType
,Так что просто проверим её наличие.
Даже если браузер имеет возможность воспроизведения встроенного видео, типы видео, кодеки для воспроизведения не стандартизированны. Возможно вы захотите проверить какие кодеки поддерживаются браузером. Нет стандартного списка кодеков, но етсь два самых весомых — это H.264 и Ogg Vorbis. Чтобы проверить поддержку конкретного кодека вы можете передать идентификационную строку функции canPlayType
. Если браузер поддерживает кодек, то функция вернет probably/возможно
(серьезно, это не шутка). Если нет, то вернется null. В коде детектирования просто определяется это и выводится в DOM. После тестирования кода в популярных браузерах мы получили Листинг 3 отображающий собранные результаты.
Листинг 3. Возможности различных браузеров
#Firefox 3.6 Your browser's user-agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 Web Workers? true Database? false Video? true Can play H.264? no Can play OGG? probably Geolocation? true Latitude: 37.2502812 Longitude: -121.9059866 #Safari 4.0.4 Your browser's user-agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10 Web Workers? true Database? true Video? true Can play H.264? probably Can play OGG? no Geolocation? false #Chrome 5.0.322 Your browser's user-agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.322.2 Safari/533.1 Web Workers? true Database? true Video? true Can play H.264? no Can play OGG? no Geolocation? false |
Все популярные браузеры для настольных компьютеров поддерживают возможности в большей или меньшей степени:
- Firefox поддерживает всё исключая базы данных. Для видео поддерживается только Ogg.
- Safari поддерживает все кроме geolocation.
- Chrome поддерживает все кроме geolocation, так же непонятно какой кодек он поддерживает H.264 илиOgg. Возможно это ошибка которая наблюдается только в этой сборке Chrome или его работе с кодом. Chrome как известно поддерживает H.264.
Geolocation не поддерживает широко браузерами используемыми на настольных компьютерах, однако хорошо поддерживается в мобильных браузерах. Листинг 4 показывает список собранных данных для мобильных браузеров.
Листинг 4. Мобильные браузеры
#iPhone 3.1.3 Simulator Your browser's user-agent: Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 3.1.3 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7E18 Safari/528.16 Web Workers? false Database? true Video? true Can play H.264? maybe Can play OGG? no Geolocation? true Latitude: 37.331689 Longitude: -122.030731 #Android 1.6 Emulator Your browser's user-agent: Mozilla/5.0 (Linux; Android 1.6; en-us; sdk Build/Donut) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1 Web Workers? false Database? false Video? false Geolocation? false #Android 2.1 Emulator Your browser's user-agent: Mozilla/5.0 (Linux; U; Android 2.1; en-us; sdk Build/ERD79) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 Web Workers? true Database? true Video? true Can play H.264? no Can play OGG? no Geolocation? true Latitude: Longitude: |
Выше показаны данные для одного из последних симуляторов iPhone и двух вариантов для Android. Android 1.6 не поддерживает ничего из того что мы тестировали. По факту все это имеет место быть в нем, кроме воспроизведения видео, так как он использует Google Gears. Они эквивалентны API (через функцию), но не соблюдают Веб-стандарты которые мы используем для получения результата в Листинге 4. Сравните с Android 2.1, в нем все поддерживается правильно.
Обратите внимание, что iPhone поддерживает все кроме Web workers. Листинг 3 показывает, что настольная версия Safari поддерживает Web workers, так что есть резон не исключать вероятность появления в скором будущем такой возможности и на iPhone.
Теперь вы научились определять возможности пользовательского браузера, давайте изучим простое приложение которое использует несколько этих возможностей в комбинации—в зависимости от того что может пользовательский браузер. Вы создадите приложение используя Foursquare API для поиска нескольких популярных мест местоположения пользователя.
Создай приложение сегодня
В примере мы фокусируемся на использовании geolocation, но так же имейте в виду что Firefox 3.5+ так же поддерживает geolocation. Приложение начинает поиск звонков Foursquare вблизи текущего местоположения пользователя. Местоположение может быть любым, но обычно это рестораны, бары, магазины или что-то подобное. Будучи веб-приложением наш пример ограничен той же политикой ограничения свойственной всем браузерам. Оно не может вызывать Foursquare’s API напрямую. Вы будете использовать Java servlet как прокси для этих вызовов. В сервлете нет ничего специфичного для Java; вы можете легко переписать этот прокси на PHP, Python, Ruby, и даже на forth. Листинг 5 показывает прокси сервлет.
Листинг 5. Прокси сервлет для Foursquare
public class FutureWebServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation"); if (operation != null && operation.equalsIgnoreCase("getDetails")){ getDetails(request,response); } String geoLat = request.getParameter("geoLat"); String geoLong = request.getParameter("geoLong"); String baseUrl = "http://api.foursquare.com/v1/venues.json?"; String urlStr = baseUrl + "geolat=" + geoLat + "&geolong=" + geoLong; PrintWriter out = response.getWriter(); proxyRequest(urlStr, out); } private void proxyRequest(String urlStr, PrintWriter out) throws IOException{ try { URL url = new URL(urlStr); InputStream stream = url.openStream(); BufferedReader reader = new BufferedReader( new InputStreamReader(stream)); String line = ""; while (line != null){ line = reader.readLine(); if (line != null){ out.append(line); } } out.flush(); stream.close(); } catch (MalformedURLException e) { e.printStackTrace(); } } private void getDetails(HttpServletRequest request, HttpServletResponse response) throws IOException{ String venueId = request.getParameter("venueId"); String urlStr = "http://api.foursquare.com/v1/venue.json?vid="+venueId; proxyRequest(urlStr, response.getWriter()); } } |
Важно отметить, что у вас проксифицирутеся два Foursquare API. Один для поиска, другой для получения детальной информации о месте нахождения. Чтобы их различать в API добавлен оперативный параметр. Вы так же можете указать JSON в качестве возвращаемого типа, для того чтобы позже легко разобрать данные используя JavaScript. Теперь, когда вы знаете какие вызовы совершает приложение и как оно получает данные, давайте посмотрим как оно будет их использовать для получения данных из Foursquare.
Использование geolocation
Это первый вызов в поиске. Листинг 5 показывает что вам требуется два параметра: geoLat
и geoLong
для широты и долготы. Листинг 6 ниже показывает как получить эти данные и совершить вызов сервлета.
Листинг 6. Вызов поиска с местоположением
if (!!navigator.geolocation){ navigator.geolocation.getCurrentPosition(function(location) { venueSearch(location.coords.latitude, location.coords.longitude); }); } var allVenues = []; function venueSearch(geoLat, geoLong){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if (this.readyState == 4 && this.status == 200){ var responseObj = eval('(' + this.responseText + ')'); var venues = responseObj.groups[0].venues; allVenues = venues; buildVenuesTable(venues); } } xhr.open("GET", "api?geoLat=" + geoLat + "&geoLong="+geoLong); xhr.send(null); } |
Код выше проверяет совместимость браузера с возможностями геолокации. Если он совместим, то приложение получает данные о местонахождении и вызывает функцию venueSearch
с широтой и долготой . Эта функция использует Ajax (это объект XMLHttpRequest
вызывающий сервлет в Листинге 5). Так же используется закрытие callback
функции, парсинг JSON данных из Foursquare, и передача массива торговых центров в функцию buildVenuesTable
, которая представлена ниже.
Листинг 7. Создание интерфейса из объектов торговых центров
function buildVenuesTable(venues){ var rows = venues.map(function (venue) { var row = document.createElement("tr"); var nameTd = document.createElement("td"); nameTd.appendChild(document.createTextNode(venue.name)); row.appendChild(nameTd); var addrTd = document.createElement("td"); var addrStr = venue.address + " " + venue.city + "," + venue.state; addrTd.appendChild(document.createTextNode(addrStr)); row.appendChild(addrTd); var distTd = document.createElement("td"); distTd.appendChild(document.createTextNode("" + venue.distance)); row.appendChild(distTd); return row; }); var vTable = document.createElement("table"); vTable.border = 1; var header = document.createElement("thead"); var nameLabel = document.createElement("td"); nameLabel.appendChild(document.createTextNode("Venue Name")); header.appendChild(nameLabel); var addrLabel = document.createElement("td"); addrLabel.appendChild(document.createTextNode("Address")); header.appendChild(addrLabel); var distLabel = document.createElement("td"); distLabel.appendChild(document.createTextNode("Distance (m)")); header.appendChild(distLabel); vTable.appendChild(header); var body = document.createElement("tbody"); rows.forEach(function(row) { body.appendChild(row); }); vTable.appendChild(body); $("searchResults").appendChild(vTable); if (!!window.openDatabase){ $("saveBtn").style.display = "block"; } } |
Код в Листинге 7 в первую очередь DOM код для создания таблицы данных об объектов торговых центров в ней. Однако, есть некотрые интересные моменты. Обратите внимание на использование передовых функций JavaScriptтаких как функция карты массива объектов (array object’s map) и функция forEach
. Эти возможности доступны во всех браузерах которые поддерживают geolocation. так же интересны последние две строки. Проверка поддержки базы данных не выполняется. Если она в начличии, то вы включите кнопку сохранения польовательских данных, при клике на которую пользователь сохранит данные поиска торговых центров в локальной базе данных. Следующий шаг нашего занятия — как это сделать.
Структурированное хранилище
Листинг 7 демонстрирует классическоую прогрессивную стратегию расширения.пример — тест поддержки базы данных . Если поддержка найдена, то код добавляет пользовательский элемент интерфейса в приложение, и который позже можно применить для использования этой возможности. В нашем случае это одна кнопка.Нажатие на кнопку вызывает функцию saveAll
, которая показана в Листинге 8.
Listing 8. Сохранение в базу данных
var db = {}; function saveAll(){ db = window.openDatabase("venueDb", "1.0", "Venue Database",1000000); db.transaction(function(txn){ txn.executeSql("CREATE TABLE venue (id INTEGER NOT NULL PRIMARY KEY, "+ "name NVARCHAR(200) NOT NULL, address NVARCHAR(100), cross_street NVARCHAR(100), "+ "city NVARCHAR(100), state NVARCHAR(20), geolat TEXT NOT NULL, "+ "geolong TEXT NOT NULL);"); }); allVenues.forEach(saveVenue); countVenues(); } function saveVenue(venue){ // check if we already have the venue db.transaction(function(txn){ txn.executeSql("SELECT name FROM venue WHERE id = ?", [venue.id], function(t, results){ if (results.rows.length == 1 && results.rows.item(0)['name']){ console.log("Already have venue id=" + venue.id); } else { insertVenue(venue); } }) }); } function insertVenue(venue){ db.transaction(function(txn){ txn.executeSql("INSERT INTO venue (id, name, address, cross_street, "+ "city, state, geolat, geolong) VALUES (?, ?, ?, ?, "+ "?, ?, ?, ?);", [venue.id, venue.name, venue.address, venue.crossstreet, venue.city, venue.state, venue.geolat, venue.geolong], null, errHandler); }); } function countVenues(){ db.transaction(function(txn){ txn.executeSql("SELECT COUNT(*) FROM venue;",[], function(transaction, results){ var numRows = results.rows.length; var row = results.rows.item(0); var cnt = row["COUNT(*)"]; alert(cnt + " venues saved locally"); }, errHandler); }); } |
Для сохранения данных о ТЦ в базу данных сначало созхдадим таблицу, в которой мы хотим сохранить данные. Для этого используется довольно стандартный синтаксис SQL для создания таблицы. (Все браузеры поддерживающие базы данных используют SQLite. Используйте документацию SQLite для изучения поддерживаемых, ограничиваемых и т.п. типах данных.) SQL выполняется асинхронно. Вызывается функция передачи данных и получаем данные. Функция callback
получает переданный объект который мы можем использовать для выполнения SQL. Функция executeSQL
принимает строку SQL, затем опциональные параметры, полюс правильность выполнения или функцию обработки ошибки. Если обработчика ошибок нет, то и ошибок нет. Для create table
это хорошо. При первом запуске сценария таблица будет создана. В последующие запуски скрипт не сможет создать таблицу, так как таблица уже существует— но это правильно. вам это требуется просто для того, чтобы убедится что таблица создана, до того как будете делать вставку данных в нее.
После создания таблицы используем функцию forEach
для вызова функции saveVenue
с возвратом каждого торгового центра из Foursquare. Эта функция сначало делает запрос в БД чтобы убедится что такие данные уже не хранятся локально. Здесь вы видите исполнение обработчика. Результат полученный в запросе передается в обработчик. Если результатов нет, или ТЦ еще не был сохранен локально то вызывается функция insertVenue
котора вставляет данные в БД.
В saveAll
, после завершения всех сохранений/вставок вы можете вызвать countVenues
. Это запрос общего числа строккоторые были вставлены в таблицу ТЦ. Запрос (row["COUNT(*)"]
) вытаскивает нам количество строк в БД .
После того как вы изучили использование БД если она поддерживается — следующий шаг — изучить работу Web worker если они поддерживаются.
Фоновые процессы с использованием Web workers
Вернемся к Листингу 6, и внесем в него изменения. Как показано ниже в Листинге 9, проверим браузер на поддержку Web worker. Если они поддерживаются — получим с их помощью больше информации о ТЦ.
Listing 9. Измененный поиск ТЦ
function venueSearch(geoLat, geoLong){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if (this.readyState == 4 && this.status == 200){ var responseObj = eval('(' + this.responseText + ')'); var venues = responseObj.groups[0].venues; allVenues = venues; buildVenuesTable(venues); if (!!window.Worker){ var worker = new Worker("details.js"); worker.onmessage = function(message){ var tips = message.data; displayTips(tips); }; worker.postMessage(allVenues); } } } xhr.open("GET", "api?geoLat=" + geoLat + "&geoLong="+geoLong); xhr.send(null); } |
Код выше использует тоже определение возможностей что вы видели до этого. Если Web workers поддерживаются, то вы создаете нового worker. Для создания нового worker, вам требуется URL на другой скрипт, который worker будет выполнять, к примеру — details.js. Когда worker завершает работу, отправляет сообшение обратно в основной поток. Обработчик onmessage
получает это сообщение; используйте простое его закрытие. Наконец, чтобы инициировать worker — вызовите postMessage
с передачей некоторых данных для обработки. Вы передадите все данные полученные из Foursquare. Листинг 10 показывает соджержимое details.js, который является скриптом worker’ом.
Listing 10. Worker скрипт — details.js
var tips = []; onmessage = function(message){ var venues = message.data; venues.foreach(function(venue){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if (this.readyState == 4 && this.status == 200){ var venueDetails = eval('(' + this.responseText + ')'); venueDetails.tips.forEach(function(tip){ tip.venueId = venue.id; tips.push(tip); }); } }; xhr.open("GET", "api?operation=getDetails&venueId=" + venueId, true); xhr.send(null); }); postMessage(tips); } |
Скрипт перебирает каждый ТЦ. Для каждого ТЦ скрипт делает вызов в прокси для Foursquare с целью получения детальной информации о каждом ТЦ через XMLHttpRequest
, как обычно. Однако обратите внимание, что при использовании функции open
для открытия соединения, вы передаете третий параметр (true
). Это делает вызов синхронным вместо обычного асинхронного. Это не страшно для worker так как он выполняется не в основном потоке пользовательского приложения и не заставляет его задумываться и замирать ожидая окончания запроса. Делая синхронные запросы вы будете знать, что каждый вызов будет завершен прежде чем начнется новый. Обработчик просто извлекает детали о ТЦ собирает их все вместе и передает обратно — в основной поток пользовательского приложения. Для передачи данных обратно используется вызов функции postMessage
которая будет вызывать callback функцию onmessage
в worker, как это показано на Листинге 9.
По умолчанию поиск торговых центров возвращает 10 ТЦ. Вы можете себе представить сколько вызовов совершается чтобы получить детальные данные о каждом из них? Но Web workers делают задачу легкой и незаметной для пользователя, делая свою работу в фоновом режиме.
Итог
В этой статье освещено несколько новых возможностей HTML 5 поддерживаемых современными браузерами. Вы научились определять какие возможности поддерживаются браузерами и как прогрессивно наращивать мощь своего Веб-приложения, используя эти возможности. Большинство функционала уже широко поддерживается даже на мобильных браузерах. теперь вы можете начать исопльзовать такие в высшей степени примечательные вещи как geolocation и Web workers для создания новых, креативных Веб-приложений!
Исходный код статьи | FutureWeb.zip | 9KB | HTTP |
Источники
Обучение
- «Explore multithreaded programming in XUL» (Michael Galpin, developerWorks, Sep 2009) has more information about using Web workers.
- «New elements in HTML 5» (developerWorks, Aug 2007) explores some of the many UI features in the HTML 5 spec.
- «Android and iPhone browser wars, Part 1: WebKit to the rescue» (developerWorks, Dec 2009) explains how you can leverage the features of mobile browsers.
- W3C HTML 5 Specification — спецификация HTML 5.
- «DOM Storage» (Mozilla Developer Center) обсуждение поддержки HTML 5 localStorage в Firefox.
- Web development zone Специализированные статьи по решению проблем поставленных перед Веб-приложениями.
- My developerWorks: Персональный опыт разработки.
- Чтобы послушать интересные интервью и дискуссии известных разработчиков — присоединйтесь к developerWorks podcasts.
- developerWorks technical events and webcasts: оставайтесь в курсе событий.
Получение продуктов и технологий
- Modernizr project предоставление утилиты для детектирования возможностей HTML5.
- Получить Mozilla Firefox 3.6.
- ПолучитьSafari 4.04.
- ПолучитьGoogle Chrome 5.0.322.
- Скачать Android SDK, доступ к описанию API, и последние новости о Android.
- Получить последний iPhone SDK. В статье использовалась версия 3.1.3.
- Получить исходный код OS Android с сайта Android Open Source Project.
- Получить Java SDK. JDK 1.6.0_17 было использовано в этой статье
Обсуждение
Заведите developerWorks блог и вступайте в developerWorks сообщество.