Awebdesign's Blog

Горизонтальная прокрутка с ява-скрипт 3

Posted in CSS, Уроки javascript, Уроки jQuery, jQuery, ява-скрипт by awebdesign on 15.04.2010

(перевод Виктории Шидловской Fun with Overflows)
Добавлен урок по горизонтальной прокрутке изображений, растягивающихся на весь экран.

горизонтальный скроллинг ява-скрипт

посмотреть ДЕМО

Пара человек попросили объяснить, как работает прокрутка на Plurk’s browse timeline. Затем на свое десятилетие Google выпустил 10 year timeline. Так что я решил показать, как сделать прокрутку, используя оба метода – прокрутку с помощью колесика мыши и с помощью перетаскивания мышкой.

Далее представлены два урока по горизонтальной прокрутке с ява-скриптом.

Первый урок – прокручиваемый дневник. Второй урок написан по запросу Trevor Morris, который хотел сделать «перетекание» радуги в шапке своего сайта более плавным.

1. Горизонтальная прокрутка мышью и колесиком мышки с помощью ява-скрипта

При создании горизонтально прокручиваемого дневника мы обеспечим поддержку прокрутки как на Plurk и как на Google.

Для начала сделаем тянущийся (wrapping) div со значением overflow: auto; (которое мы потом изменим на overflow: hidden; с помощью jQuery). Внутренний элемент (в нашем случае ul) будет иметь достаточную ширину, чтобы вместить в себя все необходимые элементы li, а чтобы li не растягивали div вертикально (не создавали новую линию), все li имеют определенную ширину и свойство float: left;.

Постановка задачи

  1. Уловить событие mouse down, определить положение прокручиваемого элемента и X-координату мышки.
  2. Когда мышка двигается (в нажатом состоянии), то прокручивать элемент на расстояние от старого до нового положения мышки.
  3. Когда мышка находится вне окна прокрутки, то отменить событие mouse down или запустить событие mouse up.

CSS

Не буду приводить весь код, только то, что имеет отношение к делу.

#timeline {
  height: 375px; /* fixed */
  overflow: auto; /* changed to hidden via JavaScript */
}

.tl-events { /* the UL */
  width: 11800px; /* the width required to hold all the info */
}

.tl-events li {
  float: left; /* allows the lis to stack against eachother */
  width: 300px;
}

jQuery

Код, используемый в demo

Мы используем три встроенные функции: mousedown, mouseup and mousemove. Затем добавляем jQuery mousewheel plugin перед изменением overflow в CSS:

// Когда DOM готов...
$(document).ready(function () {
  $('#timeline').mousedown(function (event) {
    // прикрепить 3 data элементу #timeline
    $(this)
      .data('down', true) // индикатор того, что мышь нажата
      .data('x', event.clientX) // текущая X-координата мышки
      .data('scrollLeft', this.scrollLeft); // текущая позиция скролла

    // вернуть false, чтобы избежать выделение текста и перетаскивания ссылок
   //внутри окна прокрутки
    return false;
  }).mouseup(function (event) {
    // Когда мышь отжата (mouse up), «выключить» индикатор down
    $(this).data('down', false);
  }).mousemove(function (event) {
    // если мышь нажата – начать эффект перетаскивания (drag)
    if ($(this).data('down') == true) {
      // this.scrollLeft - это scrollbar, появившийся из-за слишком большого
      //контента (overflowing content)
      // Новая позиция высчитывается по формуле: начальная позиция скролла +
      //начальная X-координата нажатой мышки – новая X-координата
      // Ищу того, кто мог бы как-то увеличить скорость прокрутки
      this.scrollLeft = $(this).data('scrollLeft') + $(this).data('x') - event.clientX;
    }
  }).mousewheel(function (event, delta) {
    // Сейчас подключаем плагин mouse wheel и прокручиваем на значение 'delta',
    // что является движением колесика, умноженное на произвольное число.
    this.scrollLeft -= (delta * 30);
  }).css({
    'overflow' : 'hidden', // изменить на hidden для пользователей с поддержкой JS
    'cursor' : '-moz-grab' // добавить курсор с изображением лапки
  });
});

// И наконец, вызываем событие, если мышка вышла за пределы прокручиваемой области
// Мы не вызываем событие mouse up (так как мышь все еще нажата)
$(window).mouseout(function (event) {
  if ($('#timeline').data('down')) {
    try {
      // *try* (попробовать) вычислить элемент, на который перешла мышка после того,
      //как покинула область
      // и если мы мы действительно вышли за пределы этой области,
      //то отключаем индикатор события mouse down
      if (event.originalTarget.nodeName == 'BODY' || event.originalTarget.nodeName == 'HTML') {
        $('#timeline').data('down', false);
      }
    } catch (e) {}
  }
});

2. Эффект радуги на сайте Trevor Morris

Используя тот же this.scrollLeft DOM мы можем создать совершенно другой эффект.
Он будет работать также при отсутствии поддержки ява-скрипта.

Разметка

Пустой экстра-div — это широкий элемент, а div#rainbow — это элемент с overflow, который будет перемещаться внутри.

<div id="headerEffect">
  <div id="rainbow"><div></div></div>
  <div id="swirl"></div>
</div>

CSS

Кроме CSS я также прописал код поддержки прозрачности PNG-изображений для IE6, для корректной работы при отключенных ява-скриптах.

#headerEffect {
  position: absolute;
  width: 100%;
  height: 400px;
  overflow: hidden;
  top: 0; /* Убедитесь, что IE растягивает его правильно */
  left: 0;
}

#rainbow {
  height: 400px;
  width: 100%;
  overflow: hidden;
}

#rainbow div {
  height: 400px;
  width: 3312px; /* хорошая ширина, чтобы быть уверенным, что картинка будет повторяться */
  background: url(/css/img/header.colour.3.png) repeat-x scroll -20% 0;
}

#swirl {
  background: url(/css/img/header.swirl.png) no-repeat scroll 50% 0;
  height: 400px;
  width: 100%;
  position: absolute; /* располагает swirl *над* rainbow */
  top: 0;
  left: 0;
}

Несколько специальных стилей для IE6:

<!--[if lte IE 6]>
<style type="text/css" media="screen">
/* Добавил alpha прозрачность в CSS для отображения в браузерах без поддежки JS */
#swirl {
  background-image: none;
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.trovster.com/css/img/header.swirl.png', sizingMethod='scale');
}
</style>
<![endif]-->

JavaScript
Заметьте, что этот раздел я назвал JavaScript, а не jQuery; мы используем свойство scrollLeft для div#rainbow, и jQuery нужен нам только для готового события.

$(document).ready(function () {
  // определяем элемент rainbow
  var rainbow = document.getElementById('rainbow'),
    lastPos, // хранит последнюю позицию scrollLeft
    width = 1656; // точка повтора бэкграунда

  // мы каждый раз сбрасывем все значения при перезагрузке страницы, так что бэкграунд всегда один и тот же
  rainbow.scrollLeft = width;

  // используем интервал для прокрутки радуги
  setInterval(function () {
    // заставляем бэкграунд прокручиваться слева направо
    rainbow.scrollLeft -= 5;

    // если мы достигнем начала, то lastPos будет равен scrollLeft
    if (lastPos == rainbow.scrollLeft) {
      // reset
      rainbow.scrollLeft = width;
    }

    lastPos = rainbow.scrollLeft;
  }, 100); // комбинация миллисекунд
});

комментариев 12

Subscribe to comments with RSS.

  1. Дмитрий said, on 05.11.2012 at 12:53 пп

    Прикрепил скрипт с шаблону Joomla. http://brandingunion.com/index.php?option=com_content&view=category&layout=blog&id=9&Itemid=137
    Но почему-то не получается прокручивать страницу. Получается только передвигать курсором. При этом курсор прилипает к блоку с прокруткой.
    Не подскажете, в чём может быть дело?

    Нравится

  2. Лиля said, on 12.10.2010 at 11:37 пп

    А вот такое как реализовать? ( http://www.urealty.ru ) — панель у шапки.

    Нравится

  3. fennom said, on 13.09.2010 at 12:26 пп

    Разобрался и сделал вот пример работы
    Находим строчку .mouseup(function (event) { и добавляем $(this).css({‘cursor’ : ‘-moz-grab’});

    А теперь дописываем следующий код
    .mousedown(function (event) {//если мышка нажата то меняем курсор
    $(this).css({‘cursor’ : ‘-moz-grabbing’});
    })

    Нравится

  4. fennom said, on 09.09.2010 at 2:47 пп

    Вопрос по поводу курсоров можно ли как нибудь реализовать отображения курсора при на видении -moz-grab а при перетаскивании -moz-grabbing

    Нравится

  5. johnyy said, on 11.07.2010 at 12:21 дп

    Вот тоже пример, интересно как реализовано? http://emfire.ru/

    Нравится

  6. NeverBorn said, on 20.06.2010 at 5:37 пп

    Тьфу ты, вертикальное перетаскивание.

    Нравится

    • awebdesign said, on 23.06.2010 at 11:03 дп

      Ой, нет, извините! Отдельный тьютор надо искать и переводить. Боюсь еще, что слишком странная просьба, если сайт можно прокручивать вертикально колесиком мыши, то зачем перетаскивать? Не юзер фрэндли.

      Нравится

  7. NeverBorn said, on 20.06.2010 at 5:36 пп

    Привет. Не подскажите плз как прикрутить горизонтальное перетаскивание мышкой? Я фотограф и хочу подобным образом организовать свое портфолио на сайте. Спасибо.

    Нравится

    • Вячеслав said, on 06.03.2012 at 9:04 пп

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

      Нравится

      • awebdesign said, on 06.03.2012 at 9:41 пп

        Этот пример — ссылка на который идет с картинки — он как раз перетаскивается мышью! То есть там и скролл и драг!

        Нравится


Оставьте комментарий