Создаем вылетающую панель с подробностями на CSS3 и jQuery » Techno-Co — Всё для вебмастера, для создание сайтов с нуля. {title}

Многие интернет-магазины сегодня используют небольшие панели с дополнительной информацией о продукции. Такой эффект еще много лет назад использовался на Template Monster, и сегодня он перерос в вездесущий тренд, почитаемый современными веб-дизайнерами.В нашем сегодняшнем руководстве хочется рассказать вам о том, как воссоздать подобный эффект при помощи небольшого фрагмента простого кода. Сегодня мы представим две разные версии, одна из которых будет реализована при помощи jQuery, а вторая за счет использования CSS3. У каждого из вариантов есть свои преимущества, и к тому же, у вас есть возможность скачать примеры с данного руководства.

BACKUP файлов для наших читателей находится в архиве.

Структурируем страницу

В нашем примере на jQuery код HTML слегка отличается от того, что представлен в адаптации на CSS3. Естественно нам понадобится библиотека jQuery, но здесь гораздо более важна реализация панели с подробностями. При помощи JS мы запускаем отдельный HTML-элемент, который заменяет внутренний HTML-контент. В случае с CSS3 нам требуются уникальные div-элементы для каждой из миниатюры-ссылки, и это вынуждает нас использовать дополнительный код в странице.


  
  • Social HX Icons
  • Message App Interface
  • Flat Toggles and Sliders




  

  

Этот код размещается в теле документа в версии на jQuery. Миниатюры разделяются в список, а информация для панели подробностей извлекается из HTML-атрибутов. Эти данные могут быть расположены в якорной ссылке, тэге image, либо связанном мета-тэге, который содержит описание контента. Мы также используем HTML5-атрибут data для отображения даты.Ближе к концу документа вы можете видеть отдельный div-контейнер с id #details-pane. Указание этого объекта в jQuery позволяет нам заменить внутренние значения для отображения подробностей. Теперь, давайте взглянем на один из элементов списка из версии на CSS3.


  
  • Social HX Icons

    Social HX Icons(Nov 12th, 2013)

    We love these little social media icons. With just a hint of depth and shadow, they make a change from the norm.

  • Мы заменяем ID на класс .details-pane, потому что нам нужно умножить число смежных div-элементов рядом с каждой миниатюрой. CSS3 осуществляет проверку, когда пользователь наводит курсор мыши на ссылку, и отображает смежный div, в котором уже размещена вся нужная информация. Итак, еще одно преимущество в использовании CSS3 заключается в том, что нам не нужно извлекать информацию из атрибутов каждый раз, когда изменяется целевое наполнение.Хотелось бы начать с примера на CSS3, так как наш jQuery-код немного сложнее. Это может стать еще одной причиной к тому, чтобы использовать версию на HTML/CSS, несмотря на то, что эффект не будет работать в устаревших браузерах.

    Панель с подробной информацией на CSS3

    Все это работает за счет использования знака (+) в селекторе. CSS определяет самый последний элемент селектора, и в данном случае это .details-pane, который расположен рядом с каждой якорной ссылкой. Мы задали ссылкам класс .hrvlink., поэтому их будет легче определить.

    .thumbs {
      padding: 8px 0;
      text-align: center;
    }
    
    .thumbs ul li {
      display: block;
      position: relative;
      float: left;
      margin-left: 50px;
      margin-bottom: 50px;
    }
    
    
    /** detail panel **/
    .details-pane {
      display: none;
      color: #414141;
      background: #f1f1f1;
      border: 1px solid #a9a9a9;
      position: absolute;
      top: 0;
      left: 290px;
      z-index: 99999;
      width: 530px;
      padding: 6px 8px;
      text-align: left;
      -webkit-box-shadow: 1px 3px 3px rgba(0,0,0,0.4);
      -moz-box-shadow: 1px 3px 3px rgba(0,0,0,0.4);
      box-shadow: 1px 3px 3px rgba(0,0,0,0.4);
    }
    .details-pane.rightside {
      left: -529px;
    }
    
    .details-pane h3 {
      font-size: 2.0em;
      line-height: 1.1em;
      margin-bottom: 4px;
    }
    
    .details-pane h3 span {
      font-size: 0.75em;
      font-style: italic;
      color: #555;
      padding-left: 15px;
    }
    
    .details-pane .desc {
      font-size: 1.2em;
      margin-bottom: 6px;
    }

    Надеемся, что здесь для вас не будет сложностей. Каждый элемент списка выравнивается по левому краю и имеет широкую маржу, чтобы в каждой строке помещалось только две миниатюры. Эти элементы списка содержат ссылку на миниатюру и окно с подробной информацией. Мы задаем элементу ‘li’ относительное позиционирование, чтобы у нас была возможность воспользоваться абсолютным позиционированием для панели с подробной информацией.Для вас может быть интересным то, что позиция изменяется между первым двумя ссылками. В случае с остальными ссылками, мы добавляем класс .rightside к контейнеру панели с подробностями. Изначально мы передвигаем панель с подробностями на 290 пикселей влево, так как это и есть длина миниатюры. Но в правой колонке получается так, что наша панель выходит за границу области видимости, поэтому вместо этого нам нужно, чтобы она появлялась с левой стороны. Для этого приема мы можем воспользоваться position:left на основе полной ширины 530 пикселей (это ширина панели подробностей).

    /** hover styles **/
    a.hvrlink:hover + .details-pane {
      display: block;
    }
    .details-pane:hover {
      display: block;
    }

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

    Переходим к jQuery

    Давайте взглянем на JS-код, который можно видеть в самом конце нашего исходного файла index.html. Большая часть CSS-кода схода, но при этом он даже короче и его проще воспринимать, так как здесь нам не нужно использовать абсолютные значения. Вместо нас за эти значения отвечают вычисления на jQuery, которые сначала могут показаться запутанными, но сильно помогут вам, если вы научитесь с ними работать.

    $(function(){
      $('.thumbs ul li img').on('mouseover', function(e){
        var dpane      = $('#details-pane');
        var dpanetitle = $('#details-pane .title');
        var dpanedesc  = $('#details-pane .desc');
        var newtitle   = $(this).attr('alt');
        var newdate    = $(this).attr('data-date');
        var newdesc    = $(this).parent().next('meta.desc').attr('content');
        var newimg     = $(this).attr('data-fullsize');
        var linkurl    = $(this).parent().attr('href');
    
        var position = $(this).offset();
        var imgwidth = $(this).width();
        var ycoord   = position.top;
        if(position.left / $(window).width() >= 0.5) {
          var xcoord = position.left - 530;
          // details pane is 530px fixed width
          // if the img position is beyond 50% of the page, we move the pane to the left side
        } else {
          var xcoord = position.left + imgwidth;
        }

    Мы указываем изображение миниатюры для обработчика событий hover, и как только он будет запущен, нам нужно будет выставить множество разных переменных. Первый большой фрагмент кода добывает всю важную информацию, которая нужна нам для отображения в панели подробностей.Далее нам нужно собрать координаты, которые помогут понять, где должна быть отображена эта панель. Координата y не будет меняться относительно позиции, но вот координата x будет, если вы наводим курсор на правую колонку. У нас также есть логическое выражение, которое перепроверяет текущее расположение изображения, разделенное на полный размер окна при помощи $(window).width(). Если изображение находится на более 50% от полной ширины страницы, то нам нужно отображать панель по левую сторону от элемента.

      $('.big-img a').attr('href',linkurl);
      $('.big-img a img').attr('src',newimg);
    
      var titlehtml = newtitle + '('+newdate+')';
    
      dpanetitle.html(titlehtml);
      dpanedesc.html(newdesc);
      dpane.css({ 'left': xcoord, 'top': ycoord, 'display': 'block'});
    
    }).on('mouseout', function(e){
      $('#details-pane').css('display','none');
    });

    Последующий код заменяет внутренние HTML-значения внутри панели с подробностями при помощи переменных, которые мы определили ранее. В самом конце мы обновляем строчные CSS-параметры для изменения параметра display:block, и отображения его на странице. При наведении курсора за пределы миниатюры, панель будет скрываться автоматически, если, конечно, пользователь не переведет курсор на саму панель. Это событие hover будет удерживаться при помощи цельного отдельного слушателя событий, для которого потребуется немного сложной логики.

      // when hovering the details pane keep displayed, otherwise hide
      $('#details-pane').on('mouseover', function(e){
        $(this).css('display','block');
      });
      $('#details-pane').on('mouseout', function(e){
        //this is the original element the event handler was assigned to
        var e = e.toElement || e.relatedTarget;
        if (e.parentNode == this || e.parentNode.parentNode == this || e.parentNode.parentNode.parentNode == this || e == this || e.nodeName == 'IMG') {
          return;
        }
        $(this).css('display','none');
        //console.log(e.nodeName)
      });
    });

    Учтите, что мы используем 2 отдельных метода .on(), прикрепленных к одному и тому же jQuery-селектору. Вы можете рассмотреть вариант с объединением их в единую jQuery-цепь с другими схожими слушателями событий. При наведении нам просто нужно удерживать панель отображенной в качестве блочного элемента. Но когда курсор уводится с панели подробностей, нам нужно ее скрыть ее, если пользователь далее наводит курсор не на ту же миниатюру.Переменная e возвращается при каждом событии mouseout, и сообщает нам, на какой новый элемент был наведен курсор. Применяя свойство parentNode, мы можем проверить, где находится этот новый элемент. Внутри выражения у нас есть 4 отдельные проверки логики, и три из них проверяют объекты внутри панели с подробностями. Все это связано с переменной #details-pane.Нам нужно проверять случаи, когда пользователь наводит курсор на элемент h3, на paragraph или же на изображение (которое встроено в якорную ссылку и в div). Если да, то мы ничего не скрываем.Мы также проверяем свойство nodeName, если пользователь уводит курсор с панели с подробностями на тело страницы. Если node возвращает IMG, значит ничего не должно скрываться. Это больше похоже на хак, так как в нашем демо с миниатюрами связаны только изображения. Так что, при наведении на изображение, нам нужно, чтобы панель с подробностями оставалась отображенной, иначе она будет скрыта при помощи jQuery-метода .css().У нас не было возможность решить это более подходящим путем, и поэтому нам хотелось бы услышать ваши предположения и предположения по поводу решения данного вопроса. Возможно, должен быть способ провести проверку класса image, но, к сожалению, мы не можем сделать это при помощи свойства nodeName. Вы можете взглянуть на комментарии к коду console.log(e.nodeName), который можно запустить для проверки, какие свойства возвращаются браузеру.

    В завершение

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