falbar Lightbox от falbar или falbox

Lightbox от falbar или falbox

20 октября 2015 3018 0

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

Реклама

По моей задумке код должен был решать несколько задач:

  • Собственно сам эффект lightbox, когда при нажатии на картинку происходит затемнение фона, а изображение показывается по центру экрана;
  • Возможность пролистывать картинок, относящихся только к статье, не затрагивая при этом другие изображения на странице;
  • Kнопка закрытия лайтбокса и, само собой, возможность перелистывания картинок при помощи клавиш клавиатуры;
  • Kнопка для открытия картинки на новой вкладке (для удобства скачивания или получения ссылки на картинку).

Это список относиться к функционалу скрипта, но хочется добавить пару пунктов относящийся к самой реализации:

  • Во-первых, HTML lightbox будет добавляться после загрузки страницы через JavaScript;
  • Во-вторых, при добавлении HTML учитывается наличие картинок: если их нет на странице – lightbox добавлен не будет, а если у нас на странице всего одно изображение, то будут отключены кнопки пролистывания;
  • В-третьих, не забываем про адаптивность и кнопки на клавиатуре, на которые пользователь может нажать при просмотре.

Описание скрипта будет относительно примера, который я прикрепил к статье. Для работы нам потребуется подключить только jQuery библиотеку:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

Все картинки в примере лежат в элементе с id=content вперемежку с текстом. К ним мы не будем нечего прописывать и изменять их CSS. Все делаем через JavaScript – это гораздо удобнее, так как не требует дополнительных манипуляций со страницей.

Немного слов о структуре (непосредственно её рассмотрим при написании JavaScript): наш lightbox будет включать в себя несколько кнопок и обёртку для вывода изображения. Теперь для работы мы опишем CSS, который и будет отвечать за отображение:

#gallery{
  background-color: rgba(24, 59, 95, 0.3);
    overflow: auto;
 position: fixed;
    left: 0;
    top: 0;
 height: 100%;
   width: 100%;
    -webkit-user-select: none;
  -moz-user-select: none;
 -o-user-select: none;
   -ms-user-select: none;
  user-select: none;
  display: none;
  z-index: 1000;
}
 #gallery .prev{
     background-color: rgba(24, 59, 95, 0.7);
        position: fixed;
        left: 0;
        top: 0;
     height: 100%;
       width: 83px;
        opacity: 0.7;
       cursor: pointer;
        z-index: 1;
 }
       #gallery .prev .icon{
           display: block;
         background: url(icons-gallery.png) no-repeat 1px center;
            margin: 18px auto 0;
            width: 14px;
            height: 24px;
       }
   #gallery .prev:hover{
       opacity: 1;
 }
   #gallery .viewer{
       display: -webkit-flex;
      display: -moz-flex;
     display: -o-flex;
       display: -ms-flex;
      display: flex;
      align-items: center;
        height: 100%;
   }
       #gallery .viewer .image{
            overflow: hidden;
           margin: auto;
       }
       #gallery .viewer.next .image{
           position: relative;
         cursor: pointer;
        }
           #gallery .viewer .image img{
                max-width: 100%;
            }
   #gallery .close{
        position: fixed;
        right: 27px;
        top: 20px;
      opacity: 0.7;
       cursor: pointer;
        z-index: 1;
 }
       #gallery .close .icon{
          display: block;
         background: url(icons-gallery.png) no-repeat -31px center;
          width: 20px;
            height: 20px;
       }
   #gallery .close:hover{
      opacity: 1;
 }
   #gallery .zoom{
     background-color: rgba(24, 59, 95, 0.7);
        position: fixed;
        bottom: 10px;
       right: 27px;
        height: 20px;
       width: 20px;
        border-radius: 2px;
     padding: 10px;
      opacity: 0.7;
       cursor: pointer;
        z-index: 1;
 }
       #gallery .zoom .icon{
           display: block;
         background: url(icons-gallery.png) no-repeat -11px 2px;
         width: 22px;
            height: 20px;
       }
   #gallery .zoom:hover{
       opacity: 1;
 }

Вышеописанный код говорит о том, что изначально lightbox будет спрятан, а в элементе с id=gallery находятся все кнопки управления (пролистывание, закрытия и открытия изображения на новой вкладке) и элемент, в котором будет отображаться выбранная картинка пользователем. Так же важно отметить, что как фон, так и кнопки зафиксированы на странице – это нужно для того чтобы при появлении скролла кнопки оставались на том же месте, а скролл происходил не по странице, а по картинке (это реализуется при помощи обрезки элемента body и компенсации правого отступа).

Переходим собственно к JavaScript. Его мы поместим в объект gallery, а весь функционал будет реализован через методы. Главный метод, а также точкой запуска/входа является initialize(containerTmp, containerImg):

  • containerTmp – контейнер, куда будет помещаться HTML разметка lightbox;
  • containerImg – контейнер, в котором находятся картинки, к которым будет применен скрипт.

Далее следует весь код gallery:

var gallery = {

    IMGS: {},

   GALLERY: {},
    BODY:    {},

    CURRENT: 0,

 initialize: function(containerTmp, containerImg){

       this.IMGS = containerImg.find("img");

     if(this.IMGS.length){

           this.IMGS.css("cursor", "pointer");

         containerTmp.append(
                this.getTemp(this.IMGS.length)
          );

          this.GALLERY = $("#gallery");
         this.BODY    = $("body");

         this.setUpListeners();
      };

      return false;
   },
  setUpListeners: function(){

     this.IMGS.on("click", this.showHandler);

      this.GALLERY.on("click", ".close", this.hideHandler);
       this.GALLERY.on("click", ".zoom", this.zoomHandler);
        this.GALLERY.on("click", ".prev", this.prevHandler);
        this.GALLERY.on("click", ".next .image", this.nextHandler);

     $(window).on("keydown", this.keydownHandler);

     return false;
   },
  showHandler: function(){

        gallery.BODY.css({
          "overflow": "hidden",
           "margin-left": "-17px"
      });
     gallery.GALLERY.show();

     gallery.CURRENT = gallery.getImgPosition($(this));

      gallery.setImg($(this));

        return false;
   },
  hideHandler: function(){

        gallery.BODY.removeAttr("style");
     gallery.GALLERY.find(".image").html("");
        gallery.GALLERY.hide();

     return false;
   },
  zoomHandler: function(){

        var img = gallery.GALLERY.find(".image img"),
         src = img.attr("src");

        if(img.length){

         var tab = window.open(src, "_blank");
         tab.focus();
        };

      return false;
   },
  prevHandler: function(){

        var size = gallery.IMGS.size();

     if(gallery.CURRENT){

            gallery.CURRENT = --gallery.CURRENT;
        }else{

          gallery.CURRENT = --size;
       };

      gallery.setImg(
         gallery.IMGS.eq(gallery.CURRENT)
        );

      return false;
   },
  nextHandler: function(){

        var size = gallery.IMGS.size();

     if(gallery.CURRENT >= size - 1){

         gallery.CURRENT = 0;
        }else if(gallery.CURRENT){

          gallery.CURRENT = ++gallery.CURRENT;
        }else{

          gallery.CURRENT = 1;
        };

      gallery.setImg(
         gallery.IMGS.eq(gallery.CURRENT)
        );

      return false;
   },
  keydownHandler: function(event){

        if(gallery.GALLERY.css("display") == "block"){

          switch(event.keyCode){

              case 39:
                    gallery.nextHandler();
                  break;

              case 37:
                    gallery.prevHandler();
                  break;

              case 27:
                    gallery.hideHandler();
                  break;

              case 40:
                    return false;
                   break;

              case 38:
                    return false;
                   break;
          };
      };

      return false;
   },
  getTemp: function(length){

      var temp  = "<div id='gallery'>";

         if(length > 1){

              temp += "<div class='prev'>";
                 temp += "<span class='icon'></span>";
               temp += "</div>";
           };

          if(length > 1){

              temp += "<div class='viewer next'>";
                  temp += "<div class='image'>";
                    temp += "</div>";
               temp += "</div>";
           }else{

              temp += "<div class='viewer'>";
                   temp += "<div class='image'>";
                    temp += "</div>";
               temp += "</div>";
           };

              temp += "<div class='close'>";
                    temp += "<span class='icon'></span>";
               temp += "</div>";

               temp += "<div class='zoom'>";
                 temp += "<span class='icon'></span>";
               temp += "</div>";

           temp += "</div>";

       return temp;
    },
  getImgPosition: function(img){

      var src = img.attr("src"),
            num;

        gallery.IMGS.each(function(i){

          if($(this).attr("src") == src){

               num = i;

                return false;
           };
      });

     if(num != undefined){

           return num;
     };

      return false;
   },
  setImg: function(img){

      var image = gallery.GALLERY.find(".image"),
           src    = img.attr("src"),
         alt    = img.attr("alt");

     image.html("<img src='" + src + "' alt='" + alt + "' />");

      return false;
   }
};

Объект состоит из четырёх свойств и одиннадцати методов. Давайте рассмотрим их подробнее:

  • IMGS – свойство, в котором хранятся все картинки;
  • GALLERY – свойство, в котором храниться jQuery объект выборки динамически добавленного HTML лайтбокса;
  • BODY – свойство, в котором храниться jQuery объект выборки элемента body;
  • CURRENT – номер выбранной картинки пользователем;
  • Initialize() – как выше было описано - точка входа;
  • setUpListeners() – функция, в которой мы отображаем все события скрипта;
  • showHandler() – обработка клика по картинке показ лайтбокса;
  • hideHandler() – обработка клика для закрытия лайтбокса;
  • zoomHandler() – отслеживание события клика по кнопке открытия картинки в новом окне;
  • prevHandler() – левая навигация;
  • nextHandler() - правая навигация (реализуется по нажатию на изображение);
  • keydownHandler() – обработка клавиш на клавиатуре (стрелки вправо и влево, esc, отключение стрелок вверх и вниз);
  • getTemp() – метод генерации шаблона галереи;
  • getImgPosition() – получение текущей выбранной картинки;
  • setImg() – установка изображения.

В конце страницы останется только запустить сам скрипт:

gallery.initialize(
  $("body"),
    $("#content")
);

Весь код написан таким образом, что, в дальнейшем, может быть легко модернизирован. К примеру, если потребуется добавить какой-нибудь красивый эффект смены картинок, то путем внесения изменений в метод setImg() этого легко можно будет добиться. Так же данный скрипт можно установить на различные CMS: Joomla, WordPress или другие.

Реклама
Комментариев еще не оставлено
no_avatar