Сетка миниатюр с возможностью расширенного представления
В последнее время поиск изображений через Google несколько преобразился. Сегодня мы рассмотрим, каким образом можно организовать подобный функционал. Идея заключается в отображении более крупного изображения при клике на его миниатюру, а также вывод названия, описания и ссылки.
Ключевым моментом будет вычисление нужного размера полного изображения и перемещение страницы на нужную позицию. При показе крупного изображения, мы также оставим видимым его миниатюру, а весь оставшийся контент накроем блоком серого цвета. Также мы не будем использовать крупные изображения, так что на крупных мониторах могут образоваться свободные области.
Итак, давайте начнём!
HTML
Для начала, нам необходимо отобразить сетку изображений. Для этого мы воспользуемся ненумерованным списком. Каждый элемент списка, будет содержать элемент ссылки с несколькими очень важными атрибутами:
<ul id="og-grid" class="og-grid">
<li>
<a href="http://cargocollective.com/jaimemartinez/" data-largesrc="/images/1.jpg" data-title="Azuki bean" data-description="Swiss chard pumpkin bunya nuts maize plantain aubergine napa cabbage soko coriander sweet pepper water spinach winter purslane shallot tigernut lentil beetroot.">
<img src="/images/thumbs/1.jpg" alt="img01"/>
</a>
</li>
<li>
<a href="http://cargocollective.com/jaimemartinez/" data-largesrc="/images/2.jpg" data-title="Veggies sunt bona vobis" data-description="Komatsuna prairie turnip wattle seed artichoke mustard horseradish taro rutabaga ricebean carrot black-eyed pea turnip greens beetroot yarrow watercress kombu.">
<img src="/images/thumbs/2.jpg" alt="img02"/>
</a>
</li>
<li><!-- ... --></li>
<!-- ... -->
</ul>
Значение атрибута href будет использоваться при формировании ссылки (также будет работать с отключённым JavaScript). В атрибутах data-largesrc содержится адрес полного изображения, data-title - название, data-description - описание.
При клике на миниатюру более крупное представление будет раскрываться чуть ниже, поэтому его html код мы поместим в тот же элемент списка, прямо за элементом ссылки:
<li>
<a href="http://cargocollective.com/jaimemartinez/" data-largesrc="/images/2.jpg" data-title="Veggies sunt bona vobis" data-description="Komatsuna prairie turnip wattle seed artichoke mustard horseradish taro rutabaga ricebean carrot black-eyed pea turnip greens beetroot yarrow watercress kombu.">
<img src="/images/thumbs/2.jpg" alt="img02"/>
</a>
<div class="og-expander">
<div class="og-expander-inner">
<span class="og-close"></span>
<div class="og-fullimg">
<div class="og-loading"></div>
<img src="/images/2.jpg">
</div>
<div class="og-details">
<h3>Veggies sunt bona vobis</h3>
<p>Komatsuna prairie turnip wattle seed artichoke mustard horseradish taro rutabaga ricebean carrot black-eyed pea turnip greens beetroot yarrow watercress kombu.</p>
<a href="http://cargocollective.com/jaimemartinez/">Visit website</a>
</div>
</div>
</div>
</li>
Теперь давайте всё это дело оформим.
CSS
Заметка: в данных листингах вы не найдёте css префиксов для разных браузеров. Полный код можно найти в исходниках, которые доступны для скачивания.
Итак, давайте начнём с самой сетки. Она будет размером во весь экран, текст будет располагаться по центру. Также будут отцентрированы и все миниатюры, благодаря данной записи “display: inline-block”:
.og-grid {
list-style: none;
padding: 20px 0;
margin: 0 auto;
text-align: center;
width: 100%;
}
.og-grid li {
display: inline-block;
margin: 10px 5px 0 5px;
vertical-align: top;
height: 250px;
}
Ссылки и изображения будут отображаться как блоки. Также для данных элементов сбросим некоторые стили:
.og-grid li > a,
.og-grid li > a img {
border: none;
outline: none;
display: block;
position: relative;
}
При клике на элемент сетки, мы добавим специальный класс og-expanded. Также к панели прикрепим знак стрелки, чтоб знать к какой миниатюре относится описание.
.og-grid li.og-expanded > a::after {
top: auto;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-bottom-color: #ddd;
border-width: 15px;
left: 50%;
margin: -20px 0 0 -15px;
}
Раскрывающийся блок будет позиционироваться абсолютно, и у него также будет класс og-expander. Изначально его высота будет равна 0, а опция overflow равна hidden, т.е. элемент будет скрыт.
.og-expander {
position: absolute;
background: #ddd;
top: auto;
left: 0;
width: 100%;
margin-top: 10px;
text-align: left;
height: 0;
overflow: hidden;
}
.og-expander-inner {
padding: 50px 30px;
height: 100%;
}
Знак закрытия панели будет формироваться из псевдо-элементов (двух повёрнутых линий):
.og-close {
position: absolute;
width: 40px;
height: 40px;
top: 20px;
right: 20px;
cursor: pointer;
}
.og-close::before,
.og-close::after {
content: '';
position: absolute;
width: 100%;
top: 50%;
height: 1px;
background: #888;
transform: rotate(45deg);
}
.og-close::after {
transform: rotate(-45deg);
}
.og-close:hover::before,
.og-close:hover::after {
background: #333;
}
Контейнеры для изображения и описания будут 50% в ширину, а также прикреплены друг к другу:
.og-fullimg,
.og-details {
width: 50%;
float: left;
height: 100%;
overflow: hidden;
position: relative;
}
Опции изображения max-width выставим 100%, чтобы его размеры автоматически подгонялись под размеры контейнера.
.og-details {
padding: 0 40px 0 20px;
}
.og-fullimg {
text-align: center;
}
.og-fullimg img {
display: inline-block;
max-height: 100%;
max-width: 100%;
}
Теперь давайте добавим стилей для текста и ссылки:
.og-details h3 {
font-weight: 300;
font-size: 52px;
padding: 40px 0 10px;
margin-bottom: 10px;
}
.og-details p {
font-weight: 400;
font-size: 16px;
line-height: 22px;
color: #999;
}
.og-details a {
font-weight: 700;
font-size: 16px;
color: #333;
text-transform: uppercase;
letter-spacing: 2px;
padding: 10px 20px;
border: 3px solid #333;
display: inline-block;
margin: 30px 0 0;
outline: none;
}
.og-details a::before {
content: '\2192';
display: inline-block;
margin-right: 10px;
}
.og-details a:hover {
border-color: #999;
color: #999;
}
Отображение загрузки изображения будет располагаться в том же контейнере, где и картинка. Данный элемент мы реализуем средствами CSS: создадим круг и три тени, затем анимируем изменение цвета заливки:
.og-loading {
width: 20px;
height: 20px;
border-radius: 50%;
background: #ddd;
box-shadow: 0 0 1px #ccc, 15px 30px 1px #ccc, -15px 30px 1px #ccc;
position: absolute;
top: 50%;
left: 50%;
margin: -25px 0 0 -25px;
animation: loader 0.5s infinite ease-in-out both;
}
@keyframes loader {
0% { background: #ddd; }
33% { background: #ccc; box-shadow: 0 0 1px #ccc, 15px 30px 1px #ccc, -15px 30px 1px #ddd; }
66% { background: #ccc; box-shadow: 0 0 1px #ccc, 15px 30px 1px #ddd, -15px 30px 1px #ccc; }
}
Ну и напоследок, добавим несколько медиа запросов для того, чтобы скорректировать размер такта, а также уберём панель полного изображения, если размер экрана меньше 650px. В этом случае, размер миниатюры и так велик:
@media screen and (max-width: 830px) {
.og-expander h3 { font-size: 32px; }
.og-expander p { font-size: 13px; }
.og-expander a { font-size: 12px; }
}
@media screen and (max-width: 650px) {
.og-fullimg { display: none; }
.og-details { float: none; width: 100%; }
}
Ну, а теперь давайте оживим нашу сетку с помощью JavaScript.
JavaScript
Для начала, давайте закэшируем некоторые данные:
// списки элементов
var $grid = $( '#og-grid' ),
// элементы
$items = $grid.children( 'li' ),
// индекс текущего раскрытого элемента
current = -1,
// позиция (top) раскрывшегося элемента
previewPos = -1,
// количество пикселей, на которое нужно прокрутить страницу
scrollExtra = 0,
// значение margin раскрытого элемента (между изображением и следующим элементов в строке)
marginExpanded = 10,
$window = $( window ), winsize,
$body = $( 'html, body' ),
// события трансформации (перемещения)
transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
support = Modernizr.csstransitions,
// изначальные настройки
settings = {
minHeight : 500,
speed : 350,
easing : 'ease'
};
Теперь можно загрузить все миниатюры в сетку. После этого мы сможем записать размеры каждого элемента сетки, размер экрана и назначить несколько событий:
function init( config ) {
// настройки..
settings = $.extend( true, {}, settings, config );
// загрузить все изображения
$grid.imagesLoaded( function() {
// сохраняем размер и смещение элементов
saveItemInfo( true );
// получаем размер окна
getWinSize();
// инициализация событий
initEvents();
} );
}
// сохраняем верхнее смещение элемента и его высоту
function saveItemInfo( saveheight ) {
$items.each( function() {
var $item = $( this );
$item.data( 'offsetTop', $item.offset().top );
if( saveheight ) {
$item.data( 'height', $item.height() );
}
} );
}
function getWinSize() {
winsize = { width : $window.width(), height : $window.height() };
}
Функция showPreview предназначена для инициализации объекта Preview, который в последствии будет раскрываться, показывая название, описание и крупное изображение. Если данный объект уже создан, то мы просто обновим его внутренние данные (в зависимости от того, какое действие совершил пользователь: закрыл представление, кликнул на другую миниатюру и так далее).
Для проверки клика по миниатюре, которая находится в том же ряду с уже кликнутой (раскрытой), воспользуемся значением смещения top данных элементов:
function showPreview( $item ) {
var preview = $.data( this, 'preview' ),
// смещение сверху
position = $item.data( 'offsetTop' );
scrollExtra = 0;
// если представление полного изображения существует и previewPos отличается (разные строки в сетке), закроем панель
if( typeof preview != 'undefined' ) {
// не в одной и той же строке
if( previewPos !== position ) {
// если position > previewPos, то берём в расчёт текущую высоту панели представления для скроллинга (смещения) страницы
if( position > previewPos ) {
scrollExtra = preview.height;
}
hidePreview();
}
// если в той же строке
else {
preview.update( $item );
return false;
}
}
// обновляем previewPos
previewPos = position;
// инициализируем новую панель для представления элемента, по которому был осуществлён клик
preview = $.data( this, 'preview', new Preview( $item ) );
// раскрыть представление
preview.open();
}
Объект Preview будет ссылаться на элемент, который отображается на текущем этапе (Preview.$item), а также будет иметь доступ к индексу раскрытого элемента (Preview.expandedIdx). Благодаря этим значениям, мы можем определить, закрывать панель представления (при клике по другой миниатюре из другой строки сетки) или оставить панель и только обновить данные (при клике по миниатюре в той же строке сетки).
// объект preview
function Preview( $item ) {
this.$item = $item;
this.expandedIdx = this.$item.index();
this.create();
this.update();
}
Теперь, когда объект Preview готов, можем взяться за код, который будет выводить детализированную информацию об изображении:
create : function() {
// создаём структуру:
this.$title = $( '<h3></h3>' );
this.$description = $( '<p></p>' );
this.$href = $( '<a href="#">Visit website</a>' );
this.$details = $( '<div class="og-details"></div>' ).append( this.$title, this.$description, this.$href );
this.$loading = $( '<div class="og-loading"></div>' );
this.$fullimage = $( '<div class="og-fullimg"></div>' ).append( this.$loading );
this.$closePreview = $( '<span class="og-close"></span>' );
this.$previewInner = $( '<div class="og-expander-inner"></div>' ).append( this.$closePreview, this.$fullimage, this.$details );
this.$previewEl = $( '<div class="og-expander"></div>' ).append( this.$previewInner );
// прикрепляем html код к элементу
this.$item.append( this.getEl() );
// задаём элементу настройки перемещения
if( support ) {
this.setTransition();
}
}
Функция update будет задействована для обновления информации в панели представления:
update : function( $item ) {
// обновить настройки элемента
if( $item ) {
this.$item = $item;
}
// если раскрыта, убираем класс "og-expanded" с текущего элемента
if( current !== -1 ) {
var $currentItem = $items.eq( current );
$currentItem.removeClass( 'og-expanded' );
this.$item.addClass( 'og-expanded' );
// позиция Preview объекта
this.positionPreview();
}
// обновить текущий индекс
current = this.$item.index();
// обновить контент представления
var $itemEl = this.$item.children( 'a' ),
eldata = {
href : $itemEl.attr( 'href' ),
largesrc : $itemEl.data( 'largesrc' ),
title : $itemEl.data( 'title' ),
description : $itemEl.data( 'description' )
};
this.$title.html( eldata.title );
this.$description.html( eldata.description );
this.$href.attr( 'href', eldata.href );
var self = this;
// удалить изображение из панели представления
if( typeof self.$largeImg != 'undefined' ) {
self.$largeImg.remove();
}
// загрузить новое изображение и добавить в панель
// для узких мониторов не будет отображать большое изображение
if( self.$fullimage.is( ':visible' ) ) {
this.$loading.show();
$( '<img/>' ).load( function() {
self.$loading.hide();
self.$largeImg = $( this ).fadeIn( 350 );
self.$fullimage.append( self.$largeImg );
} ).attr( 'src', eldata.largesrc );
}
}
Далее мы должны рассчитать размер панели представления полного изображения. Его высота будет равна значению высоты окна - высота элемента сетки. Для того чтобы избежать непредвиденных ситуаций, также зададим значение minHeight.
После того как панелька раскроется, нам нужно сместить немного страницу:
open : function() {
setTimeout( $.proxy( function() {
// задать высоту превью блока, равную высоте элемента
this.setHeights();
// сместить позицию страницы
this.positionPreview();
}, this ), 25 );
}
setHeights : function() {
var self = this,
onEndFn = function() {
if( support ) {
self.$item.off( transEndEventName );
}
self.$item.addClass( 'og-expanded' );
};
this.calcHeight();
this.$previewEl.css( 'height', this.height );
this.$item.css( 'height', this.itemHeight ).on( transEndEventName, onEndFn );
if( !support ) {
onEndFn.call();
}
}
calcHeight : function() {
var heightPreview = winsize.height - this.$item.data( 'height' ) - marginExpanded,
itemHeight = winsize.height;
if( heightPreview < settings.minHeight ) {
heightPreview = settings.minHeight;
itemHeight = settings.minHeight + this.$item.data( 'height' ) + marginExpanded;
}
this.height = heightPreview;
this.itemHeight = itemHeight;
}
positionPreview : function() {
// сместить страницу
// вариант 1 : высота превью + высота элемента (помещается в размер окна)
// вариант 2 : высота превью + высота элемента (не помещается в размер окна). Получившийся размер меньше размера окна.
// вариант 3 : высота превью + высота элемента (не помещается в размер окна). Получившийся размер больше размера окна.
var position = this.$item.data( 'offsetTop' ),
previewOffsetT = this.$previewEl.offset().top - scrollExtra,
scrollVal = this.height + this.$item.data( 'height' ) + marginExpanded <= winsize.height ? position : this.height < winsize.height ? previewOffsetT - ( winsize.height - this.height ) : previewOffsetT;
$body.animate( { scrollTop : scrollVal }, settings.speed );
}
При закрытии панели необходимо поставить всё на свои места и удалить скрытый html из DOM.
close : function() {
var self = this,
onEndFn = function() {
if( support ) {
$( this ).off( transEndEventName );
}
self.$item.removeClass( 'og-expanded' );
self.$previewEl.remove();
};
setTimeout( $.proxy( function() {
if( typeof this.$largeImg !== 'undefined' ) {
this.$largeImg.fadeOut( 'fast' );
}
this.$previewEl.css( 'height', 0 );
// текущий раскрытый элемент (может отличаться от this.$item)
var $expandedItem = $items.eq( this.expandedIdx );
$expandedItem.css( 'height', $expandedItem.data( 'height' ) ).on( transEndEventName, onEndFn );
if( !support ) {
onEndFn.call();
}
}, this ), 25 );
return false;
}
Надеюсь, данный урок и его результат будут вам полезны!
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/2q35KhfBxWE/lessons.php
|
В последнее время поиск изображений через Google несколько преобразился. Сегодня мы рассмотрим, каким образом можно организовать подобный функционал. Идея заключается в отображении более крупного |
РэдЛайн, создание сайта, заказать сайт, разработка сайтов, реклама в Интернете, продвижение, маркетинговые исследования, дизайн студия, веб дизайн, раскрутка сайта, создать сайт компании, сделать сайт, создание сайтов, изготовление сайта, обслуживание сайтов, изготовление сайтов, заказать интернет сайт, создать сайт, изготовить сайт, разработка сайта, web студия, создание веб сайта, поддержка сайта, сайт на заказ, сопровождение сайта, дизайн сайта, сайт под ключ, заказ сайта, реклама сайта, хостинг, регистрация доменов, хабаровск, краснодар, москва, комсомольск |
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2025-12-02 » Когда ошибка молчит: как бессмысленные сообщения ломают пользовательский опыт
- 2025-12-02 » 9 лучших бесплатных фотостоков
- 2025-12-02 » UTM-метки: ключевой инструмент аналитики для маркетолога
- 2025-12-02 » ПромоСтраницы Яндекса: Что такое и для чего служит
- 2025-12-02 » Метатеги для сайта: исчерпывающее руководство по Title, Description, Canonical, Robots и другим тегам
- 2025-11-26 » Оценка эффективности контента: превращаем информационный балласт в рабочий актив
- 2025-11-26 » 10 причин высокого показателя отказов на сайте
- 2025-11-26 » Когда и зачем обновлять структуру сайта
- 2025-11-26 » Скрытые демотиваторы: как мелочи разрушают эффективность команды
- 2025-11-26 » Зачем запускать MVP и как сделать это грамотно?
- 2025-11-20 » Половина российских компаний сократит расходы на транспорт и маркетинг в 2026 году
- 2025-11-20 » Перенос сайта с большим количеством ссылок
- 2025-11-20 » Перелинковка сайта: Что такое и как ее использовать
- 2025-11-20 » Критерии выбора SEO-специалиста и подрядчика для продвижения сайта
- 2025-11-20 » Применение искусственного интеллекта в рекламных агентствах: комплексное исследование трендов 2025 года
- 2025-11-19 » Геозапросы по-новому: как покорить локальное SEO с помощью ИИ
- 2025-11-14 » Консалтинг: сущность и ключевые направления
- 2025-11-14 » Онлайн-формы: универсальный инструмент для сбора обратной связи
- 2025-11-14 » Факторы конверсии органического трафика
- 2025-11-14 » Планирование рекламного бюджета: самостоятельный подход
- 2025-11-14 » Авторизация на сайте: как выбрать решение для удержания клиентов и сохранения продаж
- 2025-11-13 » Эффективные методы стимулирования клиентов к оставлению положительных отзывов
- 2025-11-13 » Налоговая реформа — 2026: грядущие изменения для предпринимателей
- 2025-11-13 » Альтернативы мессенджерам: что выбрать вместо Telegram и WhatsApp
- 2025-11-13 » Маркировка рекламы для начинающих: полное руководство по требованиям ЕРИР
- 2025-11-13 » ИИ не отберет вашу работу — её займет специалист, владеющий искусственным интеллектом
- 2025-10-29 » Как оценить эффективность работы SEO-специалиста: практическое руководство для маркетологов и владельцев бизнеса
- 2025-10-29 » Киберспорт как маркетинговый инструмент: стратегии привлечения геймеров
- 2025-10-29 » Как говорить с аудиторией о сложном
- 2025-10-29 » Что такое доказательства с нулевым разглашением (ZKP) и их роль в блокчейне
Человек - аристократ среди животных Гейне Генрих - (1797-1856) - немецкий поэт и публицист |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.


Мы создаем практически любые сайты от продающих страниц до сложных, высоконагруженных и нестандартных веб приложений! Наши сайты это надежные маркетинговые инструменты для успеха Вашего бизнеса и увеличения вашей прибыли! Мы делаем красивые и максимально эффектные сайты по доступным ценам уже много лет!
Комплексный подход это не просто продвижение сайта, это целый комплекс мероприятий, который определяется целями и задачами поставленными перед сайтом и организацией, которая за этим стоит. Время однобоких методов в продвижении сайтов уже прошло, конкуренция слишком высока, чтобы была возможность расслабиться и получать \ удерживать клиентов из Интернета, просто сделав сайт и не занимаясь им...
Мы оказываем полный комплекс услуг по сопровождению сайта: информационному и техническому обслуживанию и развитию Интернет сайтов.
Контекстная реклама - это эффективный инструмент в интернет маркетинге, целью которого является увеличение продаж. Главный плюс контекстной рекламы заключается в том, что она работает избирательно.