jQuery实现左右切换焦点图
演示图:
代码:
|
$(document).ready( function () { greyInitRedux(); ieDropdownsNav(); ieDropdownsFilter(); itemViewer(); jsTabsetInit(); slider(); headerTabs(); carousel(); emergencyClose(); replyLinks(); adjournLinks(); zebra_strip_rows(); visitor_site_slideshow(); }); var carousel_round = 0; /*------------------------------------------- Grey Initial Values -------------------------------------------*/ function greyInitRedux() { $( "input.filled, textarea.filled" ).focus( function (e){ if ( this .value == this .defaultValue) { $( this ).removeClass( 'filled' ); this .value= '' ; } $( this ).blur( function (f){ if ( this .value == this .defaultValue) { $( this ).addClass( 'filled' ); } else if ( this .value == "" ) { this .value = this .defaultValue; $( this ).addClass( 'filled' ); } }); }) } /*------------------------------------------- IE6 CSS Main Nav Dropdowns -------------------------------------------*/ function ieDropdownsNav() { if (document.all&&document.getElementById) { navRoot = document.getElementById( 'main-nav' ); if (!navRoot) { return false ; } for (i=0; i<navRoot.childNodes.length; i++) { node = navRoot.childNodes[i]; if (node.nodeName== 'LI' ) { node.onmouseover= function () { this .className+= ' over' ; } node.onmouseout= function () { this .className= this .className.replace( ' over' , '' ); } } } } } /*------------------------------------------- IE6 CSS Main Nav Dropdowns -------------------------------------------*/ function ieDropdownsFilter() { if (document.all&&document.getElementById) { navRoot = document.getElementById( 'filter-drop' ); if (!navRoot) { return false ; } for (i=0; i<navRoot.childNodes.length; i++) { node = navRoot.childNodes[i]; if (node.nodeName== 'DIV' ) { node.onmouseover= function () { this .className+= ' over' ; } node.onmouseout= function () { this .className= this .className.replace( ' over' , '' ); } } } } } /*------------------------------------------- View More -------------------------------------------*/ function itemViewer() { //$(document).delegate('#filter-drop a, .expandable > .load, .filter-nav a', 'click', function (e) //$(document).delegate('.expandable > .load, .filter-nav a', 'click', function (e) $(document).delegate( '.filter-nav a' , 'click' , function (e) { // get the src for the content we're trying to view var dataSrc = $( this ).attr('data-src '); // determine whether we' re trying to sort the existing view if ($( this ).attr( 'data-sort' )) { var dataSort = $( this ).attr( 'data-sort' ); } else { var dataSort = $( '.filter-nav > li > a' ).attr( 'data-sort' ); } // how many items do we have? var itemOffset = $( '.expandable .listing > li' ).size(); //find out if we clicked the menu, if so, clear out everything and add data attribute to the load more if ($( this ).closest( 'div' ).hasClass( "filter" )) { var hiddenDiv = $( '<div />' , { "class" : "items hidden spacer" , "height" : $( '.expandable' ).outerHeight() }); $( '.expandable > .load' ).before(hiddenDiv); $( '.expandable > ul, .expandable > div:not(.spacer)' ).remove(); $( '.load' ).attr( 'data-src' ,dataSrc); // Change Class of Dropdown Toggle var clickedClass = $( this ).parent().attr( 'class' ); $( "#filter-drop strong" ).removeClass().addClass(clickedClass); // Change Text of Dropdown Toggle var thisLabel = $( this ).text(); $( "#filter-drop strong span" ).text(thisLabel); // Grab datasrc from clicked-on menu item and populate the filters with it $( '.filter-nav a' ).attr( 'data-src' , dataSrc); $( '.filter-nav li' ).removeClass( 'active' ); $( '.filter-nav > li' ).eq(0).addClass( 'active' ); } //find out if we clicked the filter nav, if so let's switch the active class if ($( this ).closest('ul ').hasClass("filter-nav")) { $(' .filter-nav li ').removeClass(' active '); $(this).parent().addClass(' active '); //Also let' s remove all the items before replacing them with what we want var hiddenDiv = $( '<div />' , { "class" : "items hidden spacer" , "height" : $( '.expandable' ).outerHeight() }); $( '.expandable > .load' ).before(hiddenDiv); $( '.expandable > ul, .expandable > div:not(.spacer)' ).remove(); } $.get(dataSrc, { offset: itemOffset, sort: dataSort }, function (data) { $( '.expandable .spacer' ).remove(); var hiddenDiv = $( '<div class="items hidden"></div>' ); $( '.expandable > .load' ).before(hiddenDiv); $(hiddenDiv).append(data).hide().removeClass( "hidden" ).fadeIn(); }); e.preventDefault(); }); } function jsTabsetInit() { var $tabset = $( '.heading-tabset' ).eq(0); var $tablist = $( '<ul />' , { "class" : "heading-tab" }); $tabset.prepend($tablist); $( 'div.heading-tab h3' ).each( function () { var $anchor = $( '<a />' , { "class" : $( this ).attr( 'class' ), "onClick" : '_gaq.push([\'_trackEvent\', \'Connect\', \'Click\', \'Head' +$( this ).attr( 'class' )+ '\', 3]);' , "href" : "#" , "html" : $( this ).html() }); var $li = $( '<li />' ); $li.append($anchor); $tablist.append($li); }); $( 'div.heading-tab' ).remove(); $( '.heading-tabset:gt(0)' ).each( function () { $tabset.append($( this ).find( '.listing' )); $( this ).remove(); }); } function slider() { $( '.slider' ).each( function () { // As we loop through the slider items we'll document the tallest one and the left position // of each element var maxHeight = 0, lastWidth = 0; // grab the slider and make sure the overflow is hidden and it has a defined width var $slider = $( this ); $slider.css('width ', $slider.outerWidth()); $slider.css(' position ', ' relative '); $slider.css(' overflow ', ' hidden '); // store the index (or the currently "selected" slide) $slider.prop(' index ', 0); // loop through each of the direct children $slider.find(' > * ').each(function() { // localize the child as a jQuery object var $li = $(this); // if this is the tallest child, document it if ($li.outerHeight() > maxHeight) { maxHeight = $li.outerHeight(); } // position each child to the immediate right of its preceding sibling $li.css(' position ', ' absolute '); $li.css(' top ', 0); $li.css(' left ', lastWidth); // update our maths so we know where to place the next sibling lastWidth+= $li.outerWidth(); }); // set the height of the slider based on the tallest child //$slider.css(' height ', maxHeight); // build the previous control button and store a reference to its related slider var $previous = $(' <a /> ', {"class": "prev disabled", "href": "#", "text": "Previous"}); $previous.prop(' slider ', $slider); // build the next control button and store a reference to its related slider var $next = $(' <a /> ', {"class": "next", "href": "#", "text": "Next"}); $next.prop(' slider ', $slider); // build the controls div and add it to the markup var $controls = $(' <div /> ', {"class": "controls"}).append($previous).append($next); $slider.after($controls); $slider.prop(' controls ', $controls); }); // watch for clicks on the controls $(document).delegate(' .listing + .controls .prev, .listing + .controls .next ', ' click ', function (event) { // stop our clicks from affecting the browser/url event.preventDefault(); // localize a jQuery version of the clicked link var $anchor = $(this); // grab the slider, that we previously stored while creating these links var $slider = $anchor.prop(' slider '); // localize the index for prettier code var focusedIndex = $slider.prop(' index '); // determine what slide is focused var $focus = $slider.find(' > * ').eq(focusedIndex); // grab the width of that focused slide var widthDelta = $focus.outerWidth(); // if we clicked the next button we' re moving to the left (negative values, so // multiply by -1). if ($anchor.hasClass( 'next' )) { widthDelta *= -1; } focusedIndex += ($anchor.hasClass( 'next' )) ? 1 : -1; // check that the upcoming movement won't push the first element too far to the right // leaving whitespace before the element if ($slider.find('> * ').eq(0).position().left + widthDelta > 0) { return true; } // check that the upcoming movement won' t push the last element too far to the left // leaving whitespace after the element var $lastChild = $slider.find( '> *' ).eq(-1) if ($lastChild.position().left + widthDelta < $slider.outerWidth() - $lastChild.outerWidth() - 1) { return true ; } // get all the child elements, so we can loop through them and detmine offsets based // on widths var $siblings = $slider.find( '> *' ); // finally loop through each child and kick off the animation $siblings.each( function (index) { // we'll determine the `left` in just a second, sit tight var left = 0; // localize the child element var $li = $( this ); // loop through each sibling and determine the new left if (index < focusedIndex) { left = -$slider.outerWidth(); } if (index >= focusedIndex && index < focusedIndex + 3) { left = 219 * (index - focusedIndex); } if (index >= focusedIndex + 3) { left = $slider.outerWidth() * 2; } // start the animation $li.animate({'left ': left}, 300); // are we at the beginning? if (index == 0 && left == 0) { $slider.prop(' controls ').find(' .prev ').addClass(' disabled '); } else if (index == 0) { $slider.prop(' controls ').find(' .prev ').removeClass(' disabled '); } // are we at the end? if (index == $siblings.size()-1 && left == $slider.outerWidth() - $lastChild.outerWidth() - 1) { $slider.prop(' controls ').find(' .next ').addClass(' disabled '); } else if (index == $siblings.size()-1) { $slider.prop(' controls ').find(' .next ').removeClass(' disabled '); } }); // if we got down here then we actually moved the slider, update the reference to the // focused slide $slider.prop(' index ', focusedIndex); }); } function headerTabs() { var $tabset = $(' .heading-tabset ') $tabset.find(' .listing:gt(0) ').hide(); $tabset.find(' .controls:gt(0) ').hide(); $tabset.find(' .heading-tab li ').eq(0).addClass(' active '); $(document).delegate(' .heading-tab a ', ' click ', function(event) { event.preventDefault(); $(this).parent().addClass(' active '); $(this).parent().siblings().removeClass(' active '); var index = $(this).parent().prevAll(' * ').size(); $(this).parents(' .heading-tabset ').find(' .listing ').hide(); $(this).parents(' .heading-tabset ').find(' .listing ').eq(index).show(); $(this).parents(' .heading-tabset ').find(' .controls ').hide(); $(this).parents(' .heading-tabset ').find(' .controls ').eq(index).show(); }); } function carousel() { $(document).delegate(' .carousel .next, .carousel .previous ', ' click ', function(event) { // prevent the default anchor action event.preventDefault(); // get the current carousel var $carousel = $(this).parents(' .carousel '); // check if we' re already in the middle of a movement if ($carousel.prop( 'moving' )) { return true ; } // if we actually clicked it, then stop any running timers if (event.clientX) { stop($carousel); } // localize the index, so we know where we are var index = $carousel.prop( 'index' ); // determine if we're going forward or backward var movingForward = $( this ).hasClass('next '); // grab all the slides var $slides = $carousel.find(' .carousel-item '); // grab the currently focused slide var $focus = $slides.eq(index); // figure out where' re we going from here var nextObject = movingForward ? nextSlide($carousel, index) : previousSlide($carousel, index); // locaalize the next div to be shown var $next = nextObject.element; // localize the index of the next element to be shown var newIndex = nextObject.index; // determine where we should place the next element so it slides from the correct side var initialLeft = movingForward ? $(document.body).outerWidth() : -$next.outerWidth(); // save the current zero position, everything will move to/from here var zeroPosition = $focus.offset().left; // determine where the focus is moving to var targetLeft = zeroPosition + (movingForward ? -$next.outerWidth() : $next.outerWidth()); // we're comitted to moving now so set the flag to true so we don't duplicate animations $carousel.prop( 'moving' , true ); // reset all z-indexes to 1 $slides.css( 'z-index' , 1); // make the currently focused slide higher than all the rest $focus.css( 'z-index' , 2); // setup the current slide so it can animate out $focus.css({ "position" : "absolute" , "top" : 0, "left" : zeroPosition }); // setup the next slide to slide in, moving it above the focused slide and off screen $next.css({ "opacity" : 0, "position" : "absolute" , "top" : 0, "left" : initialLeft, "z-index" : 3 }); // animate the current slide out $focus.animate({ "opacity" : 0, "left" : targetLeft }, 800); // set up what we're animating var animation = { "opacity" : 1, "left" : zeroPosition } // horrible ie fix if ($.browser.msie && parseInt($.browser.version) <= 8) { delete animation.opacity; $focus.get(0).style.removeAttribute('filter '); $next.get(0).style.removeAttribute(' filter '); } // animate in the next slide, then upon completion reset everything. switch it back to // relative positioning, remove our animation flag and hide the previous element $next.show().animate(animation, 800, function() { $focus.hide(); $(this).css({ "position": "relative", "left": 0 }); // fix msie if ($.browser.msie && parseInt($.browser.version) <= 8) { this.style.removeAttribute(' filter '); } $carousel.prop(' moving ', false); }); // animate the height of our carousel, because things are abosulte the box model is shot $carousel.animate({ //"min-height": $next.outerHeight() }); // finally update our index to reflect the current view $carousel.prop(' index ', newIndex); }); $(document).delegate(' .carousel .pause ', ' click ', function(event) { // prevent the default anchor action event.preventDefault(); // localize the carousel var $carousel = $(this).parents(' .carousel '); // get the current timer, if it exists var timer = $carousel.prop(' timer '); // no timer? start it if (!timer) { start($carousel); } // timer? stop it else { stop($carousel); } }); // start a new timer, additionally update the play/pause button to the correct visual state function start($carousel) { timer = setInterval(function() { $carousel.find(' .next ').eq(0).trigger(' click '); //N.C.: added to stop carousel after one round. var index = $carousel.prop(' index '); if ( index==0 && carousel_round > 0 ) { stop($carousel); } else if ( index==1 ) { carousel_round++; } }, 5000); $carousel.prop(' timer ', timer); $carousel.find(' .play.pause ').removeClass(' play '); } // stop any existing timers, additionally update the play/pause button to the correct // visual state function stop($carousel) { clearInterval(timer); $carousel.prop(' timer ', false); $carousel.find(' .pause ').addClass(' play '); //N.C.: added to stop carousel after one round. carousel_round = 0; } function nextSlide($carousel, index) { var $slides = $carousel.find(' .carousel-item '); if (index+1 < $slides.size()) { return {"index":index+1, "element":$slides.eq(index+1)}; } return {"index":0, "element":$slides.eq(0)}; } function previousSlide($carousel, index) { var $slides = $carousel.find(' .carousel-item '); if (index-1 >= 0) { return {"index":index-1, "element":$slides.eq(index-1)}; } return {"index":$slides.size()-1, "element":$slides.eq(-1)}; } // build the controls for inclusion into the page var $previousBtn = $(' <a /> ', {"class": "previous", "href": "#", "text": "Previous"}); var $playPauseBtn = $(' <a /> ', {"class": "play pause", "href": "#", "text": "Play/Pause"}); var $nextBtn = $(' <a /> ', {"class": "next", "href": "#", "text": "Next"}); var $controlsDiv = $(' <div /> ', {"class": "carousel-controls"}); $controlsDiv.append($previousBtn); $controlsDiv.append($playPauseBtn); $controlsDiv.append($nextBtn); // loop through each carousel and set some default properties/styles $(' .carousel ').each(function() { // localize the carousel to this function var $carousel = $(this); // set the positioning and a default height, becuase we' re going to be taken out of the // flow once our animation starts $carousel.css({ "position" : "relative" //"min-height": $carousel.find('.carousel-item').eq(0).outerHeight() //N.C. commented out }); // store the currently visible slide's index $carousel.prop('index ', 0); // hide subsequent slides $carousel.find(' .carousel-item:gt(0) ').hide(); // append in our controls $carousel.prepend($controlsDiv.clone(true)); // add the previous/next images $carousel.find(' .main-image ').each(function(index) { // get the previous image var $prevImage = $(previousSlide($carousel, index).element).find(' .main-image ').clone(); // remove the class $prevImage.removeClass(' main-image '); // create a link for the previous image var $previousAnchor = $(' <a /> ', { "href": "#", "class": "prev-image", "html": $prevImage }); $previousAnchor.css(' opacity ', 0.2); // add in the previous image/anchor $(this).before($previousAnchor); // get the next image var $nextImage = $(nextSlide($carousel, index).element).find(' .main-image ').clone(); // remove the class $nextImage.removeClass(' main-image '); // create a link for the previous image var $nextAnchor = $(' <a /> ', { "href": "#", "class": "next-image", "html": $nextImage }); $nextAnchor.css(' opacity ', 0.2); // add in the next image/anchor $(this).after($nextAnchor); }); // start the carousel by default start($carousel); }); } function emergencyClose() { //$(' .emergency .wrap ').append(' <a href= "#" class= "close" >Close</a> '); $(document).delegate(' .emergency .close ', ' click ', function(event) { event.preventDefault(); $(this).parents(' .emergency ').remove(); }); } function replyLinks() { //$close = $(' <a /> ', {"class": "close", "href": "#", "text": "Close"}); $twitterWrap = $(' <div /> ', {"id": "twitter-wrap"}); //$twitterWrap.append($close); $twitter = $(' <div /> ', {"id": "twitter"}); $twitterWrap.append($twitter); $(document.body).append($twitterWrap); /*twttr.anywhere(function (T) { T("#twitter").tweetBox({ "width": 515, "height": 133, "defaultContent": "", "onTweet": function() { $("#twitter-wrap").fadeOut(' fast '); $(' #overlay').fadeOut(); $(' #overlay').remove(); _gaq.push(['trackEvent ', ' Home ', ' SubmitReply ', ' TwitterReply ', 5]); //$twitter.remove(); } }); });*/ $(document).delegate(' .link-reply ', ' click ', function(event) { event.preventDefault(); //if ( !$(' #overlay') ) { $(document.body).prepend($('<div /> ', {"id": "overlay"})); //} $(' #overlay').fadeIn(); $( "#twitter-wrap" ).css({ "position" : "fixed" , "top" : 200, "left" : ($(document.body).width()-515)/2 }); if ($.browser == 'msie ') { $("#twitter-wrap").css({ "position": "absolute", "top": $(document.body).scrollTop() + 200 }); } $("#twitter-wrap").fadeIn(' fast '); }); $(document).delegate(' #overlay, #twitter-wrap .close', 'click', function(event) { event.preventDefault(); $(' #twitter-wrap').fadeOut('fast'); $(' #overlay').fadeOut('fast', function() { $( this ).remove(); }) }); } function adjournLinks() { $('.adjoin-options ').each(function() { var headings = []; $(this).find(' *[data-heading] ').each(function() { headings[$(this).attr(' data-heading ')] = $(this).attr(' data-heading '); }); var $headings = $(' <ul /> ', { "class": "adjoin-header" }); for (var heading in headings) { var $li = $(' <li /> '); var $a = $(' <a /> ', { "href": "#", "onClick": ' _gaq.push([\ '_trackEvent\', \'SocialDirectory\', \'Click\', \'Head' +heading+ '\', 3]);' , "data-show" : heading, "text" : heading }) $li.append($a); $headings.append($li); } $( this ).before($headings); }); $(document).delegate( 'a[data-show]' , 'click' , function (event) { // stop the default click action event.preventDefault(); // set active $( this ).parent().siblings().find( '.active' ).removeClass( 'active' ); $( this ).addClass( 'active' ); // find the appropriate elements $( '.adjoin-options *[data-heading]' ).hide(); $( '.adjoin-options *[data-heading="' +$( this ).attr( 'data-show' )+ '"].' ).fadeIn(); }); $( '.adjoin-header' ).find( 'a[data-show]' ).eq(0).trigger( 'click' ); } $(document).ready( function () { var $filter = $( '#filter-drop' ); var $filterSpacer = $( '<div />' , { "class" : "filter-drop-spacer" , "height" : $filter.outerHeight() }); var $homeShield = $( '.home .primary' ); var $totalHeight = $( '.carousel' ).outerHeight() + $( '.header' ).outerHeight() if ($filter.size()) { $(window).scroll( function () { if ($(window).scrollTop() > $totalHeight ) { $homeShield.addClass( "shieldfix" ); } else if ($homeShield.hasClass( 'shieldfix' ) && $(window).scrollTop() < $totalHeight) { $homeShield.removeClass( "shieldfix" ); } if (!$filter.hasClass( 'fix' ) && $(window).scrollTop() > $filter.offset().top) { $filter.css( 'width' , $filter.width()); $filter.before($filterSpacer); $filter.addClass( "fix" ); } else if ($filter.hasClass( 'fix' ) && $(window).scrollTop() < $filterSpacer.offset().top) { $filter.removeClass( "fix" ); $filterSpacer.remove(); } }); } }); function get_more_home_items() { if ( views_left>0 ) { jQuery( "#home_items_loading" ).show(); jQuery.ajax({ type: 'POST' , url: 'ajax/home_items' , data: 'timestamp=' +curr_timestamp+ '&index=' +views_left, dataType: 'json' , success: function (data) { jQuery( "#home_items_loading" ).hide(); jQuery( "#home_content" ).append(data.html); curr_timestamp=data.timestamp; } }); views_left--; } var click_index = 2-views_left; _gaq.push([ '_trackEvent' , 'ViewMoreChannels' , 'Click' , 'ViewMore_' +click_index.toString(), 3]); if ( views_left<=0 ) { jQuery( "#view_more" ).hide(); } } /*------------------------------------------- Add Zebra Strip Rows of table with class "stripe" -- Chris Traganos -------------------------------------------*/ function zebra_strip_rows() { $( "table.stripe tr:odd" ).addClass( "odd" ); $( "table.stripe tr:even" ).addClass( "even" ); } function visitor_site_slideshow() { /* $('.visitors_slideshow').cycle({ fx: 'fade' // choose your transition type, ex: fade, scrollUp, shuffle, etc... }); */ } |
以上所述就是本文的全部内容了,希望大家能够喜欢。