Урок 5 - Операторы условного перехода

...

  • оператор if...else;
  • оператор switch

Отдохнули?

А теперь снова запаситесь терпением... всерьёз и надолго...

Сложные операторы действительно сложные. Слово «сложно» можно перевести на английский разными словами, в том числе — complex, то есть «комплексно», «много всего». А мы будем изучать эти операторы маленькими порциями. Если разбить задачу на составляющие, она не такая уж и сложная, оказывается. Но хочется-то всего сразу! Потерпите. Наступило время копнуть вглубь.

Оператор if...else

Принцип работы и синтаксис мы уже знаем. Напомню ещё раз:

if (условие) {этот код работает при выполненном условии} else {этот код работает, если условие не выполнено}

А если при невыполненном условии нам вообще никакого кода не надо?

Тогда так:

if (условие) {этот код работает при выполненном условии} // И больше ничего

А можно ли смоделировать в этом операторе следующую ситуацию?

Предположим, у Вас очень необычный дизайн, который никак не подогнать под разные типы браузеров. И вот Вы героически решили написать три почти одинаковых страницы, одна из которых правильно смотрится в IE, другая — в Netscape и Mozilla, а третья — в Opera. А теперь надо сделать такой скрипт, который при нажатии на ссылку проверил бы браузер пользователя и открыл бы ему нужную страницу.

Если (условие1 — IE), то {код1 — открытие index_ie.html}, если нет, то если (условие2 — NS или MOZILLA), то {код2 — открытие index_ns.html}, если нет, то если (условие3 — OPERA), то {код3 — открытие index_op.html}.

Этот алгоритм несовершенен: если браузер не подходит ни под одно из определений, то по ссылке не откроется ничего. Но при таком раскладе яснее проступит синтаксис вложенных операторов, что я и хочу в первую очередь продемонстрировать.

Для определения типа браузера у объекта navigator существует свойство appName

У IE это свойство имеет значение "Microsoft Internet Explorer", у NS и Mozilla"Netscape", а у Opera"Opera".

Заготовим тэги для скрипта

<script type="text/javascript"> </script>

и начнём его заполнять. Для начала предлагаю объявить переменные для имён браузеров: и основной код компактнее будет, и потренируемся, кстати.

<script type="text/javascript"> var IE = (navigator.appName == "Microsoft Internet Explorer"); var OP = (navigator.appName == "Opera"); var NS = (navigator.appName == "Netscape"); </script>

А теперь добавим основной код, и скрипт будет выглядеть так:

<script type="text/javascript"> var IE = (navigator.appName == "Microsoft Internet Explorer"); var OP = (navigator.appName == "Opera"); var NS = (navigator.appName == "Netscape"); if (IE) { self.parent.location = "index_ie.html"; } else { if (NS) { self.parent.location = "index_ns.html"; } else { if (OP) { self.parent.location = "index_op.html"; } } } </script>

Обратите внимание на фигурные скобки. Первый альтернативный код включает в себя все вложенные условия и выполнения и закрывается скобкой в самом конце. Все вложенные операторы вкладываются друг в друга, как матрёшки. Ниже я изобразил «голую» схему, в которую вложил больше операторов, и соединил стрелочками их начала и концы.

Оба кода расположены традиционной программистской «лесенкой», но это делается не по требованиям языка, а для нашего «человеческого» удобства чтения.

Кстати, в этой схеме есть одна дополнительная деталь: последний виток завершён кодом else, работающим во всех остальных (не упомянутых) случаях. Если мы, допустим, зададим страницу для IE по умолчанию (чтобы её открывали и все остальные, не учтённые нами браузеры), то правильный код будет выглядеть так:

<script type="text/javascript"> var OP = (navigator.appName == "Opera"); var NS = (navigator.appName == "Netscape"); /* Уже излишне объявлять переменную для IE, так как он задан по умолчанию */ if (OP) { self.parent.location = "index_op.html"; } else { if (NS) { self.parent.location = "index_ns.html"; } else { self.parent.location = "index_ie.html"; } //страница по умолчанию } </script>

Но тогда бы получилось меньше вложений, а моей задачей было объяснить технику записи вложенных операторов.

И вот ещё один маленький скрипт с этим оператором, который может оказаться весьма полезным. Привожу его, во-первых, для того, чтобы из сегодняшнего теоретического занудства Вы извлекли максимум пользы, а во-вторых, чтобы Вам примелькалось словосочетание, которое я сегодня сознательно не объяснял: self.parent.location. Ну и self.parent.frames.length тоже ничего. Это я Вас потихоньку веду к иерархии объектов. Через подсознание.

Так вот. Есть на свете такие фреймы, которые кто-то любит, а кто-то ненавидит. Если Вы совсем зелёный новичок, то, наверно, любите. Если пару раз столкнулись с проблемой фрейма в поисковике, то, возможно, успели возненавидеть. А суть в том, что если дана ссылка на страницу, которая находится во фрейме, а сама по себе является как бы неполноценной (то есть без навигации и т.п.) то по этой ссылке Вы попадёте прямо на неё в первозданно-недоделанном виде, а не туда, где она симпатично упакована во фрейм. Но от этого есть элементарное противоядие. Когда я его узнал, то вновь возлюбил фреймы.

Итак, в «голову» (head) этой злосчастной страницы нужно вживить ма-аленький такой имплант, который переадресовывает её на страницу-«хозяйку».

Вместо адрес/имя_основного_документа.html вписываете эту самую «хозяйку», ну, скажем, там, http://mysite.ru/index.html.

<script type="text/javascript"> if (self.parent.frames.length == 0) { self.parent.location = "адрес/имя_основного_документа.html"; } </script>

Теперь, щёлкнув по ссылке на эту подчинённую страницу, мы откроем её в нужном фрейме. Но всё же чрезмерно не увлекайтесь фреймами: у них и другие сюрпризы бывают.

Оператор switch

С английского switch переводится как «переключать». Это оператор-переключатель. Вот его структура (в квадратных скобках обозначены необязательные части):

switch (выражение) { case вариант1: код [break] case вариант2: код [break] [default: код] }

Выражение — это контрольное, тестовое значение, с которым будут сравниваться варианты.

Выражение может быть числовым, строковым или булевым значением. При булевом значении возможны только 2 варианта: true и false (или 1 и 0). При остальных вариантов может быть сколько угодно.

Для каждого варианта пишется определённый код. Весь перебор вариантов заключён в фигурные скобки.

Сначала рассмотрим вариант работы оператора без использования break и default.

Когда последовательное тестирование вариантов натыкается на вариант, совпадающий с тестовым, то выполняется код этого варианта и все последующие коды.

Например:

var x = 0; switch (x) { case 11: alert("Эй!"); case 0: alert("Осторожно!"); case "stroka": alert("Злая"); case 235: alert("собака!"); }

Мы объявили переменную и назначили на неё числовое значение 0. Далее я специально ввёл в оператор этакий шизофренический набор вариантов (11, 0, "stroka", 235), чтобы Вы поняли, что от какой-либо последовательности или логичности в этом наборе ровным счётом ничего не зависит.

Вариант 11 проносится мимо, а начиная с варианта 0 при выполнении начинают по очереди выпадать алерты: «Осторожно!» «Злая» «собака!»

Ключевое слово break прерывает дальнейшее выполнение кода. Давайте «брекнем» наш нолик:

var x = 0; switch (x) { case 11: alert("Эй!"); case 0: alert("Осторожно!"); break case "stroka": alert("Злая"); case 235: alert("собака!"); }

Теперь выскакивает только один алерт: «Осторожно!»

Если нет ни одного варианта, соответствующего выражению, то ничего выполняться не будет. Но если мы напишем код для ключевого слова default, то именно он будет выполняться при отсутствии соответствующих вариантов. В следующем примере изменено значение переменной, используемой в выражении, и добавлен вариант default, который в данном случае и будет выполняться.

var x = 8; switch (x) { case 11: alert("Эй!"); case 0: alert("Осторожно!"); case "stroka": alert("Злая"); case 235: alert("собака!"); default: alert("Да заходи, не бойся!"); }

А теперь выполним с помощью этого оператора предыдущее задание по загрузке определённой страницы в определённый браузер:

var mybrowser = (navigator.appName) switch (mybrowser) { case "Netscape": self.parent.location = "index_ns.html"; break case "Opera": self.parent.location = "index_op.html"; }

Мы полагаем, что скрипт находится на главной по умолчанию странице index_ie.html, поэтому незачем давать её ни как case, ни как default. Понятно также, что с помощью директивы break мы предотвращаем попытку выполнения невыполнимого кода, которая лично у меня, когда я тестировал этот пример, привела к глюкам (и стал я жертвой собственного фанатизма: «Лисичка» почему-то вообще перестала открываться, обиделась, что ли :).

Итак, мы узнали:

всё основное об операторах if...else и switch, кое-что о свойствах браузеров и о приручении фреймов.

А также научились:

переадресовывать страницы с помощью этих операторов.

К следующему уроку

К списку уроков JavaScript

(© А. Фролов)