Урок 10 - Ещё о массивах
- многомерные массивы;
- встроенные массивы;
- усовершенствованный фотоальбом;
- оператор-помощник with.
Многомерные массивы
Многомерные массивы в JavaScript — это массивы, содержащие внутри себя другие массивы.
Чтобы это проиллюстрировать, представим себе заготовку двухуровнего меню в виде списка.
Сначала объявим массив:
| list = new Array() |
Теперь объявим его первый элемент как массив из трёх элементов — наших основных пунктов меню.
| list[0] = new Array("Меню 1", "Меню 2", "Меню 3") |
В этом «массиве в массиве» у нас три элемента, которые можно вызвать как 0, 1 и 2 (помним, что отсчёт ведётся с нуля).
Теперь, вызывая list[0][0], мы получим «Меню 1», вызывая list[0][1] — «Меню 2», и т.д.
Следующие элементы главного массива заготавливаем как массивы пунктов подменю:
| list[1] = new Array("Меню 1.1", "Меню 1.2", "Меню 1.3") list[2] = new Array("Меню 2.1", "Меню 2.2") list[3] = new Array("Меню 3.1", "Меню 3.2", "Меню 3.3", "Меню 3.4") "tratata" |
Вызываются аналогично: например, list[1][2] («Меню 1.3») или list[2][0] («Меню 2.1»).
Теперь формируем список:
| /*Первый уровень, первый пункт*/ document.writeln("<ul><li>" + list[0][0] + "</li>") /*Второй уровень*/ document.writeln("<ul><li>" + list[1][0] + "</li>") document.writeln("<li>" + list[1][1] + "</li>") document.writeln("<li>" + list[1][2] + "</li></ul>") /*Первый уровень, второй пункт*/ document.writeln("<li>" + list[0][1] + "</li>") /*Второй уровень*/ document.writeln("<ul><li>" + list[2][0] + "</li>") document.writeln("<li>" + list[2][1] + "</li></ul>") /*Первый уровень, третий пункт*/ document.writeln("<li>" + list[0][2] + "</li>") /*Второй уровень*/ document.writeln("<ul><li>" + list[3][0] + "</li>") document.writeln("<li>" + list[3][1] + "</li>") document.writeln("<li>" + list[3][2] + "</li>") document.writeln("<li>" + list[3][3] + "</li></ul></ul>") |
Результат:
- Меню 1
- Меню 1.1
- Меню 1.2
- Меню 1.3
- Меню 2
- Меню 2.1
- Меню 2.2
- Меню 3
- Меню 3.1
- Меню 3.2
- Меню 3.3
- Меню 3.4
Для чего это нужно?
Чтобы для настройки и «оживления» меню можно было программно обращаться к его пунктам как к элементам массива.
Таким же образом можно загнать в многомерный массив, скажем, таблицу и написать скрипт, который при нажатии определённых кнопок или заголовков будет выполнять сортировку (по алфавиту, по величине и т.д.).
О методах сортировки элементов массива я расскажу, когда мы будем говорить о методах JavaScript.
Встроенные массивы
Поскольку JavaScript предназначен прежде всего для web-страниц, некоторые элементы HTML встроены в него как массивы (иногда их называют коллекциями).
К таким массивам-коллекциям относятся формы — forms() и изображения — images().
Допустим, на нашей web-странице несколько раз встречается тэг <img>. Первый <img> будет автоматически определяться какimages[0], и т.д. по порядку появления в коде. То же и с формами.
Иногда это бывает удобно, но не всегда.
В Ассоциации «Русская Традиция» при Питерском Союзе композиторов, в которой я состою, двое из музыкантов являются также и одарёнными художниками. Я сделал на сайте Ассоциации маленькую галерею (можете посмотреть) и использовал эту встроенную коллекцию. А потом решил резко поменять дизайн всего сайта. Но поскольку в элементах дизайна тоже есть графика, то нумерация сбилась, и я двое суток сидел и правил цифры. А на третьи сутки до меня дошло, что лучше это сделать, например, через getElementById() — помните? — присваиваем тэгу id и обращаемся к нему этим методом.
Но есть от встроенных массивов и настоящая польза. У элементов этих массивов есть свойства, присущие их объектам-прототипам. Так, элементы коллекции forms() имеют свойства method, action, name, а элементы images() — свойства src, width,height. Таким образом, мы можем создавать некие «абстрактные» элементы массива, а потом определять для них конкретный тэг. Это хорошо работает в слайд-шоу, когда в одном тэге программно заменяются картинки, определённые в скрипте.
Чтобы создать такой элемент, нужно объявить обычный массив и переопределить его элементы:
| imgslide = new Array() imgslide[0] = new Image() imgslide[1] = new Image() |
Обратите внимание: элементы называются в единственном числе — Image() (и с большой буквы), а не images() (с маленькой буквы), как вся коллекция.
Усложняем слайд-шоу № 9
В «Диких уроках HTML» урок № 9 посвящён созданию слайд-шоу на JavaScript. Мы немного усложним этот скрипт.
Там фотоальбом посвящён кошкам. Я тоже люблю и кошек, и собак, но ещё больше — друзей. Есть у меня друг Гена Змитрович, талантливый скульптор и художник. И в нашем уроке я хочу представить несколько его работ. А поскольку он выступает в двух ипостасях — как художник и как скульптор — у нас будет два слайд-шоу, с картинами и скульптурами, но управляться они будут одним скриптом.
Этот скрипт — своего рода контрольное задание. Кроме массивов, в нём используется ряд операторов, которые мы изучили, а также он продемонстрирует, как можно использовать логический (булев) тип данных.
Если Вы сможете сами соорудить подобный скрипт, значит, уже перешли из категории «чайников» в категорию «кофейников»:)
Объявим две переменных счётчика и два массива — для картин и для скульптур. Элементы массивов сразу объявим как images.
(В первоначальном варианте я для простоты дал один счётчик, но с ним функция работала не совсем корректно. Так что пусть будет немного сложнее, но без халтуры.)
| var i = 0, j = 0; imgslide = new Array() imgslide[0] = new Image() imgslide[1] = new Image() imgslide[2] = new Image() imgslide[3] = new Image() imgslide[4] = new Image() imgslide2 = new Array() imgslide2[0] = new Image() imgslide2[1] = new Image() imgslide2[2] = new Image() imgslide2[3] = new Image() imgslide2[4] = new Image() |
Высота у всех изображений одинаковая — 300 px. А вот ширина немножко разная. Воспользуемся свойствами элементов встроенного массива. Кроме ширины width укажем имена и пути файлов src.
| imgslide[0].src = "album/plakha.jpg" imgslide[0].width = "225" |
Что, так и будем по два раза каждый элемент прописывать?
Для сокращения кода существует вспомогательный оператор with. Сейчас научу, как им пользоваться.
Один раз упомянув в круглых скобках объект, в фигурных можно выписать все его свойства и методы через точку с запятой:
| with (объект) {свойство_или_метод; свойство_или_метод} |
Теперь наш код приобретёт более компактный вид:
| with (imgslide[0]) {src = "album/plakha.jpg"; width = "225"} with (imgslide[1]) {src = "album/grav.jpg"; width = "224"} with (imgslide[2]) {src = "album/history.jpg"; width = "200"} with (imgslide[3]) {src = "album/porog.jpg"; width = "202"} with (imgslide[4]) {src = "album/dedal.jpg"; width = "232"} with (imgslide2[0]) {src = "album/applegir.jpg"; width = "178"} with (imgslide2[1]) {src = "album/atlant.jpg"; width = "181"} with (imgslide2[2]) {src = "album/afrodita.jpg"; width = "193"} with (imgslide2[3]) {src = "album/turgenev.jpg"; width = "199"} with (imgslide2[4]) {src = "album/obelisk.jpg"; width = "222"} |
Все картины и скульптуры как-то называются. Картины у Змитровича философские. А среди скульптур есть и памятник, и кубок, и просто миниатюры. С названиями легче. Давайте сделаем, чтобы и названия выпрыгивали.
Для этого заготовим ещё два массива — тоже для картин и для скульптур.
| imgname = new Array() imgname[0] = "Плаха" imgname[1] = "И сказал Бог: «Да будет свет!»<br><small>по гравюре Г. Доре</small>" imgname[2] = "История" imgname[3] = "Порог" imgname[4] = "Дедал" imgname2 = new Array() imgname2[0] = "Девочка с яблоком" imgname2[1] = "Почетный приз «Атлант»" imgname2[2] = "Пеннорожденная Афродита" imgname2[3] = "И.С.Тургенев" imgname2[4] = "Памятник Л.Богданову" |
Принцип работы будет такой: в левой половине — слайд с картинами и под ним две кнопки: «вперёд» и «назад». Под кнопками — меняющееся название. Справа — аналогичная конструкция для скульптур (всё это можно поместить в таблицу с двумя <td> по 50%). Кнопки мы возьмём из стандартного элемента form.
Сейчас напишем этакую многофункциональную функцию, которая отрегулирует работу всей этой системы.
Сначала сформулируем задачи:
Кнопка «вперёд» должна «бесконечно» прокручивать картинки вперёд, то есть, дойдя до конца, возвращаться к началу.
Кнопка «назад» должна делать то же самое, но в обратном направлении.
Пары кнопок должны работать автономно, прокручивая только свой слайд.
Вот сейчас и пора вспомнить гениального Джорджа Буля, который утверждал, что самые сложные проблемы можно решить через последовательность цепочек «да» и «нет».
Нам нужны всего две таких цепочки:
вперёд-назад — да-нет;
картины-скульптуры — да-нет.
Эти два булевых выражения и станут аргументами нашей функции. Поскольку это «родная дочь» функции dem(n) из Дикого урока № 9, назовём её dem_plus(n,k). Приведу её всю, а дальше будем разбираться, что к чему.
| function dem_plus(n, k) { var dlina; switch (k) { case true: // определяем размерность первого массива // и подставляем значение в код для кнопок dlina = imgslide.length if (n == true) { i++; if (i == dlina) i = 0; } else {i--; if (i == -1) i = (dlina - 1); } with(document.images("pic")) {src = imgslide[i].src; width=imgslide[i].width} document.getElementById("picname").innerHTML = imgname[i] break case false: // определяем размерность второго массива // и снова подставляем, используя новый счётчик dlina = imgslide2.length if (n == true) { j++; if (j == dlina) j = 0; } else {j--; if (j == -1) j = (dlina - 1); } with(document.images("sculp")) {src = imgslide2[j].src; width = imgslide2[j].width} document.getElementById("sculpname").innerHTML = imgname2[j] } } |
Количество картин и скульптур в нашем примере одинаково. Но оно может быть и разным. Для этого нам и нужны два счётчика. Но это ещё не всё. Для правильной работы функция должна «знать» фактическую длину каждого массива. Поэтому объявим в ней переменную dlina, чтобы, воспользовавшись свойством массива length, динамически определить «потолок» для каждой группы слайдов.
(Вспомните, что переменная, объявленная внутри функции, «живёт» только в теле этой функции. Но здесь нам этого вполне достаточно.)
Сначала разнесём разные слайды. С этим управится второй аргумент — k. Тут никаких особых действий — просто «да» и «нет». Не будем конструировать «если бы да кабы», а используем простой переключатель switch. И в случае true (картины) будем использовать счётчик i, а в случае false (скульптуры) — j.
Аргумент n отвечает за «вперёд-назад». Если он true, то вперёд. Счётчик (i или j) будет считать картинки по возрастающей.
Теперь внимание: пошла арифметика, в которой можно и запутаться.
Какова размерность массива картин (скульптур)? Как мы помним, это составит их реальное количество + 1 (см. прошлый урок). Значит, dlina даст нам на 1 номер больше, чем их количество.
Значит, когда счётчик перейдёт на значение dlina (элемента с таким номером уже нет, понятно, почему?), нужно взмахнуть волшебной палочкой и превратить его в 0. Вот видите, можно и так циклы делать, не используя специальных операторов. Но здесь нам не нужен самодвижущийся цикл. «Движок» — это «юзер» с мышкой.
В противном случае (else) делаем «пач-пач-пач» (назад). За нулём — что там в школе проходили? Минус единичка. Её-то мы и превращаем в...
Будьте внимательны! В dlina - 1. Именно это и будет номером последней картинки, который нам нужен.
Кончилась абстракция, теперь мы имеем дело с конкретными объектами на web-странице. Давайте отвлечёмся от функции и подготовим плацдарм.
Вот наши окошки для слайдов. Можно воспользоваться и порядковыми номерами из коллекции. Но давайте дадим дизайнеру возможность оформить страницу, не заморачиваясь сохранностью её содержимого. Поэтому лучше дадим нашим окошкам имена собственные: pic и sculp.
Да, у нас же ещё и названия! Так что зададим имена и тем абзацам или заголовкам (у меня <h3>), в которых эти названия должны появляться.
Теперь вернёмся к функции. Зададим для подготовленных окошек имя файла и ширину картинки (можно опять через with), а также текст названия (из массивов imgname и imgname2). В качестве номера элемента указываем счётчик. Если счётчик будет работать правильно, он сам будет подставлять нужные номера.
Метод innerHTML возвращает то, что находится внутри указанного тэга HTML (в данном случае — текст). Подробнее об этих методах будем говорить позже.
Разбросаем всё по случаям true (картины) false (скульптуры).
Не забудем поставить break!
Нам нужно либо одно, либо другое, а не всё сразу!
Аккуратно закрываем все скобки. Функция готова.
Вызывать её будем из кнопок формы (из атрибута onClick) с нужными аргументами (true или false).
В реальные тэги HTML (по умолчанию) вставим параметры нулевых слайдов.
Вот примерно что должно быть в <body> (проанализируйте, как расподожены аргументы true и false в вызовах функции):
| d<table width="100%" border="0" cellspacing="0" cellpadding="0"align="center"> <tr> <td width="50%" align="center"> <h3>Живопись</h3> <img src="album/plakha.jpg" alt="" name="pic" id="pic" width="225"height="300" border="0"></td> <td width="50%" align="center"> <h3>Скульптура</h3> <img src="album/applegir.jpg" alt="" name="sculp" id="sculp" width="178"height="300" border="0"></td> </tr> <tr> <td align="center"><form name="form1"> <input type="button" value="Назад" onClick="dem_plus(false, true)"> <input type="button" value="Вперед" onClick="dem_plus(true, true)"> </form> <h3 id="picname">Плаха</h3></td> <td align="center"><form name="form2"> <input type="button" value="Назад" onClick="dem_plus(false, false)"> <input type="button" value="Вперед" onClick="dem_plus(true, false)"> </form> <h3 id="sculpname">Девочка с яблоком</h3></td> </tr> </table> |
А теперь смотрим, как это работает.
Не работает?..
Ага, значит, у Вас браузер Netscape, Mozilla или Firefox. Они не всегда понимают document.images (впрочем, иногда и понимают, но действуют непредсказуемо).
Как это исправить?
Так Вы уже знаете, как.
У наших тэгов <img> есть id? А знаем мы, что такое getElementById? Ну так полный вперёд!
Это будет Вашим самостоятельным домашним заданием. А чтобы проверить себя и заглянуть в ответ... у Вас есть мышка с двумя, по крайней мере, кнопками. Поняли, где лежит ответ?
Геннадий Змитрович
скульптор и художник
Живопись![]() | Скульптура![]() |
Плаха | Девочка с яблоком |
Подробнее с работами автора можно познакомиться на сайте Геннадия Змитровича
После небольших каникул приступим ко второй фазе знакомства с JavaScript.
Итак, мы узнали:
какие бывают массивы и как их можно использовать, а также как использовать вспомогательный оператор with.
А также научились:
делать не самое простое слайд-шоу, а возможно, даже подгонять его под разные браузеры.
источник http://www.dikarka.ru/




