JavaScript и Web-программирование

advertisement
JavaScript и
Web-программирование
Валеев Т. Ф.
к.ф.-м.н., н.с. ИСИ СО РАН
Материалы курса:
http://nprog.ru/~lan/CourseJS
Введение в CSS
•
•
CSS — каскадные таблицы стилей
На данный момент неплохо поддерживается CSS 3.0 (IE – с 9-й версии)
http://www.w3.org/TR/CSS2/ http://www.w3.org/Style/CSS/specs
http://www.w3.org/TR/css-2010/
Определение стиля:
– Внутри тега: <div style=“color: red;”> (не рекомендуется)
– В заголовке HTML-документа: <style>...</style>
– В отдельном файле стилей .css
<link rel="stylesheet" type="text/css" href="style.css"/>
• Стиль применяется в соответствии с селектором. Вот некоторые
примеры ( => styles.html):
–
–
–
–
–
–
div {color: blue;}
div.alert {color: red;} // <div class=“alert”>!!!</div>
div#msg {color: green;} // <div id=“msg”>Green message</div>
a:hover {text-decoration: underline;}
div.alert span, span.alert {background: yellow;}
input[type=“text”] {background: blue;}
Введение в CSS: некоторые свойства
• Свойства (property) разделяются точкой с запятой
• Свойства задаются в виде «имя: значение»
• Отдельные элементы значения разделяются пробелами или
(редко) запятыми
• Для расстояний всегда надо задавать единицу измерения
• Некоторые свойства используются как сокращения для других
свойств (border; border-top; border-width; border-top-width)
• Оформление текста: color, background, font-family, font-size, textdecoration , text-indent, text-transform, font-weight, white-space
• Box-model: margin, border, padding
• Заполнение: width, height, overflow (hidden/auto/scroll)
• Расположение блоков: display (block/inline/none), float, z-index,
position (relative/absolute/fixed), left, right, top, bottom
CSS: рекомендации
•
•
•
•
•
•
•
•
http://habrahabr.ru/post/160177/ Код CSS «с душком»
http://practicaltypography.com/index.html Butterick’s Practical Typography
Рекомендуется большинство стилей задавать в заголовке или внешнем CSS-файле,
определяя их для классов или для id, отделяя тем самым документ от представления
Не забываем, что в документе не должно быть более одного элемента с заданным id!
Вместо <div style=“border: 1pt solid blue; background: yellow url(‘static/back.png’); color:
blue; text-decoration: underline; font-weight: bold”>
пишем:
<div class=“highlighted”>
// в static/style.css-файле:
div.highlighted {
color: blue; text-decoration: underline; font-weight: bold;
background: yellow url(‘back.png’); // путь относительно .css-файла, а не исходного html!
border: 1pt solid blue;
}
Явно задавать можно стиль display (скрыть/показать элемент), а также стили, значение
которых может меняться непрерывно (а не переключаться между несколькими
состояниями). Пример: ширина полосы прогресс-индикатора width.
Элемент может принадлежать нескольким классам (указывать через пробел).
Пример: => tabs.html
Введение в DOM
• DOM — Document Object Model — кроссплатформенный
программный интерфейс для представления и взаимодействия с
объектами в HTML, XHTML, XML-документах
(http://www.w3.org/DOM/DOMTR );
• Стандарт: DOM3 (2004), черновик: DOM4 (2014)
• Имеются реализации DOM на разных языках, в том числе JavaScript
(но DOM не является неотъемлемой частью JavaScript!)
• Каждый элемент HTML(XML)-документа представляется в виде
объекта определённого класса в иерархии со своим набором
методов, полей и обработчиков событий;
• Большинство полей соответствуют атрибутам соответствующего тега,
что позволяет получать текущее состояние и визуальное
представление элемента или менять его.
• Tutorial: http://www.w3schools.com/dom/default.asp
DOM: поиск нужных элементов
(Vanilla JS!)
• Получение элемента или группы элементов:
–
–
–
–
document.getElementById(“id”)
document.getElementsByName(“name”)
document.getElementsByTagName(“div”)
document.getElementsByClassName(“name”) ( => dynamiclist.html )
• Обход дерева элементов:
–
–
–
–
elem.getElementsByTagName(“*”)
elem.parentNode()
elem.childNodes[i]
elem.firstChild, elem.lastChild, nextSibling, prevSibling
• Осторожно: текстовые элементы! ( =>
domtraversal.html )
DOM: создание элемента
• Создание:
newelem = document.createElement(‘div’);
textnode = document.createTextNode(‘Text’);
clone = elem.cloneNode(true);
• Вставка в документ:
oldelem.appendChild(newelem);
• Удаление:
parent.removeChild(removeelem);
DOM: получение информации об
элементе
• Общее:
– node.nodeType (1 = элемент, 3 = текстовый объект и др.)
• Элементы (теги):
–
–
–
–
elem.id — поле id элемента
elem.tagName — имя тега (DIV, BODY и т. д.)
elem.className — классы стилей
elem.innerHTML — HTML внутри элемента
• Текстовый объект:
– textnode.data — содержимое
– textnode.isElementContentWhitespace — одни пробелы или нет
DOM: управление атрибутами
• Стандартные атрибуты тега обычно доступны как поля
соответствующего элемента ( => attr.html)
• Аттрибуты могут преобразовываться браузером
автоматически (вы необязательно получите точно то, что
установили)
• Стили доступны в объекте style, имена свойств пишутся
слитно (без дефисов), второе и последующие слова с
большой буквы: text-decoration (CSS) => textDecoration
(DOM) (не забывайте единицы измерения!)
• Имена классов доступны в elem.className
• Почти всё доступно для записи
DOM: пользовательские
аттрибуты
• Пользовательские аттрибуты недоступны
как поле класса, но доступны как объект
Attr ( => attr_u.html)
• Можно использовать
getAttribute/setAttribute
• Удалить атрибут: removeAttribute
• HTML-5: data-*
DOM: события (events)
• Элементу можно назначить обработчик события в соответствующем
атрибуте тега:
<div onclick=“handleClick()”>
или в скрипте:
elem.onclick = handleClick; // старый метод
elem.addEventListener(“click”, handleClick); // современный метод
• Виды событий:
– От мыши: click, dblclick, mousemove, mouseover, mouseout, mousedown,
mouseup и т. д. (события от правой кнопки пользователь может
запретить!)
– От клавиатуры: keydown, keyup
– Логические: focus, blur, change
• Обработчику события передаётся параметром объект event,
позволяющий узнать дополнительную информацию о событии
(координаты клика мышки, состояние клавиш shift, ctrl, alt и т. д.)
• Простой пример: => mousemove.html
DOM: назначение события на
клик
• Некоторые используют тег <a>:
<a href=“#” onclick=“handleclick(this)”>
Способ неправильный ( => handleclick.html )
• Следует писать
<span class=“clickable” onclick=“handleclick(this)”>
• Можно даже <span class=“clickable”>
А где-то ниже (+ jQuery)
<script>
$(‘.clickable’).click(handleclick);
</script>
=> clickable.html
DOM: управление элементами
формы
•
•
•
•
Фокус ввода: focus(), blur()
Эмуляция клика: click()
Выделение текста в текстовом поле: select()
Манипуляция списком <select>: add(),
remove()
Координаты объектов
• С координатами много проблем
• Есть координаты в клиентской области, координаты в
буфере прокрутки, координаты относительно родителя,
позиция собственного буфера прокрутки (scrollLeft,
scrollTop)
• У элемента имеется offsetLeft, offsetTop, offsetParent.
• Ширина объектов: clientWidth (ширина содержимого,
видимая на странице), offsetWidth (ширина элемента,
занимаемая на странице), scrollWidth (полная ширина с
учётом буфера прокрутки) ( => width.html)
AJAX
• AJAX = Asynchronous Javascript + XML — технология,
позволяющая клиентскому JS-коду самостоятельно
выполнять HTTP-запросы к серверу
• IFrames: IE 3.0, 1996
• XMLHTTP ActiveX control: IE 5.0, 1999
• Название AJAX — Garret, 2005-й год, тогда же началось
распространение технологии (Gmail, Google Maps)
• Черновик стандарта W3C:
http://www.w3.org/TR/XMLHttpRequest/
AJAX: синтаксис
• Для создания AJAX-запросов в современных браузерах используется
DOM-объект XMLHttpRequest: var req = new XMLHttpRequest()
• В более старых браузерах (IE 5, IE 5.5, IE 6) синтаксис отличался,
поэтому рекомендуется пользоваться библиотеками
prototype.js/jQuery, которые реализуют совместимый с многими
браузерами класс для AJAX-запросов.
• req.open(method, URL, async?[, user, password])
– method = GET/POST/HEAD/etc. (IE кэширует GET-запросы!)
– URL (должен быть на том же сервере и на том же порту, что и исходный
документ!)
– async? = true/false, является ли запрос асинхронным (рекомендуется
всегда ставить true)
– user/password для HTTP-аутентификации, обычно не нужно
AJAX: синтаксис
• req.setRequestHeader(name, value) — добавить полей в
заголовок HTTP-запроса (текущие cookies, httpаутентификация и ряд других полей добавляются
автоматически, часть полей установить нельзя!)
• req.onreadystatechange — обработчик события изменения
состояния запроса
• req.send(content) — отправить запрос. Значение content
обычно null. Асинхронный запрос не блокирует
программу. Когда он будет выполнен, вызовется
обработчик onreadystatechange
• req.abort() — прервать запрос
AJAX: обработчик
onreadystatechange
• Внутри обработчика можно использовать:
– req.readyState — текущий статус
• 0 — uninitialized, 1 — open, 2 — sent, 3 — receiving, 4 — loaded
– req.status — код возврата HTTP-сервера
• 200 = OK, 404 = Not found, 500 = Server error, etc.
– req.getResponseHeader(headerField) — поле HTTPзаголовка ответа (например, “Content-type”)
– req.responseText — документ, возвращённый сервером
( => ajaxbasic.html)
– req.responseXML — DOM-объект возвращённого XMLдокумента (если вернули XML-документ). Для него весь
DOM работает!
AJAX: сценарии использования
•
•
Сохранение состояния на сервере. В запросе передаются параметры пользовательского ввода
(например, форма), факт получения ответа 200 свидетельствует об успешном сохранении на
сервере (responseText не требуется или минимален)
Получение информации с сервера в текстовом виде. Запрашивается некоторое значение (текущая
температура воздуха, количество ответов в теме на форуме, занято ли выбранное пользователем
имя и т. д.), которое затем вписывается в соответствующее поле на странице:
Desired user name: <input onblur=“checkname(this.value)” type=“text”><span id=“check_name”></span>
<script>
function checkname(name) {
var req = new XMLHttpRequest();
req.open(“POST”, “checkname.pl?name=“+name, true);
req.onreadystatechange = function() {
if(req.readyState == 4 && req.status == 200) {
document.getElementById(‘check_name’).innerHTML =
req.responseText == ‘OK’?’Ok’:’Please select another name’;
}
}
req.send();
}
</script>
AJAX: сценарии использования
•
•
•
•
Получение фрагмента HTML-документа и внедрение его в нужное место:
<div id=“info”></div>
…
document.getElementById(“info”).innerHTML = req.responseText;
Так удобно периодически (или по запросу пользователя) обновлять фрагмент страницы,
не трогая страницу целиком (похоже на IFrame)
Если пришедший фрагмент содержит блоки <script>, они не выполнятся автоматически!
(см. prototype.js)
Выполнение пришедшего JS-кода:
eval(req.responseText);
практически универсальная конструкция: пришедший с сервера код может сделать
любое другое действие (встроить фрагмент HTML-кода в нужное место, поменять
значения каких-либо полей и т. д.)
Получение XML с последующей обработкой:
x=req.responseXML.documentElement.getElementsByTagName(“State");
alert(x.length.toString()+” state(s) were loaded”);
Получение информации в произвольно форматированном виде и её разбор (regexp,
string functions, etc.) — обычно некрасиво.
AJAX: обработка ошибок
•
•
•
•
Ошибки, возвращённые HTTP-сервером: проверить req.status
Ошибки при подключении к серверу (DNS lookup failure, connection refused,
etc.): req.status = 0
Тайм-аут подключения к серверу — обработать самим:
var reqtimer = setTimeout(function() {req.abort();alert(‘Timeout in AJAX call’);},
1000);
req.onreadystatechange = function() {
if(req.readyState != 4) return;
clearTimeout(reqtimer);
…
}
Что сказать пользователю?
– Ничего
– Показать предупреждение, попытаться повторить запрос (если был тайм-аут)
– Показать сообщение об ошибке, разрешить пользователю повторить запрос
вручную
Download