Горизонтальная прокрутка меню и изображений на jQuery

Перевод статьи Create a Scrolling Menu with and .

Существует множество прокручивающихся меню и галерей изображений, созданных на Flash, вот яркие тому примеры 1, 2. Но автор захотел создать аналог на CSS и jQuery, конечно без эффектов смазывания картинки при перемещении, но все же. Это решение хорошо работает в большинстве популярных браузеров и при этом сохраняет доступность элементов при отключенном JavaScript.

Посмотреть результат

 

Разметка

Начнем с создания HTML структуры. Используем ненумерованный список, где каждый элемент содержит изображение и заголовок, так же добавим дополнительный элемент «a».

<span class="pun">&lt;</span><span class="tag">div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"sc_menu"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="tag">ul</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"sc_menu"</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="tag">li</span><span class="pun">&gt;&lt;</span><span class="tag">a</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"#"</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="tag">img</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">"img/1.jpg"</span><span class="pln"> </span><span class="atn">alt</span><span class="pun">=</span><span class="atv">"Menu"</span><span class="pun">/&gt;&lt;</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">Menu</span><span class="pun">&lt;/</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="tag">a</span><span class="pun">&gt;&lt;/</span><span class="tag">li</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="tag">li</span><span class="pun">&gt;&lt;</span><span class="tag">a</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"#"</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="tag">img</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">"img/2.jpg"</span><span class="pln"> </span><span class="atn">alt</span><span class="pun">=</span><span class="atv">"Navigation"</span><span class="pun">/&gt;&lt;</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">Navigation</span><span class="pun">&lt;/</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="tag">a</span><span class="pun">&gt;&lt;/</span><span class="tag">li</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="tag">li</span><span class="pun">&gt;&lt;</span><span class="tag">a</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"#"</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="tag">img</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">"img/3.jpg"</span><span class="pln"> </span><span class="atn">alt</span><span class="pun">=</span><span class="atv">"Scrolling"</span><span class="pun">/&gt;&lt;</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">Scrolling</span><span class="pun">&lt;/</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="tag">a</span><span class="pun">&gt;&lt;/</span><span class="tag">li</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="tag">li</span><span class="pun">&gt;&lt;</span><span class="tag">a</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"#"</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="tag">img</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">"img/4.jpg"</span><span class="pln"> </span><span class="atn">alt</span><span class="pun">=</span><span class="atv">"jQuery"</span><span class="pun">/&gt;&lt;</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">jQuery</span><span class="pun">&lt;/</span><span class="tag">span</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="tag">a</span><span class="pun">&gt;&lt;/</span><span class="tag">li</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="tag">ul</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="tag">div</span><span class="pun">&gt;</span>

Базовая стилизация

Добавляем необходимые стили

<span class="pln">div</span><span class="pun">.</span><span class="pln">sc_menu </span><span class="pun">{</span><span class="pln">
  </span><span class="com">/* Set it so we could calculate the offsetLeft */</span><span class="pln">
  position</span><span class="pun">:</span><span class="pln"> relative</span><span class="pun">;</span><span class="pln">
  height</span><span class="pun">:</span><span class="pln"> </span><span class="lit">145px</span><span class="pun">;</span><span class="pln">
  width</span><span class="pun">:</span><span class="pln"> </span><span class="lit">500px</span><span class="pun">;</span><span class="pln">
  </span><span class="com">/* Add scroll-bars */</span><span class="pln">
  overflow</span><span class="pun">:</span><span class="pln"> auto</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
ul</span><span class="pun">.</span><span class="pln">sc_menu </span><span class="pun">{</span><span class="pln">
  display</span><span class="pun">:</span><span class="pln"> block</span><span class="pun">;</span><span class="pln">
  height</span><span class="pun">:</span><span class="pln"> </span><span class="lit">110px</span><span class="pun">;</span><span class="pln">
  </span><span class="com">/* Max width here, for users without Javascript */</span><span class="pln">
  width</span><span class="pun">:</span><span class="pln"> </span><span class="lit">1500px</span><span class="pun">;</span><span class="pln">
  padding</span><span class="pun">:</span><span class="pln"> </span><span class="lit">15px</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="lit">15px</span><span class="pun">;</span><span class="pln">
  </span><span class="com">/* Remove default margin */</span><span class="pln">
  margin</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  background</span><span class="pun">:</span><span class="pln"> url</span><span class="pun">(</span><span class="str">'navigation.png'</span><span class="pun">);</span><span class="pln">
  list</span><span class="pun">-</span><span class="pln">style</span><span class="pun">:</span><span class="pln"> none</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">sc_menu li </span><span class="pun">{</span><span class="pln">
  display</span><span class="pun">:</span><span class="pln"> block</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">float</span><span class="pun">:</span><span class="pln"> left</span><span class="pun">;</span><span class="pln">
  padding</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="lit">4px</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">sc_menu a </span><span class="pun">{</span><span class="pln">
  display</span><span class="pun">:</span><span class="pln"> block</span><span class="pun">;</span><span class="pln">
  text</span><span class="pun">-</span><span class="pln">decoration</span><span class="pun">:</span><span class="pln"> none</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">sc_menu span </span><span class="pun">{</span><span class="pln">
  </span><span class="com">/* We want a caption to display on the next line */</span><span class="pln">
  display</span><span class="pun">:</span><span class="pln"> block</span><span class="pun">;</span><span class="pln">
  margin</span><span class="pun">-</span><span class="pln">top</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3px</span><span class="pun">;</span><span class="pln">
  text</span><span class="pun">-</span><span class="pln">align</span><span class="pun">:</span><span class="pln"> center</span><span class="pun">;</span><span class="pln">
  font</span><span class="pun">-</span><span class="pln">size</span><span class="pun">:</span><span class="pln"> </span><span class="lit">12px</span><span class="pun">;</span><span class="pln">
  color</span><span class="pun">:</span><span class="pln"> </span><span class="com">#fff;</span><span class="pln">
</span><span class="pun">}</span>

Свойства «width» и «overflow» используются для добавления полосы прокрутки в главном div’е. Использование свойства «position» облегчает расчет позиционирования на JavaScript. Не забывайте что отступ считается от родительского элемента. Что должно получиться.

Добавление бордера и эффектов при наведении

Свойство «display: none» скрывает заголовки, и при наведении курсора мыши (:hover) меняется на «display:block».

Свойства «-webkit-border-radius» и «-moz-border-radius » добавляют скругленные углы для правильных браузеров Firefox, Safari и Chrome. Конечно IE не поддерживает ничего подобного вплоть до 8й версии, тем хуже для него :)

Так меню выглядит, когда JavaScript отключен.

<span class="pun">.</span><span class="pln">sc_menu span </span><span class="pun">{</span><span class="pln">
  display</span><span class="pun">:</span><span class="pln"> none</span><span class="pun">;</span><span class="pln">
  margin</span><span class="pun">-</span><span class="pln">top</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3px</span><span class="pun">;</span><span class="pln">
  text</span><span class="pun">-</span><span class="pln">align</span><span class="pun">:</span><span class="pln"> center</span><span class="pun">;</span><span class="pln">
  font</span><span class="pun">-</span><span class="pln">size</span><span class="pun">:</span><span class="pln"> </span><span class="lit">12px</span><span class="pun">;</span><span class="pln">
  color</span><span class="pun">:</span><span class="pln"> </span><span class="com">#fff;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">sc_menu a</span><span class="pun">:</span><span class="pln">hover span </span><span class="pun">{</span><span class="pln">
  display</span><span class="pun">:</span><span class="pln"> block</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">sc_menu img </span><span class="pun">{</span><span class="pln">
  border</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3px</span><span class="pln"> </span><span class="com">#fff solid;</span><span class="pln">
  </span><span class="pun">-</span><span class="pln">webkit</span><span class="pun">-</span><span class="pln">border</span><span class="pun">-</span><span class="pln">radius</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3px</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">-</span><span class="pln">moz</span><span class="pun">-</span><span class="pln">border</span><span class="pun">-</span><span class="pln">radius</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3px</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">sc_menu a</span><span class="pun">:</span><span class="pln">hover img </span><span class="pun">{</span><span class="pln">
  filter</span><span class="pun">:</span><span class="pln">alpha</span><span class="pun">(</span><span class="pln">opacity</span><span class="pun">=</span><span class="lit">50</span><span class="pun">);</span><span class="pln">
  opacity</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span>

jQuery

Сначала нам нужно подключить сам jQuery. Автор использует версию доступную на Google API.

<span class="pun">&lt;</span><span class="tag">script</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">"http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"text/javascript"</span><span class="pun">&gt;&lt;/</span><span class="tag">script</span><span class="pun">&gt;</span>

Что нужно знать для понимания кода:
$() это сокращение для $(document).ready (). Функция в скобках вызывается после того как дерево докумена DOM будет полностью загружено.

<span class="pln">$</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">(){</span><span class="pln">
  </span><span class="com">// Your code here</span><span class="pln">
</span><span class="pun">});</span>

Мы используем событие «mousemove» чтоб назначить функцию, которая сработает при перемещении курсора мыши по нашему блоку.

«ul.width ()» не возвращает реальную ширину всех изображений, можно получить ширину путем добавления еще одного элемента в список и измерив его левый отступ.

Используем «lastLi[0]» чтоб получить элемент из массива jQuery и «offsetLeft» чтоб получить позицию от левого верхнего угла оберточного div’а.

Атрибут «pageX» нашего события (mousemove) возвращает координату курсора по горизонтали относительно всего документа, но нам нужна координата относительно оберточного div’а, для этого просто вычтем из нее «div.offset ().left».

Список должен прокручиваться значительно быстрее чем мы передвигаем курсор, чтоб добиться этого используем пропорцию «(ulWidth-divWidth) / divWidth».

Собственно код:

<span class="pln">$</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">(){</span><span class="pln">
  </span><span class="com">//Get our elements for faster access and set overlay width</span><span class="pln">
  </span><span class="kwd">var</span><span class="pln"> div </span><span class="pun">=</span><span class="pln"> $</span><span class="pun">(</span><span class="str">'div.sc_menu'</span><span class="pun">),</span><span class="pln">
               ul </span><span class="pun">=</span><span class="pln"> $</span><span class="pun">(</span><span class="str">'ul.sc_menu'</span><span class="pun">),</span><span class="pln">
               </span><span class="com">// unordered list's left margin</span><span class="pln">
               ulPadding </span><span class="pun">=</span><span class="pln"> </span><span class="lit">15</span><span class="pun">;</span><span class="pln">

  </span><span class="com">//Get menu width</span><span class="pln">
  </span><span class="kwd">var</span><span class="pln"> divWidth </span><span class="pun">=</span><span class="pln"> div</span><span class="pun">.</span><span class="pln">width</span><span class="pun">();</span><span class="pln">

  </span><span class="com">//Remove scrollbars</span><span class="pln">
  div</span><span class="pun">.</span><span class="pln">css</span><span class="pun">({</span><span class="pln">overflow</span><span class="pun">:</span><span class="pln"> </span><span class="str">'hidden'</span><span class="pun">});</span><span class="pln">

  </span><span class="com">//Find last image container</span><span class="pln">
  </span><span class="kwd">var</span><span class="pln"> lastLi </span><span class="pun">=</span><span class="pln"> ul</span><span class="pun">.</span><span class="pln">find</span><span class="pun">(</span><span class="str">'li:last-child'</span><span class="pun">);</span><span class="pln">

  </span><span class="com">//When user move mouse over menu</span><span class="pln">
  div</span><span class="pun">.</span><span class="pln">mousemove</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">(</span><span class="pln">e</span><span class="pun">){</span><span class="pln">

    </span><span class="com">//As images are loaded ul width increases,</span><span class="pln">
    </span><span class="com">//so we recalculate it each time</span><span class="pln">
    </span><span class="kwd">var</span><span class="pln"> ulWidth </span><span class="pun">=</span><span class="pln"> lastLi</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class="pln">offsetLeft </span><span class="pun">+</span><span class="pln"> lastLi</span><span class="pun">.</span><span class="pln">outerWidth</span><span class="pun">()</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> ulPadding</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">var</span><span class="pln"> left </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">e</span><span class="pun">.</span><span class="pln">pageX </span><span class="pun">-</span><span class="pln"> div</span><span class="pun">.</span><span class="pln">offset</span><span class="pun">().</span><span class="pln">left</span><span class="pun">)</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="pun">(</span><span class="pln">ulWidth</span><span class="pun">-</span><span class="pln">divWidth</span><span class="pun">)</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> divWidth</span><span class="pun">;</span><span class="pln">
    div</span><span class="pun">.</span><span class="pln">scrollLeft</span><span class="pun">(</span><span class="pln">left</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">});</span><span class="pln">
</span><span class="pun">});</span>
Все готово, результат можно посмотреть здесь.

  • Antonio

    Прикольная штука, интересно реально ли реализовать такое но что бы по вертикали крутило...

  • а я на море

    Прикольный дизайн и это радует. Статья нравится. Спасибо.

  • Petrik

    Все одно и тоже...

Запись навигация

Top