Создание Web приложений с HTML 5

Создай сегодня веб-приложения завтрашнего дня.

Это перевод статьи выложенной на сайте 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

Источники

Обучение

Получение продуктов и технологий

Обсуждение

Заведите developerWorks блог и вступайте в developerWorks сообщество.

Оцените статью
( Пока оценок нет )
Блог админа