我已经将网格实现到一个站点中,一切都很好!我已经使用 JavaScript 文件添加了上一个和下一个按钮来附加它们,但似乎无法让它们循环上一个和下一个。
我注意到 Google 的图像搜索,您可以使用箭头键循环浏览它们,但希望使用这些按钮来完成。我知道您可以定位名称属性并循环浏览图像,但在这个特定的网格中,只有data-largesrc
我似乎无法定位的那些(我可以定位img src
拇指。图像在<li>
所以也许可以定位?任何想法都将不胜感激。JavaScript文件有点大......
/*
* debouncedresize: special jQuery event that happens once after a window resize
*
* latest version and complete README available on Github:
* https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js
*
* Copyright 2011 @louis_remi
* Licensed under the MIT license.
*/
var $jevent = $j.event,
$jspecial,
resizeTimeout;
$jspecial = $jevent.special.debouncedresize = {
setup: function() {
$j( this ).on( "resize", $jspecial.handler );
},
teardown: function() {
$j( this ).off( "resize", $jspecial.handler );
},
handler: function( event, execAsap ) {
// Save the context
var context = this,
args = arguments,
dispatch = function() {
// set correct event type
event.type = "debouncedresize";
$jevent.dispatch.apply( context, args );
};
if ( resizeTimeout ) {
clearTimeout( resizeTimeout );
}
execAsap ?
dispatch() :
resizeTimeout = setTimeout( dispatch, $jspecial.threshold );
},
threshold: 250
};
// ======================= imagesLoaded Plugin ===============================
// https://github.com/desandro/imagesloaded
// $j('#my-container').imagesLoaded(myFunction)
// execute a callback when all images have loaded.
// needed because .load() doesn't work on cached images
// callback function gets image collection as argument
// this is the container
// original: MIT license. Paul Irish. 2010.
// contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou
// blank image data-uri bypasses webkit log warning (thx doug jones)
var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
$j.fn.imagesLoaded = function( callback ) {
var $jthis = this,
deferred = $j.isFunction($j.Deferred) ? $j.Deferred() : 0,
hasNotify = $j.isFunction(deferred.notify),
$jimages = $jthis.find('img').add( $jthis.filter('img') ),
loaded = [],
proper = [],
broken = [];
// Register deferred callbacks
if ($j.isPlainObject(callback)) {
$j.each(callback, function (key, value) {
if (key === 'callback') {
callback = value;
} else if (deferred) {
deferred[key](value);
}
});
}
function doneLoading() {
var $jproper = $j(proper),
$jbroken = $j(broken);
if ( deferred ) {
if ( broken.length ) {
deferred.reject( $jimages, $jproper, $jbroken );
} else {
deferred.resolve( $jimages );
}
}
if ( $j.isFunction( callback ) ) {
callback.call( $jthis, $jimages, $jproper, $jbroken );
}
}
function imgLoaded( img, isBroken ) {
// don't proceed if BLANK image, or image is already loaded
if ( img.src === BLANK || $j.inArray( img, loaded ) !== -1 ) {
return;
}
// store element in loaded images array
loaded.push( img );
// keep track of broken and properly loaded images
if ( isBroken ) {
broken.push( img );
} else {
proper.push( img );
}
// cache image and its state for future calls
$j.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } );
// trigger deferred progress method if present
if ( hasNotify ) {
deferred.notifyWith( $j(img), [ isBroken, $jimages, $j(proper), $j(broken) ] );
}
// call doneLoading and clean listeners if all images are loaded
if ( $jimages.length === loaded.length ){
setTimeout( doneLoading );
$jimages.unbind( '.imagesLoaded' );
}
}
// if no images, trigger immediately
if ( !$jimages.length ) {
doneLoading();
} else {
$jimages.bind( 'load.imagesLoaded error.imagesLoaded', function( event ){
// trigger imgLoaded
imgLoaded( event.target, event.type === 'error' );
}).each( function( i, el ) {
var src = el.src;
// find out if this image has been already checked for status
// if it was, and src has not changed, call imgLoaded on it
var cached = $j.data( el, 'imagesLoaded' );
if ( cached && cached.src === src ) {
imgLoaded( el, cached.isBroken );
return;
}
// if complete is true and browser supports natural sizes, try
// to check for image status manually
if ( el.complete && el.naturalWidth !== undefined ) {
imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 );
return;
}
// cached images don't fire load sometimes, so we reset src, but only when
// dealing with IE, or image is complete (loaded) and failed manual check
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
if ( el.readyState || el.complete ) {
el.src = BLANK;
el.src = src;
}
});
}
return deferred ? deferred.promise( $jthis ) : $jthis;
};
var Grid = (function() {
// list of items
var $jgrid = $j( '#og-grid' ),
// the items
$jitems = $jgrid.children( 'li' ),
// current expanded item's index
current = -1,
// position (top) of the expanded item
// used to know if the preview will expand in a different row
previewPos = -1,
// extra amount of pixels to scroll the window
scrollExtra = 0,
// extra margin when expanded (between preview overlay and the next items)
marginExpanded = 10,
$jwindow = $j( window ), winsize,
$jbody = $j( 'html, body' ),
// transitionend events
transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
// support for csstransitions
support = Modernizr.csstransitions,
// default settings
settings = {
minHeight : 500,
speed : 350,
easing : 'ease'
};
function init( config ) {
// the settings..
settings = $j.extend( true, {}, settings, config );
// preload all images
$jgrid.imagesLoaded( function() {
// save item´s size and offset
saveItemInfo( true );
// get window´s size
getWinSize();
// initialize some events
initEvents();
} );
}
// saves the item´s offset top and height (if saveheight is true)
function saveItemInfo( saveheight ) {
$jitems.each( function() {
var $jitem = $j( this );
$jitem.data( 'offsetTop', $jitem.offset().top );
if( saveheight ) {
$jitem.data( 'height', $jitem.height() );
}
} );
}
function initEvents() {
// when clicking an item, show the preview with the item´s info and large image.
// close the item if already expanded.
// also close if clicking on the item´s cross
$jitems.on( 'click', 'span.og-close', function() {
hidePreview();
return false;
} ).children( 'a' ).on( 'click', function(e) {
var $jitem = $j( this ).parent();
// check if item already opened
current === $jitem.index() ? hidePreview() : showPreview( $jitem );
return false;
} );
// on window resize get the window´s size again
// reset some values..
$jwindow.on( 'debouncedresize', function() {
scrollExtra = 0;
previewPos = -1;
// save item´s offset
saveItemInfo();
getWinSize();
var preview = $j.data( this, 'preview' );
if( typeof preview != 'undefined' ) {
hidePreview();
}
} );
}
function getWinSize() {
winsize = { width : $jwindow.width(), height : $jwindow.height() };
}
function showPreview( $jitem ) {
var preview = $j.data( this, 'preview' ),
// item´s offset top
position = $jitem.data( 'offsetTop' );
scrollExtra = 0;
// if a preview exists and previewPos is different (different row) from item´s top then close it
if( typeof preview != 'undefined' ) {
// not in the same row
if( previewPos !== position ) {
// if position > previewPos then we need to take te current preview´s height in consideration when scrolling the window
if( position > previewPos ) {
scrollExtra = preview.height;
}
hidePreview();
}
// same row
else {
preview.update( $jitem );
return false;
}
}
// update previewPos
previewPos = position;
// initialize new preview for the clicked item
preview = $j.data( this, 'preview', new Preview( $jitem ) );
// expand preview overlay
preview.open();
}
function hidePreview() {
current = -1;
var preview = $j.data( this, 'preview' );
preview.close();
$j.removeData( this, 'preview' );
}
// the preview obj / overlay
function Preview( $jitem ) {
this.$jitem = $jitem;
this.expandedIdx = this.$jitem.index();
this.create();
this.update();
}
Preview.prototype = {
create : function() {
// create Preview structure:
this.$jtitle = $j( '<h3></h3>' );
this.$jdescription = $j( '<p></p>' );
this.$jhref = $j( '<a href="#">Go To Contact Page...</a>' );
this.$jdetails = $j( '<div class="og-details"></div>' ).append( this.$jtitle, this.$jdescription, this.$jhref );
this.$jloading = $j( '<div class="og-loading"></div>' );
this.$jfullimage = $j( '<div class="og-fullimg"></div>' ).append( this.$jloading );
this.$jclosePreview = $j( '<span class="og-close"></span>' );
this.$jprevious = $j( '<a href="javascript:PreviousImage()"><span class="og-previous"></span></a>' );
this.$jnext = $j( '<a href="javascript:NextImage()"><span class="og-next"></span></a>' );
this.$jpreviewInner = $j( '<div class="og-expander-inner"></div>' ).append( this.$jclosePreview, this.$jprevious, this.$jnext, this.$jfullimage, this.$jdetails );
this.$jpreviewEl = $j( '<div class="og-expander"></div>' ).append( this.$jpreviewInner );
// append preview element to the item
this.$jitem.append( this.getEl() );
// set the transitions for the preview and the item
if( support ) {
this.setTransition();
}
},
update : function( $jitem ) {
if( $jitem ) {
this.$jitem = $jitem;
}
// if already expanded remove class "og-expanded" from current item and add it to new item
if( current !== -1 ) {
var $jcurrentItem = $jitems.eq( current );
$jcurrentItem.removeClass( 'og-expanded' );
this.$jitem.addClass( 'og-expanded' );
// position the preview correctly
this.positionPreview();
}
// update current value
current = this.$jitem.index();
// update preview´s content
var $jitemEl = this.$jitem.children( 'a' ),
eldata = {
href : $jitemEl.attr( 'href' ),
largesrc : $jitemEl.data( 'largesrc' ),
title : $jitemEl.data( 'title' ),
description : $jitemEl.data( 'description' )
};
this.$jtitle.html( eldata.title );
this.$jdescription.html( eldata.description );
this.$jhref.attr( 'href', eldata.href );
var self = this;
// remove the current image in the preview
if( typeof self.$jlargeImg != 'undefined' ) {
self.$jlargeImg.remove();
}
// preload large image and add it to the preview
// for smaller screens we don´t display the large image (the media query will hide the fullimage wrapper)
if( self.$jfullimage.is( ':visible' ) ) {
this.$jloading.show();
$j( '<img/>' ).load( function() {
var $jimg = $j( this );
if( $jimg.attr( 'src' ) === self.$jitem.children('a').data( 'largesrc' ) ) {
self.$jloading.hide();
self.$jfullimage.find( 'img' ).remove();
self.$jlargeImg = $jimg.fadeIn( 350 );
self.$jfullimage.append( self.$jlargeImg );
}
} ).attr( 'src', eldata.largesrc );
}
},
open : function() {
setTimeout( $j.proxy( function() {
// set the height for the preview and the item
this.setHeights();
// scroll to position the preview in the right place
this.positionPreview();
}, this ), 25 );
},
close : function() {
var self = this,
onEndFn = function() {
if( support ) {
$j( this ).off( transEndEventName );
}
self.$jitem.removeClass( 'og-expanded' );
self.$jpreviewEl.remove();
};
setTimeout( $j.proxy( function() {
if( typeof this.$jlargeImg !== 'undefined' ) {
this.$jlargeImg.fadeOut( 'fast' );
}
this.$jpreviewEl.css( 'height', 0 );
// the current expanded item (might be different from this.$jitem)
var $jexpandedItem = $jitems.eq( this.expandedIdx );
$jexpandedItem.css( 'height', $jexpandedItem.data( 'height' ) ).on( transEndEventName, onEndFn );
if( !support ) {
onEndFn.call();
}
}, this ), 25 );
return false;
},
calcHeight : function() {
var heightPreview = winsize.height - this.$jitem.data( 'height' ) - marginExpanded,
itemHeight = winsize.height;
if( heightPreview < settings.minHeight ) {
heightPreview = settings.minHeight;
itemHeight = settings.minHeight + this.$jitem.data( 'height' ) + marginExpanded;
}
this.height = heightPreview;
this.itemHeight = itemHeight;
},
setHeights : function() {
var self = this,
onEndFn = function() {
if( support ) {
self.$jitem.off( transEndEventName );
}
self.$jitem.addClass( 'og-expanded' );
};
this.calcHeight();
this.$jpreviewEl.css( 'height', this.height );
this.$jitem.css( 'height', this.itemHeight ).on( transEndEventName, onEndFn );
if( !support ) {
onEndFn.call();
}
},
positionPreview : function() {
// scroll page
// case 1 : preview height + item height fits in window´s height
// case 2 : preview height + item height does not fit in window´s height and preview height is smaller than window´s height
// case 3 : preview height + item height does not fit in window´s height and preview height is bigger than window´s height
var position = this.$jitem.data( 'offsetTop' ),
previewOffsetT = this.$jpreviewEl.offset().top - scrollExtra,
scrollVal = this.height + this.$jitem.data( 'height' ) + marginExpanded <= winsize.height ? position : this.height < winsize.height ? previewOffsetT - ( winsize.height - this.height ) : previewOffsetT;
$jbody.animate( { scrollTop : scrollVal }, settings.speed );
},
setTransition : function() {
this.$jpreviewEl.css( 'transition', 'height ' + settings.speed + 'ms ' + settings.easing );
this.$jitem.css( 'transition', 'height ' + settings.speed + 'ms ' + settings.easing );
},
getEl : function() {
return this.$jpreviewEl;
}
}
return { init : init };
})();
这是HTML...
<ul id="og-grid" class="og-grid">
<!-- The Entrance -->
<li>
<a href="http://www.thebarnandpinncottage.co.uk/contact" data-largesrc="/images/cottage-images/entrance/image-entrance.jpg" data-title="The Entrance" data-description="The Barn and Pinn Cottage">
<img src="/images/cottage-images/entrance/image-entrance-thumb.jpg" alt="img01"/>
</a>
</li>
<li>
<a href="http://www.thebarnandpinncottage.co.uk/contact" data-largesrc="/images/cottage-images/entrance/image-entrance-2.jpg" data-title="The Entrance" data-description="The Barn and Pinn Cottage">
<img src="/images/cottage-images/entrance/image-entrance-2-thumb.jpg" alt="img01"/>
</a>
</li>
<li>
<a href="http://www.thebarnandpinncottage.co.uk/contact" data-largesrc="/images/cottage-images/entrance/image-entrance-3.jpg" data-title="The Entrance" data-description="The Barn and Pinn Cottage">
<img src="/images/cottage-images/entrance/image-entrance-3-thumb.jpg" alt="img01"/>
</a>
</li>
<li>
<a href="http://www.thebarnandpinncottage.co.uk/contact" data-largesrc="/images/cottage-images/entrance/image-entrance-4.jpg" data-title="The Entrance" data-description="The Barn and Pinn Cottage">
<img src="/images/cottage-images/entrance/image-entrance-4-thumb.jpg" alt="img01"/>
</a>
</li>
<li>
<a href="http://www.thebarnandpinncottage.co.uk/contact" data-largesrc="/images/cottage-images/entrance/image-entrance-5.jpg" data-title="The Entrance" data-description="The Barn and Pinn Cottage">
<img src="/images/cottage-images/entrance/image-entrance-5-thumb.jpg" alt="img01" name="VCRImage"/>
</a>
</li>
这是CSS...
.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-grid li.og-expanded > a::after {
top: auto;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-bottom-color: #B3BCC6;
border-width: 15px;
left: 50%;
margin: -20px 0 0 -15px;
}
.og-expander {
position: absolute;
background: #B3BCC6;
top: auto;
left: 0;
width: 88.888888%;
margin-top: 10px;
text-align: left;
height: 0;
overflow: hidden;
}
.og-expander-inner {
padding: 80px 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: white;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
}
.og-close::after {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.og-close:hover::before,
.og-close:hover::after {
background: #333;
}
.og-previous {
position: absolute;
width: 40px;
height: 40px;
top: 20px;
right: 200px;
cursor: pointer;
}
.og-previous::before {
content: '<<';
position: absolute;
width: 100%;
top: 50%;
color: white;
}
.og-next {
position: absolute;
width: 40px;
height: 40px;
top: 20px;
right: 100px;
cursor: pointer;
}
.og-next::before {
content: '>>';
position: absolute;
width: 100%;
top: 50%;
color: white;
}
.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: 1.6em;
padding: 0;
margin: 0 0 1em 0;
color: #4B77B1;
}
.og-details p {
font-weight: 400;
font-size: 16px;
line-height: 22px;
color: white;
}
.og-details a {
font-weight: 700;
font-size: 16px;
color: #4B77B1;
text-transform: uppercase;
letter-spacing: 2px;
padding: 10px 20px;
border: 3px solid #4B77B1;
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: white;
color: white;
}
.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;
-webkit-animation: loader 0.5s infinite ease-in-out both;
-moz-animation: loader 0.5s infinite ease-in-out both;
animation: loader 0.5s infinite ease-in-out both;
}
@-webkit-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; }
}
@-moz-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; }
}
@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; }
}