====== Упражнения и задания к урокам ====== [[http://wiki.nsunc.com/_export/html/javascript/ex|удобный для просмотра вид]] ===== Урок 1: введение ===== Язык JavaScript изначально был предназначен для написания простых сценариев, исполняемых в среде www-браузера... На [[http://learn.javascript.ru/hello-world|странице портала javascript.ru]] и в разделе [[http://ru.wikipedia.org/wiki/JavaScript#.D0.92.D1.81.D1.82.D1.80.D0.B0.D0.B8.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_.D0.B2_.D0.B2.D0.B5.D0.B1-.D1.81.D1.82.D1.80.D0.B0.D0.BD.D0.B8.D1.86.D1.8B|Встраивание в веб-страницы]] на wikipedia подробное обсуждается вопрос внедрения скриптов в тело html-страниц с примерами и историей вопроса. Если коротко, то самый компактный и современный (по стандарту html5) вариант выглядит так: более общий и более совместимый со стандартом html4 -- так: ещё более древний, не стандартный, но до сих пор самый ходовой: (возможно их совмещение, указание дополнительных атрибутов, напр., кодировки скрипта -- примеры см. на указанных выше сайтах) Наиболее важным для нас атрибутом является src, который позволяет подгружать внешний отдельный файл со скриптом. ===== Урок 2: ввод-вывод информации из скрипта ===== Простейший вывод из скрипта на JavaScript осуществляется с помощью вызова функции alert("string"). Hello, world!

Click me!

Реализацию можно посмотреть тут: [[http://users.nsunc.com/~vlasov/javascript/hellow.html|Hello, world!]] Простейший ввод можно сделать с помощью функции prompt(). Alert-Prompt

Click me!

Реализацию можно посмотреть тут: [[http://users.nsunc.com/~vlasov/javascript/alertprompt.html|Alert-Prompt]] (в Internet Explorer'е может быть заблокировано окошко ввода, и надо будет дать специальное разрешение на временное исполнение скрипта) **NB!!** Вот здесь надо прочитать [[http://javascript.ru/unsorted/why_href_js_is_bad|Почему - плохо]] Следующее упражнение: вычисление факториала от заданного числа, с возможностью продолжения и прекращения выполнения вычисления. n!-calculating

Расчет факториала

На данной странице предложен пример расчета факториала...
Для завершения работы введите любое ненатуральное число и/или буквы.


Перезапуск

Реализацию можно посмотреть тут: [[http://users.nsunc.com/~vlasov/javascript/factorial.html|факториал]] (в Internet Explorer'е может быть заблокировано окошко ввода, и надо будет дать специальное разрешение на временное исполнение скрипта) Таким образом, в этом уроке, кроме собственно ввода и вывода данных, мы видим активацию функций JavaScript по событиям, задаваемым пользователем, таким как клик мышкой по ссылке, изменение данных в форме ввода и т.п. Связь эта изначально описывалась атрибутами onclick, onchange, onload и другим, добавленными к некоторым тегам в html-3, либо обработчиками в форме по атрибуту action или по псведопротоколу в ссылках (см. выше). В настоящее время, отчетливо сформировалась другая тенденция, так называемый [[http://ru.wikipedia.org/wiki/Ненавязчивый_JavaScript|ненавязчивый JavaScript]], суть которого еще больше разделить контент с размеченным html-текстом и скрипты поддержки на javascript. Но об этом в другой раз. ==== Урок 2.1: ввод-вывод из полей формы ==== На практике функцию prompt() используют чаще всего в целях отладки. Для ввода удобней поля специально предназначенных для этого форм. Рассмотрим пример: working with form

Форма ввода

Обрабатываем форму ввода...

   

Обращение к полям в функции Yeah() происходит как квалифицированной глобальной переменой, точнее, как к свойству объекта, внешнего по отношению к телу функции. Запись document.fm1.tx1.value как раз и показывает пример такого обращения. Здесь document -- это объект самого высокого уровня (выше -- ссылка на окно, по умолчанию -- текущее), fm1 -- имя формы (подчиненного объекта), заданной в атрибуте name формы, tx1 -- имя имя текстового поля ввода (подчиненного к форме), value -- изменяемое свойство объекта document.fm1.tx1. Пример доступен здесь: [[http://users.nsunc.com/~vlasov/javascript/forma.html|Доступ к полям формы через объекты]] Добавим еще код. Теперь обратимся к элементам формы не через глобальный объект, а через передачу ссылки на объект при вызове функции, сократив таким образом количество вводимого текста и сделав функцию вызова более универсальной (единообразно пригодной для обработки других форм на странице).

Определим Ваш любимый цвет:

  В заключение темы стоит отметить, что современным способом вывода отладочной информации является использование ''console'': console.log("var =", myvar); ===== Урок 3: управляющие операторы, создание функций ===== Пока сообщим, что язык Си-подобный, основные управляющие операторы if, for, while и др. наследуются из Си. Особенности опишем позже :) В качестве примера рассмотрим "решатель квадратных уравнений": function roots(a,b,c) { var sd,x1,x2; if (a==0 && b==0) return; if (a==0 && b!=0) { x1=-c/b; return [x1,x1] }; var d = b*b - 4*a*c; if (d>=0) { sd = Math.sqrt(d); x1 = (-b-sd)/(2*a); x2 = (-b+sd)/(2*a); return [x1,x2]; } else return; } запуск будем осуществлять через такую страничку: Решатель квадратных уравнений

Решатель квадратных уравнений

a: b: c:
===== Урок 4: динамическое изменение документов (простой вариант) ===== Сочетание JavaScript и HTML4 дает возможность простого изменения содержимого документов в случае если теги поддерживают изменение атрибутов, либо с помощью функции write мы можем перезаписать содержимое документа. При применении функции write должна происходить дозапись в конец документа, однако может происходить и удаление предыдущего и запись нового документа. В таком случае, лучше не надеясь на сохранение предыдущего документа, осуществлять перезапись во фрейм. Данная последовательность команд всегда делает перезапись: top.doc.document.open(); top.doc.document.write("

Hello!

"); top.doc.document.close();
Здесь top -- ссылка на окно самого верхнего уровня (в нашем случае будем фреймсодержащее окно), top.doc -- ссылка на окно (фрейм), предназначенное для перезаписи. Если речь идет о текущем окне, то пишем document.open() и т.п. Иллюстрация описанных идей: [[http://users.nsunc.com/~vlasov/javascript/doc.html|Пример динамического изменения документа]] ===== Урок 5: динамическое изменение документов (более сложный вариант) ===== Рассмотрим элементы наиболее современной технологии динамического изменения элементов HTML документа: так называемую технологию DOM. Прежде всего мы должны уметь получить ссылку на желаемый html-элемент по его "ID":
...
... var zdes = document.getElementById("label123")
Далее, мы должны сформировать html-контейнер, который будет содержать требуемый html-код, и текст: var node1 = document.createElement('p'); var node2 = document.createTextNode("В лесу родилась елочка"); Теперь, добавим текстовое содержимое (т.е. node2) в заданный контейнер (т.е. node1): node1.appendChild(node2); Затем, мы должны добавить полученный контейнер в дерево документа: zdes.appendChild(node1); Обращаясь каждый раз к данному коду, мы можем добавить ряд подобных записей. Чтобы теперь удалить последнего "потомка", сделаем так: zdes.removeChild(zdes.lastChild) а чтобы удалить их всех, так: function MyClear() { while (zdes.lastChild) { zdes.removeChild(zdes.lastChild) }; }; Теперь, можно посмотреть реализацию данных идей в примере тут: [[http://users.nsunc.com/~vlasov/javascript/simpledom.html|Пример динамического изменения документа]] Эта тема рассмотрена на сайте javascript.ru: [[http://javascript.ru/tutorial/dom/modify|Изменение страницы посредством DOM]]. **Другие возможности.** Можно упростить вставку, не формируя поддерево DOM, а вставляя лишь требуемый html-код. Об этом можно почитать, напр., тут: [[http://habrahabr.ru/post/235333/|JavaScript метод insertAdjacentHTML и beforeend]] или тут: [[http://innerhtml.ru/|Свойство innerHTML]]. **Использование css.** Для создания спойлеров, описанный выше метод может оказаться громоздким. Более простым решением будет манипуляция свойством стиля, например: display:none или display:block (см. описание [[http://htmlbook.ru/css/display|display]] или похожую технику [[http://htmlbook.ru/css/visibility|visibility]]) И реализовать тогда его можно следующим образом. Получаем как прежде ссылку на требуемый объект (html-ноду):
...
... var zdes = document.getElementById("label123")
Затем устанавливаем zdes.style.display = 'none'; и наш
..
вместе с содержимым визуально исчезнет. Выставим теперь: zdes.style.display = 'block'; и он появится! 8-) ==== Урок 5.1: Создаем свой спойлер ==== Сформулируем такую задачу: //необходимо создать разметку спойлера, основанную на тэгах div и необходимых классах, сопровождение в виде js-функций, с тем, чтобы при отсустствии поддержки javascript в окне браузера, все спойлеры были раскрыты и никаких затруднений (и даже напоминаний о спойлере) у пользователя не возникало.// Иными словами, выглядеть это должно примерно так:
...здесь скрываемый текст...
Для начала определим пару полезных нам функций: function getTagged(name, elem) { return (elem || document).getElementsByTagName(name); } function getNext(elem) { do { elem = elem.nextSibling; } while ( elem && elem.nodeType != 1 ); return elem; } Здесь первая функция ''getTagged'' собирает множество элементов с тэгом ''name'', при этом, если задан второй аргумент ''elem'', то в его <<потомках>>, если не задан, то -- по всему документу. Вторая функция ''getNext'' находит и возрващает следующий сестринский элемент, который не будет являться текстом. Следует иметь ввиду, что текстом может оказаться простой перевод строки, поэтому проверка elem.nodeType != 1 важна, если есть такой риск. Теперь, собственно, основной код: var alldiv = getTagged("div"); for (var j=0; j делает отбор только тэгов, помеченных классом ''spoilertitle''. Для этого контейнера, мы, во-первых вставляем следом (но перед спойлером!) html-текст из <<нестандартного>> атрибута ''text'': alldiv[j].insertAdjacentHTML('afterbegin', alldiv[j].getAttribute("text")); Строка alldiv[j].onclick = spoiling; создает обработчик события клика мышкой по содержимому контейнера. Заметим, что ''spoiling'' -- всего лишь ссылка на функцию, а не ее вызов типа ''spoiling(..)''! Строки alldiv[j].onmouseover = function(){this.style.textDecoration="underline"}; alldiv[j].onmouseout = function(){this.style.textDecoration="none"}; описывают поведение, когда наводим мышку на текст и когда уводим мышку. Также обращаем внимание, что вместо ссылки на функцию используем анонимную функцию, созданную прямо по месту применения. Далее, в блоке var nxt = getNext(alldiv[j]); while ( nxt.className != "spoiler" ) {nxt = getNext(nxt)}; nxt.style.border = "dotted black"; nxt.style.backgroundColor = "aqua"; nxt.style.display = "none"; во-первых, с помощью ''nxt = getNext(alldiv[j])'' получаем ссылку на следующий контейнер (сестринский элемент), перебираем их все, проверяя, чтобы был в наличии класс ''spoiler'': while ( nxt.className != "spoiler" ) {nxt = getNext(nxt)}; Для найденного элемента ''nxt'' устанавливаем требуемое стилевое оформление: nxt.style.border = "dotted black"; nxt.style.backgroundColor = "aqua"; nxt.style.display = "none"; где самое главное для нас -- скрытое по умолчанию состояние спойлера: ''nxt.style.border = "dotted black"'' И, наконец, рассмотрим функцию-обработчик клика, которая и осуществляет работу спойлера. Строки вроде таких var nxt = getNext(this); while ( nxt.className != "spoiler" ) {nxt = getNext(nxt)}; мы уже обсуждали. Команда console.log("check: ", nxt.style.display); позволяет нам осуществить запись в лог значения ''nxt.style.display''. Наконец, проверяем if (nxt.style.display == "none") {nxt.style.display = "block"; console.log("set=",nxt.style.display); return}; if (nxt.style.display == "block" || !nxt.style.display) {nxt.style.display = "none"; console.log("set=",nxt.style.display)}; состояние значения ''nxt.style.display'' и соответственно переобпредляем это значение на противополжное (отдельная забота о случае, если pyfxtybt ''nxt.style.display'' не определено). Код базируется на примерах, взятых из книги Резинга, создателя пакета ''jquery''; разность стилей в выполнении однотипных задач определяется ленью и забывчивостью... ===== Урок 6: динамическое изменение картинок и события задержки ===== В браузерах рисунки рассматриваются как объекты с набором некоторых свойств. Таким образом, новый рисунок может быть создан в скрипте таким образом: img1 = new Image(40,120); (однако, это не значит, что он будет отображен, тем не менее, он будет добавлен в кэш и в случае необходимости мгновенно отображен) Наиболее важным для нас атрибутом будет src, значение которого мы будем динамически менять. Сами рисунки в документе организованы в массив, к которому удобно обращаться, если нам ненужно или неудобно обращать к рисунку по имени-ссылке. Имя рисунка, заданного тегом будет совпадать со значением атрибута name. Вот как это реализовано в примере: [[http://users.nsunc.com/~vlasov/javascript/knopa.html|Дин. картинки]] ===== Урок 7: тайм-аут ;-) ===== [[http://users.nsunc.com/~vlasov/javascript/data.html|Пример работы с таймером и с датой]] демонстрирует "старый стиль" работы с таймером: вместо установки setInterval используем рекурсивный вызов таймера, и вместо передачи ссылки на функцию передаем строку с выражением для выполнения.
sic (на будущее) [[http://htmlweb.ru/java/example/calendar_kdg.php|работа с календарем]]