Статьи

Как создать простую новостную ленту

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


Контекстом примера является скроллер новостей, поэтому мы будем работать с простым текстом, но мы должны иметь возможность поместить все, что мы хотели, в базовую разметку; изображения или ссылки, или что-то еще. Мы будем использовать jQuery в качестве базовой библиотеки JS, а также немного HTML и CSS. Давайте начнем.

Конечный продукт

На новой странице в вашем текстовом редакторе добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01//EN» «http://www.w3.org/TR/html4/strict.dtd»>
<html>
  <head>
    <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
    <title>Simple News Ticker</title>
    <link rel=»stylesheet» type=»text/css» href=»simpleTicker.css»>
  </head>
  <body>
    <dl id=»ticker»>
      <dt>This is a news title!</dt><dd>This is a snippet of the news.
      <dt>News Heading 2</dt><dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</dd>
      <dt>News Heading 3</dt><dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</dd>
      <dt>News Heading 4</dt><dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</dd>
      <dt class=»heading»>This item is long!</dt><dd class=»text»>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </dl>
    <script type=»text/javascript» src=»jquery-1.3.2.js»></script>
    <script type=»text/javascript»>
     
    </script>
  </body>
</html>

Сохраните его как simpleTicker.html в каталоге, содержащем jQuery 1.3.2. Как и обычная мебель страницы — DOCTYPE, META-тип контента, заголовок и т. Д. — у нас есть настраиваемая таблица стилей, которую мы создадим в одно мгновение, и в конце тела мы даем ссылку на jQuery (из соображений производительности ).

пример

На странице есть контент, который мы будем постепенно улучшать в новостной ленте; он состоит из простого элемента списка определений, который подходит для наших целей. Хотя в каждый элемент <dt> может быть помещено только встроенное содержимое, содержимое уровня блока может быть помещено в элементы <dd>.

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

Давайте добавим некоторые базовые стили; даже если JavaScript отключен, никто не хочет видеть список таким, какой он есть в данный момент. В новом файле в вашем текстовом редакторе добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
#ticker {
  width:180px;
}
#ticker dt {
  font:normal 14px Georgia;
  background-color:#e5e5e5;
  border-bottom:none;
}
#ticker dd {
  margin-left:0;
  border-bottom:1px solid #aaaaaa;
  border-left:1px solid #ffffff;
}
#ticker dd.last { border-bottom:1px solid #ffffff;

Сохраните этот файл в том же каталоге, что и страница, и назовите его simpleTicker.css. Мы даем списку заданную ширину и высоту и устанавливаем для свойства overflow значение auto; высота тикера меньше пространства, необходимого для отображения всех новостных элементов, поэтому полоса прокрутки позволит посетителям с отключенным JavaScript просматривать весь контент.

пример

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

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

Теперь мы можем перейти к забавной части — добавив JavaScript, который превратит это из простого списка в автоматический тикер; в пустой элемент <script> внизу страницы добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$(function() {
       
  //cache the ticker
  var ticker = $(«#ticker»);
           
  //wrap dt:dd pairs in divs
  ticker.children().filter(«dt»).each(function() {
           
    var dt = $(this),
      container = $(«<div>»);
   
    dt.next().appendTo(container);
    dt.prependTo(container);
    container.appendTo(ticker);
  });
                 
  //hide the scrollbar
  ticker.css(«overflow», «hidden»);
         
  //animator function
  function animator(currentItem) {
             
    //work out new anim duration
    var distance = currentItem.height(),
    duration = (distance — Math.abs(parseInt(currentItem.css(«marginTop»)))) / 0.025;
 
    //animate the first child of the ticker
    currentItem.animate({ marginTop: -distance }, duration, «linear», function() {
             
      //move current item to the bottom currentItem.appendTo(currentItem.parent()).css(«marginTop», 0);
 
    //recurse
    animator(currentItem.parent().children(«:first»));
    });
  };
         
  //start the ticker
  animator(ticker.children(«:first»));
});

Весь наш код заключен в ярлык jQuery document.ready $ (function () {}), который будет выполнять анонимную функцию, как только страница загрузится. Первое, что мы делаем, это кешируем наш главный селектор, который является внешним элементом <dl>; это избавит нас от необходимости многократно выбирать элемент из DOM всякий раз, когда мы захотим с ним работать, и повысит производительность страницы.

Базовый список определений содержит как термины определения, так и элементы описания определения, каждый из которых может иметь различные размеры. Чтобы немного упростить наш сценарий, мы обернем каждую пару <dt> и <dd> в содержащий элемент <div>; это позволяет нам логически сгруппировать различные элементы и сгладить анимацию. Это также означает, что мы можем использовать любые поля и отступы для * lt; dt> и

элементы без необходимости учитывать их в наших расчетах анимации.

Для этого мы выбираем все дочерние элементы из нашего кэшированного селектора и используем метод фильтра jQuery, чтобы отбросить все элементы <dd>. Затем для каждого оставшегося <dt> мы создаем новый контейнер <div> и добавляем оба <dt> и <dd> в новый контейнер. Мы должны сначала добавить <dd>, который следует за текущим <dt>, потому что после добавления <dt> к контейнеру после него не будет <dd>. Поэтому нам нужно использовать метод prepend для <dt> после добавления <dd>.

Когда все пары <dt> и <dd> обернуты в элементы <div>, мы изменяем свойство CSS переполнения тикера на скрытое, чтобы полоса прокрутки была удалена. Это является частью стратегии доступности и гарантирует, что только посетители с включенным JavaScript смогут увидеть расширенный тикер.

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

Первое, что мы делаем в этой функции, это вычисляем расстояние, которое должен пройти выбранный элемент, и продолжительность анимации. Часть расстояния легка; это просто высота текущего элемента контейнера.
Продолжительность немного сложнее; это общее расстояние, которое вы должны пройти за вычетом пройденного расстояния, деленное на базовую скорость, которую я произвольно установил на уровне 0,025. Высота уже будет целым числом, но метод css вернет строку, представляющую верхнюю границу анимируемого элемента, поэтому нам нужно использовать функцию JavaScript parseInt (), чтобы преобразовать ее в число. Это также будет отрицательное число, поэтому мы используем функцию JavaScript Math.abs (), чтобы преобразовать ее из отрицательного в абсолютное (положительное) число.

По моему мнению, базовая скорость, на которую мы делим оставшееся расстояние, чтобы проехать, довольно медленная; Я уже видел тикеры (созданные на Java), и они работали примерно с одинаковой скоростью, и у меня не было укачивания или каких-либо побочных эффектов. Если вы чувствуете, что анимация слишком быстрая (или даже слишком медленная), смело изменяйте эту цифру. Это должно быть действительно небольшое число, хотя; все в диапазоне от 0,01 до 0,09, вероятно, будет в порядке.

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

Второй аргумент метода animate — это продолжительность, которую мы разработали минуту назад. Третий аргумент — это метод ослабления; Пользовательские анимации jQuery автоматически получают два типа замедления — свинг и линейный. Swing заставляет анимацию ускоряться и замедляться, в то время как linear делает ее плавной и непрерывной, так что это вариант для нас в этой ситуации.

Последний аргумент — это функция анонимного обратного вызова, которая будет выполнена после завершения анимации. Внутри этой функции мы перемещаем только что анимированный элемент в конец набора контейнеров, сбрасываем его marginTop обратно в 0, а затем рекурсивно вызываем функцию аниматора снова, передавая нового первого потомка тикера.

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

пример

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
//set mouseenter
ticker.mouseenter(function() {
           
  //stop current animation
  ticker.children().stop();
           
});
         
//set mouseleave
ticker.mouseleave(function() {
                   
  //resume animation
  animator(ticker.children(«:first»));
});

Обе эти функции действительно просты; мы используем mouseenter и mouseleave вместо mouseover и mouseout, потому что это делает эти функции красивыми и маленькими; нам не нужно беспокоиться о игнорировании указателей мыши, когда указатель перемещается от внешнего элемента тикера к одному из дочерних элементов. В функции mouseenter мы просто останавливаем анимацию. В функции mouseleave мы просто перезапускаем анимацию еще раз, передавая первого потомка тикера.

Нам осталось решить одну проблему, и, к счастью, это легко. Запуск страницы в IE (тестирование в версии 8) выдает ошибку, как только она загружается. Ошибка вызвана тем, что в самый первый раз, когда функция аниматора запускает первый контейнер <div>, браузер установит для маржинальной вершины значение auto. Другие браузеры будут интерпретировать маржинальную вершину как 0. Какой браузер правильный, спорный, хотя я позволю вам сделать свой собственный вывод о том, что IE — единственный браузер, который вызывает проблему. Все, что нам нужно сделать, чтобы это исправить — это явно установить поле margin для контейнера. Мы можем сделать это, добавив следующую строку кода в таблицу стилей:

1
#ticker div { margin-top:0;

Теперь страница должна работать и в IE:

пример

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

  • Подпишитесь на нас в Твиттере или подпишитесь на ленту Nettuts + RSS для ежедневных новостей и статей о веб-разработке.