|
||||||||||||||||||||||
|
||||||||||||||||||||||
|
6. Динамічні веб-сторінки на основі JavaScript 6.1. Прості приклади До цих пір ми розглядали оформлення статичних веб-сторінок, тобто таких, які, будучи завантажені, вже зовні не змінюються. Проте останнім часом всього більшого поширення набувають так звані динамічні веб-сторінки. Вони можуть змінювати свій внеш- ший вигляд залежно від дій користувача або навіть самі по собі. Крім того, на них можуть бути присутніми динамічні елементи. Якими ж способами пишуться такі веб-сторінки? Ясно, що за допомогою звичайних тегов особливої динаміки досягти не можна. Існують, звичайно, теги <MARQUEE> (рядок”, що “біжить, підтримується тільки в Internet (Explorer) і <BLINK> (миготливий текст, підтримується тільки в Netscape). Існує визначене в стандарті CSS2 стильова властивість text-decoration: blink; (миготливий текст) і псевдоклас A:hover (зміна виду якоря/гипер- посилання при наведенні на них покажчика миші). Але це, звичайно, ще не динаміка. Запис інформації у веб-сервер-документ Для написання динамічних веб-сторінок використовуються фрагменти коду, написані на мові JavaScript (або іншій мові сценаріїв, про що мова піде нижчим), яка має синтаксис, відмінний від HTML. Для отде ленія цих фрагментів від решти частини HTML-документа вони распоагаются між тегамі <SCRIPT> і </SCRIPT> . Наприклад, так: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>SCRIPT!</TITLE> </HEAD> <BODY> <SCRIPT> document.write("Эта страница написана на JavaScript!"); </SCRIPT> </BODY> </HTML> Результат роботи цього коду показаний на мал. 6.1. Як бачите, поки нічого незвичайного. Цей же напис можна було написати і просто так, не використовуючи JavaScript - результат був би той же. Зате тепер ми знаємо, що якщо написати метод document.write, то на сторінку буде вставлено те, що далі стоїть в дужках. Якщо це текстовий рядок, то потрібно її укласти ще і в лапки.
Мал. 6.1. Просте використання JavaScript Гаразд, давайте трохи змінимо текст коду (для економії місця ми приводимо тільки текст сценарію, припускаючи, що все решта теги залишається такими ж, як в попередньому прикладі): <SCRIPT> window.status = "Эта страница написана на JavaScript!"; </SCRIPT> Результат можна побачити на мал. 6.2. Тепер вікно броузера абсолютне порожнє! Але це і правильно, адже ми ж не вводили ніякого тексту. Зате якщо ви подивитеся на рядок стану, то побачите там наш напис. У цьому рядку завжди з'являється значення, привласнене об'єкту window.status. Знак рівності в JavaScript означає “привласнити значення
Мал. 6.2. Зміна рядка стану Добре, скажете ви, ось ми вже управляємо рядком стану, але де ж обіцяна динаміка? Ну, якщо не терпиться, то можна ще небагато змінити код попереднього прикладу: <SCRIPT> window.status = "Эта страница написана на JavaScript!"; setTimeout("window.status = 'А вы как думали?'",2000); </SCRIPT> Тепер у момент завантаження наша сторінка виглядатиме так само, як і в попередньому прикладі, проте через дві секунди вміст рядка стану зміниться на фразу “А ви як думали?”. Річ у тому, що функція setTimeoutO, яку ми тут використовували, здійснює дію, визначену усередині неї, з деякою затримкою. Ця затримка обчислюється в мілісекундах (тисячних долях секунди). Відповідно, значення 2000 відповідає затримці в 2 секунди. Само дія визначається у вигляді рядка, тобто повинно бути поміщено в лапки. Тому фразу “А ви як думали?” довелося укласти в інший тип лапок - так звані одинарні, щоб броузер не “заплутався”. У JavaScript (як і в HTML) допускається використання і тих, і інших лапок, потрібно тільки уважно стежити, щоб всі лапки в потрібному місці закривалися. Не можна було написати так: . setTimeout("window.status = "А вы как думали?"", 2000); оскільки тоді броузер “вирішив би”, що рядок закінчився після знаку рівності, а далі, не зустрівши коми, поскаржився б на помилку. До речі, необхідно уважно стежити, щоб в JavaScript-фрагментах не було помилок. Ви пам'ятаєте, що якщо броузер зустрічає помилку синтаксису HTML (наприклад, незрозумілий йому тег), то він його просто ігнорує. Але якщо броузер зустріне помилку в коді JavaScript, то буде видано повідомлення про помилку, причому важ сценарій не буде виконаний. Ще одна деталь: у JavaScript необхідно дотримувати регістр символів, оскільки в цій мові розрізняються прописні і рядкові букви. Напри заходів, якщо замість setTimeoutO написати SetTimeoutO або settimeoutQ, то буде видано повідомлення про помилку. Інтерпретація мови JavaScript Перш ніж розглянути який-небудь осмислений приклад, необхідно відзначити ще декілька моментів. По-перше, броузери можуть інтерпре- тіровать фрагменти JavaScript по-різному, але про це мова піде нижчим. По-друге, треба передбачити варіант, коли броузер взагалі “не поні- клопоту” сценаріїв (сценаріями називають фрагменти, написані на мові JavaScript і інших подібних мовах, що інтерпретуються). В цьому випадку він, швидше за все, пропустить текст, ув'язнений між тегамі <SCRIPT> і </SCRIPT> . Але тоді користувач цього броузера нічого не побачить на екрані. Щоб таких неприємностей не відбувалося, придумайте альтернативний HTML-текст, який би відображався в броузерах, що не підтримують сценарії. Його потрібно укласти між тегамі <NOSCRIPT> і </NOSCRIPT> . Якщо ж придумати такий текст абсолютно неможливо, напишіть між цими тегамі хоч би те, що для проглядання цієї сторінки необхідний броузер, підтримуючий JavaScript, і поставте на нього гіперпосилання. Але це ще не все. Уявіть собі, що броузер користувача вже дуже старий і взагалі не розуміє тег <SCRIPT> . Що буде тоді? Як і порожнисто жено, він цей тег проігнорує, і тоді важ код сценарію відобразиться на екрані, а це зовсім непривабливо. Щоб цього уникнути, прийнято укладати код сценарію теги коментарів <!-- і -->. Проте деякі інтерпретатори JavaScript, вбудовані в броузери, при цьому намагаються обробити другою з цих тегов. Тому перед ним зазвичай ставлять цим віл JavaScript-коментаря //. Таким чином, виходить приблизно наступне: <SCRIPT> window.status = "Эта страница написана на Javascript!"; setTimeout("window.status " 'А вы как думали?'", 2000); //--> </SCRIPT> Облік версії броузера Тепер давайте розглянемо простій приклад. Припустимо, що у нас вже є сторінки, створені спеціально для броузера Internet Explorer 4, Netscape 4 або Netscape 6. Ми хочемо написати код, який би визначав тип броузера користувача і, залежно від цього, завантажувала б одну з наших сторінок. Крім того, він повинен видавати попередження, якщо виявить застарілий броузер (версії 3 і нижче). Спочатку давайте напишемо таке попередження. Щоб користувач напевно звернув на нього увагу, можна використовувати метод alert. Застосовується він точно так, як і вже знайомий нам метод document.write, але при цьому виводить текст не прямо на сторінку, а в діалогове вікно. Поки користувач не натисне кнопку ОК, робота сценарію не буде продовжена. Як визначити номер версії броузера? Для цього існує властивість navigator.appVersion. Проте його значенням є не число (власне номер версії), а цілий рядок. Наприклад, якщо написати: document.write(navigator.appVersion) ; то в броузере Internet Explorer 5 буде видане таке повідомлення: 4.0 (compatible; MSIE 5.0; Windows 98; DigExt) Netscape і інші броузери також видають подібний довгий рядок. Як же виділити з неї номер версії? На щастя, перша цифра цього рядка у всіх броузерах указує саме на номер версії (у Internet Explorer 5 на цьому місці залишили цифру 4, щоб підкреслити схожість цих версій.) Оскільки після цього номера коштує крапка, тобто не цифра, його легко виділити зі всього рядка за допомогою функції parselnt(). Вона завжди виділяє ціле число з рядка, зупиняючись на не першій цифрі. В даному випадку нам треба, якщо номер версії менше 4, видати застережливе діалогове вікно. Для перевірки умови в JavaScript існує оператор if, після якого в дужках слід поставити умову. Тому ми можемо написати так: if (parseint(navigator.appVersion)<4) alert("Вы используете старую версию броузера.\nВ ней страница может отображаться неправильно") ; При цьому метод alert буде виконаний тільки тоді, коли умова номер версії менше 4 виконується, а інакше він буде просто пропущений. Ви, напевно, звернули увагу на дивне поєднання . Воно використовується в JavaScript як спеціальний символ, переклад рядка. Взагалі, в рядках JavaScript символ зворотної косої межі разом з наступним за ним символом завжди означає спеціальний символ. В даному випадку друга пропозиція в нашому діалоговому вікні почнеться з нового рядка. Добре, попередження ми написали, тепер потрібно визначити тип броузера. Для цього існує властивість navigator.appName. У Internet Explorer його значенням є “Microsoft Internet Explorer”, а в броузерах компанії Netscape - просто “Netscape”. Оскільки для кожного випадку нам треба передбачити ряд дій, зручно використовувати оператора switch (пері ключатель). Схемне його використання можна зобразити так: switch (умова) { case "перший випадок": якісь дії case "другий випадок": якісь дії і т.д. default: дії в решті всіх випадків У нашому прикладі умовою є значення navigator.appName, а випадки можуть бути такими: "Microsoft Internet Explorer" і "Netscape". switch (navigator.appName) { case "Microsoft Internet Explorer": якісь дії case "Netscape": якісь дії дії в решті всіх випадків Звернете увагу на те, що важ блок коду, що йде після умови, дол-жен бути поміщений у фігурні дужки. До речі, ці фігурні дужки грають велику роль в JavaScript. Наприклад, в них завжди можна укласти деяку послідовність дій, щоб вона інтерпретувалася як одне ціле (про це ми ще поговоримо нижче). Щоб завантажити іншу веб-сторінку замість даної, потрібно привласнити нове значення властивості window.location.href. Наприклад, якщо написати: window.location.href = "msie4.html"; то поточна сторінка буде замінена у вікні броузера на сторінку msie4.html. Давайте перед завантаженням нової сторінки створимо відповідне повідомлення: document-write ("Сейчас будет загружена страница для Internet Explorer 4") ; setTimeout("window.local ion.href = 'msie4.html'", 3000); При цьому нам довелося використовувати функцію setTimeout, щоб користувач встиг побачити наш напис. Оскільки на цьому дії, передбачені для даного випадку, закан- чиваются, потрібно вийти з блоку switch за допомогою оператора break. Після цього можна приступати до обробки інших випадків. Якщо тип броузера визначився як Netscape, нам потрібно знову дивитися його версію. Ми можемо використовувати для цього оператора if...else: if (parseint(navigator.appversion)<=4) { document.write ("Сейчас будет загружена страница для Netscape 4"); setTimeout("window, location.href = 'nn4.html'", 3000); } else { document.write ("Сейчас будет загружена страница для Netscape 6") ; setTimeout("window.location.href = 'nn6.html'", 3000); } Если условие parselnt(navigator.appversion)<=4 вірно, то виконується блок операторів, наступний відразу після умови, а якщо невірно, то виконується блок, наступний після ключового слова else. Крім того, потрібно передбачити дії для решти всіх випадків. Правда, такі випадків буде небагато, оскільки багато броузери (наприклад Opera) люблять представлятися як Netscape. Проте передбачити такі дії все одно треба. Можна, наприклад, запропонувати користувачеві уручну вибрати потрібну сторінку: alert ("Вы используете неизвестный нам тип броузера. \пСейчас вам будет предложено выбрать версию страницы, которую следует загрузить"); document.write ("<A HREF='msie4.html'>Страница для Internet Explorer 4</A><BR>"); document.write ("<A HREF='nn4.html'>Страница для Netscape 4 </A><BR>") ; document.write ("<A HREF='nn6.html'>Страница для Netscape 6 </A>");
Итак, теперь посмотрим, что же у нас получается в целом: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <ТIТLЕ>Автоматический выбор нужной версии cтpaницы</TITLE> </HEAD> <BODY> <SCRIPT> < ! -- if (parseint(navigator.appVersion)<4) alert("Вы используете старую версию броузера.\nВ ней страница может отображаться неправильно") ; switch (navigator.appName) case "Microsoft Internet Explorer": document.write ("Сейчас будет загружена страница для Internet Explorer 4"); setTimeout ("window.location.href = 'msie4.html'", 3000); break; case "Netscape": if (parseint(navigator.appversion)<=4) { document.write ("Сейчас будет загружена страница для Netscape 4") ; setTimeout("window.location.href = 'nn4.html'", 3000); } else { document.write ("Сейчас будет загружена страница для Netscape 6"); setTimeout("window.location.href = 'nn6.html'", 3000); } break; default: alert ("Вы используете неизвестный нам тип броузера.><nСейчас вам будет предложено выбрать версию страницы, которую следует загрузить"); document.write ("<A HREF='msie4.html'>Страница для Internet Explorer 4</A><BR>") ; document.write ("<A HREF='nn4.html'>Страница для Netscape 4</A><BR>") ; document.write ("<A HREF='nn6.html>Страница для Netscape 6</A>"); } //—> </SCRIPT> </BODY> </HTML> Результат проглядання цієї сторінки залежить від броузера. На мал. 6.3 зображено попередження, яке отримає користувач при прогляданні цієї сторінки в броузере Internet Explorer.
Мал. 6.3. Використання умовної переадресації і тимчасової затримки Таблиця множення Приведений приклад достатньо простий, але він демонструє способи використання деяких основних операторів JavaScript. Тепер розглянемо ще один дуже простій приклад, який демонструє, як можна іноді скоротити собі працю за допомогою мови JavaScript, а заразом розглянемо оператора циклу for. Допустимо, нам потрібно було представити таблицю множення. Звичайно, можна уручну написати кожен її рядок: <TABLE> <TR> <TD>2×2=4</TD> <TD>3×2=6</TD> <TD>4×2=8</TD> І т.д. (До речі, спеціальний символ × означає знак множення.) Це спосіб достатньо довгий і нудний, крім того, легко можна допустити випадкову помилку і не відмітити її. Давайте спробуємо згенерувати таблицю прямо на ході”, використовуючи засоби JavaScript. Teг <TABLE> можна винести за межі сценарію. Далі, потрібно сформувати деяку кількість рядків (традиційно рівне кількості варіантів другого множника, який зазвичай приймає значення від 2 до 10). Можна цей множник занести в змінну (назвемо її “I”) і написати: for (i=2; i<=10; i++) { document.write ("<TR>"); document.write ("</TR>") ; } Вираз в дужках після оператора циклу for означає наступне: • початкове значення змінної - 2; умова виконання циклу - змінна повинна бути менше або рівна 10; на кожному кроці змінна збільшується на 1 (позначення “++” означає збільшення на одиницю, а “- -” зменшення на одиницю.) Якщо зараз запустити цей цикл, то у вікні броузера нічого не відобразиться, оскільки поки немає тегов елементів таблиці ( <TD> ). Оскільки в кожному рядку повинне бути стільки осередків, скільки значень приймає перший множник (занесемо його в змінну “j”), організовуємо між записом тегов <TR> і </TR> ще один цикл: for (j=2; j<10; j++) document.write("<TD>"+j+"×"+i+"="+(i*j)+"</TD>") ; Тут умовою виходу з циклу є j<10, а не j<=10, оскільки традиційно перший множник в таблиці множення не перевищує 9. Звернете увагу на рядок методу document.write. Тут в лапках вказане те, що потрібно безпосередньо помістити на сторінку. Змінні ж вказані поза лапками, щоб в документ записувалися їх значення. Весь рядок з'єднується знаками “+”. Щоб отримати результат множення змінної i змінну j, використаний запис “i*j”. Знак * означає в JavaScript множення, а знак / (коса межа) - ділення. Є ще операція “залишок від ділення”, що позначається знайомий %. Значення твору i*j в нашому прикладі поміщене в дужки, щоб виключити можливість неправильної інтерпретації броузером, хоча це не обов'язково. В принципі, наша таблиця вже готова! Залишилося тільки оголосити змінні i і j на початку сценарію (взагалі-то, як правило, цього можна навіть і не робити, але щоб уникнути випадкових помилок краще перестрахуватися, та і взагалі оголошення змінних є хорошим тоном і полегшує сприйняття коду). Для цього треба використовувати ключове слово var: var i,j; Крім того, для поліпшення сприйняття, можна “розлініяти” таблицю, відокремивши стовпці один від одного. Для цього, як ви пам'ятаєте, потрібно ісполь зовать атрибут RULES= тега <TABLE>: <TABLE BORDER="1" CELLSPACING="0" CELLPADDING="2" RULES="cols"> Останнім штрихом до форматування наший таблиці буде вирівнювання тексту в осередках по правому краю. Для цього можна просто додати після тега <TABLE> тег <COLGROUP SPAN=10 ALIGN-"right"> або ж просто визначити в стильовому блоці властивість для тега <TD>: TD { text-align: right; ) У нашому випадку цей варіант, мабуть, переважно, оскільки деякі броузери можуть не розпізнати атрибут ALIGN= тега <COLGROUP>. Тепер давайте подивимося, що у нас виходить в цілому. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Ta6лица умножения</TITLE> </HEAD> Teг <COLGROUP> задает группировку столбцов таблицы, а тег <COL> — вид каждого столбца, принятый по умолчанию. К сожалению, не все броузеры интерпретируют эти теги достаточно корректно. <STYLE> BODY { text-align: center; background-color: #FCF7EC; } TD { text-align: right; } </STYLE> <BODY> <Н2>ТАБЛИЦА УМНОЖЕНИЯ</Н2> <TABLE BORDER""!" CELLSPACING="0" CELLPADDING="2" RULES="cols"> <SCRIPT> <!-- var i, j ; for (i=2; i<=10; i++) { document.write ("<TR>"); for (j=2; j<10; j++) document.write("<TD>"+j+"×"+i+"="+(i*j)+"</TD>") ; document.write ("</TR>") ; } //--> </SCRIPT> </TABLE> </BODY> </HTML> Результат роботи цього коду показаний на мал. 6.4. До речі, ви можете відмітити, що вирівнювання по правому краю в кожному елементі таблиці все ж таки не зовсім естетично. Краще було б, якби всі знаки рівності в одному стовпці знаходилися один під іншим. Взагалі кажучи, для цього в HTML 4.0 є спосіб, званий вирівнюванням по символу. <COLGROUP SPAN=10 ALIGN="char" CHAR="="> Вірогідно, такий запис повинен дати якраз необхідний результат - вирівняти всі знаки рівності в кожному стовпці. Проте на момент написання цих рядків така можливість ще не реалізована ні в одному броузере! Запит відомостей у читача Як бачите, нам не довелося уручну заповнювати всі елементи таблиці, ми обмежилися натомість шістьма витонченими рядками коду. Крім того, якщо вам раптом знадобиться розширити таблицю, наприклад організувати виведення значень аж до 20х20, це можна зробити, просто замінивши два числа в коді (10 на 20). Більш того, ми тепер можемо дати користувачеві
Мал. 6.4. Генерація таблиці “на льоту” можливість самому визначити межі значень множників таблиці. Наприклад, це можна зробити таким чином. При завантаженні сторінки за допомогою методу prompt попросити його ввести мінімальне і максимальне значення кожного множника, наприклад: mini = prompt ("Введите минимальное значение первого множителя", "2"); Тут є пояснення і поле для введення, де вже приготовано значення, прийняте за умовчанням. І пояснення, і значення, прийняте за умовчанням, необхідно вказати при виклику методу prompt, як показано вище. Значення, введене користувачем, буде привласнено змінною mini. Якщо користувач натисне кнопку Відміна, то цим значенням буде null (так в JavaScript позначається ніщо, тобто відсутність якого-небудь значення). Отже, за допомогою методу prompt ми просимо ввести значення (доведеться використовувати цей метод 4 рази), привласнюємо їх змінним і підставляємо ці змінні в умови циклу, наприклад, так: for (j=minl; j<=maxl; j++) document.write("<TD>"+j+"×"+i+"="+(i*j)+"</TD>"); <STYLE> BODY { text-align: center; background-color: #FCF7EC; } TD { text-align: right; } </STYLE> <BODY> <Н2>ТАБЛИЦА ВОЗВЕДЕНИЯ В СТЕПЕНЬ</Н2> <TABLE BORDER="1" CELLSPACING="0" CELLPADDING="2" RULES="cols"> <SCRIPT> <! -- var i,j; for (i=2; i<=10; i++) { document.write("<TR>") ; for (j=2; j<10; j++) document.write("<TD>"+j+"<SOP>"+i+"</SUP>="+ Math.pow(j,i)+"</TD>") ; document.write("</TR>") ; } //--> </SCRIPT> </TABLE> </BODY> </HTML> Якщо подивитися уважно, то можна відмітити, що вся відмінність полягає в заголовках і рядку запису осередку. У ній ми використовували тег <SUP> для запису показника ступеня. А для обчислення результату тут ісполь- зуєтся метод Math.pow, який, до речі, дуже простий у використанні. Наприклад, щоб обчислити 5 7, досить написати Math.pow(5,7). Отже, в цьому розділі були показані приклади використання сценаріїв JavaScript. Нижче ми розглянемо, як можна скоротити кількість коду, використовуючи так звані функції.
|