Опубликован: 01.07.2011 | Доступ: свободный | Студентов: 6427 / 1052 | Оценка: 4.07 / 3.64 | Длительность: 10:34:00
Лекция 4:

Современные методы применения JavaScript

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

Разбивайте на модули - одна функция на задачу

Это обычная практика программирования - создание функций, которые выполняют только одну задачу, облегчает другим разработчикам отладку и изменение кода, не требуя просмотра всего кода, чтобы определить, какой блок выполняет какую функцию.

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

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

function addLink(text,url,parentElement){
  var newLink = document.createElement('a');
  newLink.setAttribute('href',url);
  newLink.appendChild(document.createTextNode(text));
  parentElement.appendChild(newLink);
}

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

function addLink(text,url,parentElement){
  var newLink = document.createElement('a');
  newLink.setAttribute('href',url);
  newLink.appendChild(document.createTextNode(text));
  if(parentElement.id === 'menu'){
    newLink.className = 'menu-item';
  }
  if(url.indexOf('mailto:')!==-1){
    newLink.className = 'mail';
  }
  parentElement.appendChild(newLink);
}

Это делает функцию более специфической, которую труднее применять в различных ситуациях. Более аккуратный способ состоит в возвращении ссылки и реализации дополнительных случаев в основных функциях, которые этого требуют. Это превращает addLink() в более общую функцию createLink():

function createLink(text,url){
  var newLink = document.createElement('a');
  newLink.setAttribute('href',url);
  newLink.appendChild(document.createTextNode(text));
  return newLink;
}

function createMenu(){
  var menu = document.getElementById('menu');
  var items = [
    {t:'Home',u:'index.html'},
    {t:'Sales',u:'sales.html'},
    {t:'Contact',u:'contact.html'}
  ];
  for(var i=0;i<items.length;i++){
    var item = createLink(items[i].t,items[i].u);
    item.className = 'menu-item';
    menu.appendChild(item);
  }
}

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

Улучшайте постепенно

Прогрессивное улучшение является практикой разработки, которая подробно рассматривается в "Постепенное ухудшение или прогрессивное улучшение" , Постепенное ухудшение или прогрессивное улучшение. По сути, вы должны написать код, который работает, независимо от доступной технологии. В случае JavaScript это означает, что когда создание сценария невозможно (скажем на BlackBerry, или в связи с крайне строгой политикой безопасности ), web-продукты все равно должны позволить пользователям достичь определенной цели, а не блокировать их в связи с отсутствием JavaScript, поддержку которого они не включили, или не хотят использовать.

Удивительно, как часто создаются крайне путаные приложения JavaScript для проблем, которые могут быть легко решены без этого. Один из примеров, который мне встречался, был полем поиска на странице, которое позволяло искать различные данные: web, изображения, новости, и т.д.

В исходной версии различные варианты данных были ссылками, которые должны были перезаписывать атрибут действия формы, чтобы указывать на различные сценарии на сервере для выполнения поиска.

Проблема в том, что если JavaScript будет отключен, ссылки все равно выводятся, но каждый вид поиска будет возвращать стандартные результаты из web, так как действие формы не изменяется. Решение было очень простым: вместо ссылок варианты были представлены как группа радио-кнопок, которые делали ветвление к различным сценариям специализированного поиска, используя серверный сценарий.

Это не только заставило поиск работать правильно для каждого варианта, но также облегчило отслеживание, сколько пользователей выбирает тот или иной вариант. Используя правильную конструкцию HTML, мы смогли избавиться, как от JavaScript для переключения действия формы, так и сценариев отслеживания переходов, и заставили ее работать для каждого пользователя - независимо от рабочей среды.

Предусматривайте конфигурацию и перевод

Одним из наиболее полезных действий для поддержания кода обслуживаемым и понятным является создание конфигурационного объекта, который содержит все вещи, которые возможно изменяются со временем. Сюда входит любой текст, используемый в создаваемых элементах (включая значения кнопок и альтернативный текст для изображений), имена ID и классов CSS, и общие параметры создаваемого интерфейса.

Например, плеер Easy YouTube (http://icant.co.uk/easy-youtube/) имеет следующий конфигурационный объект:

/*
  	Это  конфигурация плеера. Скорее всего вам никогда 
не придется ничего здесь изменять, но иметь такую 
возможность неплохо, не так ли? 
*/
config = {
  CSS:{
    /* 
     Используемые в документе IDs. Сценарий будет получать
доступ к различным элементам плеера с помощью этих IDs, 
поэтому, если вы изменяете их в коде HTML ниже, 
не забудьте также изменить имена здесь!  
    */
    IDs:{
      container:'eytp-maincontainer',
      canvas:'eytp-playercanvas',
      player:'eytp-player',
      controls:'eytp-controls',

      volumeField:'eytp-volume',
      volumeBar:'eytp-volumebar',

      playerForm:'eytp-playerform',
      urlField:'eytp-url',

      sizeControl:'eytp-sizecontrol',

      searchField:'eytp-searchfield',
      searchForm:'eytp-search',
      searchOutput:'eytp-searchoutput'
      /* 
Отметим, что после последней записи в списке 
никогда не должна стоять запятая, так как 
иначе MSIE будет очень сердит!
      */
    },
    /*
     Это имена классов CSS, которые плеер добавляет 
динамически на панель громкости в определенных ситуациях.
    */
    classes:{
      maxvolume:'maxed',
      disabled:'disabled'
      /* 
Отметим, что после последней записи в списке 
никогда не должна стоять запятая, так как 
иначе MSIE будет очень сердит!

      */
    }
  },
  /* 
    	Это конец  определений CSS, отсюда и дальше вы можете 
изменять настройки плеера самостоятельно. 
  */
  application:{
    /*
      Базовый URL API YouTube. Он изменился во время 
разработки этого приложения, поэтому будет полезно 
сделать его параметром.
    */
    youtubeAPI:'http://gdata.youtube.com/apiplayer/cl.swf',
    /* 
     Ключ YouTube Developer,
     Замените его своим собственным, когда разместите 
плеер на сервере!!!!!
    */
    devkey:'AI39si7d...Y9fu_cQ',
    /*
     Увеличение/уменьшение громкости в процентах и сообщение 
о громкости, выводимое в скрытом поле формы (для 
считывателя экрана). $x в сообщении будет заменяться 
реальным значением.
    */
    volumeChange:10,
    volumeMessage:'volume $x percent',
    /*
     Количество результатов поиска и сообщение об ошибке, 
если результатов не будет.
    */
    searchResults:6,
    loadingMessage:'Searching, please wait',
    noVideosFoundMessage:'No videos found : (',
    /*
     Количество секунд повторения, когда пользователь 
нажимает кнопку обратной перемотки.
    */
    secondsToRepeat:10,
    /*
      Размер кадра фильма.
    */
    movieWidth:400,
    movieHeight:300
    /* 
Отметим, что после последней записи в списке 
никогда не должна стоять запятая, так как 
иначе MSIE будет очень сердит!

    */
  }  
}
.

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

Крайне важно поддерживать обслуживание кода простым, исключая для будущего персонала сопровождения необходимость чтения всего кода и поиска, где необходимо что-то изменить. Если это не очевидно, то решение будет либо полностью выброшено, либо грубо модифицировано. Модифицированные решения невозможно обновить, если в этом возникнет необходимость, тем самым уничтожается возможность повторного использования кода.

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >
Александр Мельников
Александр Мельников

В лекции №7 результат работы ни одного скрипта кроме первого не выводит результат на странице браузера, ни одного. Почему. Автор, разъясните пожалуйста. Сокурсники, можете помочь понять?

Юлия Максимова
Юлия Максимова

Я пишу в блокноте, сохраняю с разрешением html и открываю через браузер. Пустой лист

Это задание после первой лекции,  в чем его выполнить, чтобы увидеть результат или как?

Сердар Салихов
Сердар Салихов
Туркмения, Ашхабад, Туркменский Государственный Универсиитет, 1997