Skip to content

Instantly share code, notes, and snippets.

@danomanion
Last active December 14, 2015 23:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danomanion/5168818 to your computer and use it in GitHub Desktop.
Save danomanion/5168818 to your computer and use it in GitHub Desktop.
jQuery for Designers code examples for future reference.
Code examples from book.
http://my.safaribooksonline.com/book/-/9781849516709
<!doctype html>
<head>
<!-- CSS -->
<link rel="stylesheet" href=""/>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
//externalLinks();
});
/* Open up a link in a new window using a class to define such */
//function externalLinks() {}
</script>
<style>
#ajax-header { margin: 40px 0 0 0; }
#ajax-header h1 { color:#859900;margin:0 0 10px 0;padding:0; }
#ajax-nav { background:#859900;margin:0;padding:0;overflow:hidden;zoom:1; }
#ajax-nav li { list-style-type:none;margin:0;padding:10px 20px;display:block;float:left; }
#ajax-nav a,
#ajax-nav a:link,
#ajax-nav a:visited { color: #eee8d5; }
#ajax-nav a:hover,
#ajax-nav a:active { color: #fff; }
#main-col { float:left;width:60%; }
#side-col { float:right;width:35%; }
.widget { border:2px solid #859900;margin:10px 0; }
.widget h4 { margin:0 0 10px 0;padding:10px;background:#859900;color:#FDF6E3; }
.float-right { float:right;margin:0 0 10px 10px; }
.float-left { float:left;margin:0 10px 10px 0; }
.source { font-size:12px; }
#ajax-foot { clear:both;margin:10px 0 40px 0;padding:5px;background:#859900;color:#f3f6e3; }
#ajax-foot p { margin:0;padding:0;font-size:12px;}
</style>
</head>
<body>
<div id="ajax-header">
<h1>Miniature Treats</h1>
<ul id="ajax-nav">
<li><a href ="index.html">Home</a></li>
<li><a href ="cupcakes.html">Cupcakes</a></li>
<li><a href ="petitfours.html">Petits Fours</a></li>
<li><a href ="teacakes.html">Tea Cakes</a></li>
<li><a href ="muffins.html">Muffins</a></li>
</ul>
</div>
<div id="main-col">
<div id="main-col-wrap">
<h2>Cupcakes</h2>
<p><img src="images/cupcakes.jpg" class="float-right" alt="Photo of cupcakes"/>A cupcake is a small cake designed to serve one person, frequently baked in a small, thin paper or aluminum cup. As with larger cakes, frosting and other cake decorations, such as sprinkles, are common on cupcakes.</p>
<p>Although their origin is unknown, recipes for cupcakes have been printed since at least the late 18th century.</p>
<p>The first mention of the cupcake can be traced as far back as 1796, when a recipe notation of "a cake to be baked in small cups" was written in <em>American Cookery</em> by Amelia Simms. The earliest documentation of the term <em>cupcake</em> was in "Seventy-five Receipts for Pastry, Cakes, and Sweetmeats" in 1828 in Eliza Leslie's <em>Receipts</em> cookbook.</p>
<p class="source">Text source: <a href="http://en.wikipedia.org/wiki/Cupcakes">Wikipedia</a><br/>Image source: <a href="http://flickr.com/people/10506540@N07">Steven Depolo</a> via <a href="http://commons.wikimedia.org/wiki/File:Blue_cupcakes_for_graduation,_closeup_-_Tiffany,_May_2008.jpg">Wikimedia Commons</a></p>
</div></div>
<div id="side-col">
<div class="widget">
<h4>More Information</h4>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Cupcakes">Cupcakes (Wikipedia)</a></li>
<li><a href="http://en.wikipedia.org/wiki/Petit_fours">Petits Fours (Wikipedia)</a></li>
<li><a href="http://en.wikipedia.org/wiki/Tea_cake">Tea Cakes (Wikipedia)</a></li>
<li><a href="http://en.wikipedia.org/wiki/Muffins">Muffins (Wikipedia)</a></li>
</ul>
</div>
<div class="widget">
<h4>Also Delicious</h4>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Banana_bread">Banana Bread</a></li>
<li><a href="http://en.wikipedia.org/wiki/Pumpkin_bread">Pumpkin Bread</a></li>
<li><a href="http://en.wikipedia.org/wiki/Swiss_roll">Swiss Roll</a></li>
<li><a href="http://en.wikipedia.org/wiki/Cheesecake">Cheesecake</a></li>
<li><a href="http://en.wikipedia.org/wiki/Bundt_cake">Bundt Cake</a></li>
</ul>
</div>
</div>
<div id="ajax-foot">
<p>Sample of progressively enhanced asynchronous navigation</p>
</div>
</body>
</html>
<!doctype html>
<head>
<!-- CSS -->
<link rel="stylesheet" href=""/>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#ajax-nav a').bind('click', function() {
var url = $(this).attr('href');
$('#main-col').load(url + ' #main-col-wrap');
return false;
});
//externalLinks();
});
/* Open up a link in a new window using a class to define such */
//function externalLinks() {}
</script>
<style>
#ajax-header { margin: 40px 0 0 0; }
#ajax-header h1 { color:#859900;margin:0 0 10px 0;padding:0; }
#ajax-nav { background:#859900;margin:0;padding:0;overflow:hidden;zoom:1; }
#ajax-nav li { list-style-type:none;margin:0;padding:10px 20px;display:block;float:left; }
#ajax-nav a,
#ajax-nav a:link,
#ajax-nav a:visited { color: #eee8d5; }
#ajax-nav a:hover,
#ajax-nav a:active { color: #fff; }
#main-col { float:left;width:60%; }
#side-col { float:right;width:35%; }
.widget { border:2px solid #859900;margin:10px 0; }
.widget h4 { margin:0 0 10px 0;padding:10px;background:#859900;color:#FDF6E3; }
.float-right { float:right;margin:0 0 10px 10px; }
.float-left { float:left;margin:0 10px 10px 0; }
.source { font-size:12px; }
#ajax-foot { clear:both;margin:10px 0 40px 0;padding:5px;background:#859900;color:#f3f6e3; }
#ajax-foot p { margin:0;padding:0;font-size:12px;}
</style>
</head>
<body>
<div id="ajax-header">
<h1>Miniature Treats</h1>
<ul id="ajax-nav">
<li><a href ="index.html">Home</a></li>
<li><a href ="asynchronous-nav-page-cupcakes.html">Cupcakes</a></li>
<li><a href ="asynchronous-nav-page-cupcakes.html">Petits Fours</a></li>
<li><a href ="asynchronous-nav-page-cupcakes.html">Tea Cakes</a></li>
<li><a href ="asynchronous-nav-page-cupcakes.html">Muffins</a></li>
</ul>
</div>
<div id="main-col">
<div id="main-col-wrap">
<p>Welcome to the miniature treats roundup. We've got a variety of miniature goodies to share with you.</p>
<p>Don't be shy - just dive right in. Your mouth will water with the possibilites.</p>
<p>If it's tiny enough to be a single portion all on it's own, we've included it here.</p>
</div>
</div>
<div id="side-col">
<div class="widget">
<h4>More Information</h4>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Cupcakes">Cupcakes (Wikipedia)</a></li>
<li><a href="http://en.wikipedia.org/wiki/Petit_fours">Petits Fours (Wikipedia)</a></li>
<li><a href="http://en.wikipedia.org/wiki/Tea_cake">Tea Cakes (Wikipedia)</a></li>
<li><a href="http://en.wikipedia.org/wiki/Muffins">Muffins (Wikipedia)</a></li>
</ul>
</div>
<div class="widget">
<h4>Also Delicious</h4>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Banana_bread">Banana Bread</a></li>
<li><a href="http://en.wikipedia.org/wiki/Pumpkin_bread">Pumpkin Bread</a></li>
<li><a href="http://en.wikipedia.org/wiki/Swiss_roll">Swiss Roll</a></li>
<li><a href="http://en.wikipedia.org/wiki/Cheesecake">Cheesecake</a></li>
<li><a href="http://en.wikipedia.org/wiki/Bundt_cake">Bundt Cake</a></li>
</ul>
</div>
</div>
<div id="ajax-foot">
<p>Sample of progressively enhanced asynchronous navigation</p>
</div>
</body>
</html>
<!doctype html>
<head>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
/* Append Text to body */
$('body').append('<p>This is a page powered by jQuery</p>');
/* FadeIn red Canvas */
$('img').fadeIn('slow');
});
</script>
</head>
<body>
<h1>Hello World!</h1>
<p>Thanks to jQuery doing fancy JavaScript stuff is easy!.</p>
<img id="red-canvas" src="http://stardate.org/sites/default/files/imagecache/product/images/gallery/11%2001%2003.jpg" />
</body>
</html>
<!doctype html>
<head>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
//Functions
dynamicFaq();
});
/* Javacript */
function dynamicFaq() {
$('dd').hide();
$('dt').bind('click', function() {
$(this).toggleClass('open').next().slideToggle();
});
}
</script>
<style>
/* CSS */
dt {
color: #268bd2;
font-weight: bold;
cursor: pointer;
margin: 0 0 1em 0;
}
dt:hover {
color: #2aa198;
}
.open {
background-color: gold;
}
</style>
</head>
<body>
<h1>Frequently Asked Questions</h1>
<dl>
<dt>What is jQuery?</dt>
<dd>
<p>jQuery is an awesome JavaScript library</p>
</dd>
<dt>Why should I use jQuery?</dt> <dd>
<p>Because it's awesome and it makes writing JavaScript faster and easier</p>
</dd>
<dt>Why would I want to hide the answers to my questions? </dt>
<dd>
<p>To make it easier to peruse the list of available questions - then you simply click to see the answer you're interested in reading.</p>
</dd>
<dt>What if my answers were a lot longer and more complicated than these examples?</dt>
<dd>
<p>The great thing about the &lt;dd&gt; element is that it's a block level element that can contain lots of other elements.</p>
<p>That means your answer could contain:</p>
<ul>
<li>Unordered</li>
<li>Lists</li>
<li>with lots</li>
<li>of items</li>
<li>(or ordered lists or even another definition list)</li>
</ul>
<p>Or it might contain text with lots of <strong>special</strong> <em>formatting</em>.</p>
<h2>Other things</h2>
<p>It can even contain headings. Your answers could take up an entire screen or more all on their own - it doesn't matter since the answer will be hidden until the user wants to see it.</p>
</dd>
<dt>What if a user doesn't have JavaScript enabled?</dt>
<dd>
<p>You have two options for users with JavaScript disabled - which you choose might depend on the content of your page.</p>
<p>You might just leave the page as it is - and make sure the &lt;dt&gt; tags are styled in a way that makes them stand out and easy to pick up when you're scanning down through the page. This would be a great solution if your answers are relatively short.</p>
<p>If your FAQ page has long answers, it might be helpful to put a table of contents list of links to individual questions at the top of the page so users can click it to jump directly to the question and answer they're interested in. This is similar to what we did in the tabbed example, but in this case, we would use jQuery to hide the table of contents when the page loaded since users with JavaScript wouldn't need to see the table of contents.</p>
</dd>
</dl>
</body>
</html>
/*
ColorBox Core Style:
The following CSS is consistent between example themes and should not be altered.
*/
#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
#cboxOverlay{position:fixed; width:100%; height:100%;}
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
#cboxContent{position:relative;}
#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
#cboxTitle{margin:0;}
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;}
.cboxIframe{width:100%; height:100%; display:block; border:0;}
#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
/*
User Style:
Change the following styles to modify the appearance of ColorBox. They are
ordered & tabbed in a way that represents the nesting of the generated HTML.
*/
#cboxOverlay{background:url(http://www.jacklmoore.com/colorbox/example1/images/overlay.png) repeat 0 0;}
#colorbox{outline:0;}
#cboxTopLeft{width:21px; height:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) no-repeat -101px 0;}
#cboxTopRight{width:21px; height:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) no-repeat -130px 0;}
#cboxBottomLeft{width:21px; height:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) no-repeat -101px -29px;}
#cboxBottomRight{width:21px; height:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) no-repeat -130px -29px;}
#cboxMiddleLeft{width:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) left top repeat-y;}
#cboxMiddleRight{width:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) right top repeat-y;}
#cboxTopCenter{height:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/border.png) 0 0 repeat-x;}
#cboxBottomCenter{height:21px; background:url(http://www.jacklmoore.com/colorbox/example1/images/border.png) 0 -29px repeat-x;}
#cboxContent{background:#fff; overflow:hidden;}
.cboxIframe{background:#fff;}
#cboxError{padding:50px; border:1px solid #ccc;}
#cboxLoadedContent{margin-bottom:28px;}
#cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;}
#cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;}
#cboxLoadingOverlay{background:url(http://www.jacklmoore.com/colorbox/example1/images/loading_background.png) no-repeat center center;}
#cboxLoadingGraphic{background:url(http://www.jacklmoore.com/colorbox/example1/images/loading.gif) no-repeat center center;}
/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
#cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
#cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
#cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;}
#cboxPrevious{position:absolute; bottom:0; left:0; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;}
#cboxPrevious:hover{background-position:-75px -25px;}
#cboxNext{position:absolute; bottom:0; left:27px; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;}
#cboxNext:hover{background-position:-50px -25px;}
#cboxClose{position:absolute; bottom:0; right:0; background:url(http://www.jacklmoore.com/colorbox/example1/images/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}
#cboxClose:hover{background-position:-25px -25px;}
/*
The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9.
See: http://jacklmoore.com/notes/ie-transparency-problems/
*/
.cboxIE #cboxTopLeft,
.cboxIE #cboxTopCenter,
.cboxIE #cboxTopRight,
.cboxIE #cboxBottomLeft,
.cboxIE #cboxBottomCenter,
.cboxIE #cboxBottomRight,
.cboxIE #cboxMiddleLeft,
.cboxIE #cboxMiddleRight {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
}
/*
The following provides PNG transparency support for IE6
Feel free to remove this and the /ie6/ directory if you have dropped IE6 support.
*/
.cboxIE6 #cboxTopLeft{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderTopLeft.png);}
.cboxIE6 #cboxTopCenter{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderTopCenter.png);}
.cboxIE6 #cboxTopRight{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderTopRight.png);}
.cboxIE6 #cboxBottomLeft{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderBottomLeft.png);}
.cboxIE6 #cboxBottomCenter{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderBottomCenter.png);}
.cboxIE6 #cboxBottomRight{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderBottomRight.png);}
.cboxIE6 #cboxMiddleLeft{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderMiddleLeft.png);}
.cboxIE6 #cboxMiddleRight{background:url(http://www.jacklmoore.com/colorbox/example1/images/ie6/borderMiddleRight.png);}
.cboxIE6 #cboxTopLeft,
.cboxIE6 #cboxTopCenter,
.cboxIE6 #cboxTopRight,
.cboxIE6 #cboxBottomLeft,
.cboxIE6 #cboxBottomCenter,
.cboxIE6 #cboxBottomRight,
.cboxIE6 #cboxMiddleLeft,
.cboxIE6 #cboxMiddleRight {
_behavior: expression(this.src = this.src ? this.src : this.currentStyle.backgroundImage.split('"')[1], this.style.background = "none", this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + this.src + ", sizingMethod='scale')");
}
<!doctype html>
<head>
<title>Custom Scrollbars</title>
<link rel="stylesheet" href="jquery.jscrollpane.css">
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="jquery.mousewheel.js"></script>
<script src="jquery.jscrollpane.min.js"></script>
<script src="mwheelIntent.js"></script>
<script>
$(document).ready(function() {
//Functions
//function();
$('#scrolling').jScrollPane({
showArrows:true,
verticalGutter:30,
hijackInternalLinks: true,
animateScroll: true
});
});
/* Javacript */
//function functionName() {}
</script>
<style>
/* CSS */
#scrolling {
width:500px;
height:300px;
overflow:auto;
}
.jspTrack
{
background: #dde;
position: relative;
}
.jspTrack
{
background: #fbebf3;
position: relative;
}
.jspDrag
{
background: #D33682;
position: relative;
top: 0;
left: 0;
cursor: pointer;
}
.jspArrow
{
text-indent: -20000px;
display: block;
cursor: pointer;
}
.jspArrow.jspDisabled
{
cursor: default;
background-color: #999;
}
.jspArrowUp
{
background: #d6448b url(../images/arrows.png) 0 0 no-repeat; /* images arn't included */
}
.jspArrowDown
{
background: #d6448b url(../images/arrows.png) 0 -16px no-repeat; /* images arn't included */
}
</style>
</head>
<body>
<h2>We don't want this box of content to get too long, so we'll make it scroll:</h2>
<p>Scroll to a paragraph:
<a href="#para1">1</a>,
<a href="#para2">2</a>,
<a href="#para3">3</a>,
<a href="#para4">4</a>,
<a href="#para5">5</a>
</p>
<div id="scrolling">
<p id="para1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eget nunc et erat volutpat volutpat. Suspendisse imperdiet blandit eleifend. Quisque facilisis scelerisque mollis. Donec dictum ipsum non enim suscipit a porttitor diam sodales. In eget massa tortor, id imperdiet urna. Nunc quis est a nulla adipiscing facilisis. Fusce vitae libero purus. Suspendisse nisi sapien, sollicitudin id semper nec, placerat quis odio.</p>
<p id="para2">Morbi tempor quam eget lacus tempus eu rhoncus diam fringilla. Ut aliquam ullamcorper sapien, non scelerisque tellus fringilla feugiat. Donec in euismod magna. Duis in viverra neque. In porttitor sem id nisl scelerisque adipiscing. Nam a posuere nisi. Nullam pretium leo id purus vehicula gravida aliquam nisi iaculis. Nunc interdum, orci in luctus scelerisque, nunc orci adipiscing libero, sed mattis orci massa ac nulla. Cras suscipit, magna eu semper bibendum, libero ligula molestie diam, a laoreet nunc tellus in dui. Fusce a metus nec sem luctus volutpat. Morbi sodales magna in arcu ullamcorper rhoncus. Donec lacus erat, volutpat sed accumsan ac, blandit id nunc. Nunc dolor ipsum, feugiat vel tempor vitae, adipiscing ut libero.</p>
<p id="para3">Integer eu massa dolor, vitae ultricies nulla. Nam vitae mauris eu magna tincidunt tristique sed vel lectus. Vestibulum sed nunc nibh, ut sagittis justo. Proin hendrerit, felis ac varius viverra, velit nunc semper velit, nec congue ante tortor vitae quam. Pellentesque sed eros sit amet nunc dignissim varius ut vel lectus. Phasellus tempor pretium mollis. Proin euismod aliquet sapien id consequat.</p>
<p id="para4">Sed suscipit lectus at turpis pellentesque in tincidunt leo aliquet. Nulla sodales consectetur convallis. Cras in mattis lacus. Phasellus vestibulum placerat condimentum. Aliquam tincidunt, nibh quis suscipit scelerisque, nunc neque pellentesque ligula, nec elementum libero ipsum non mauris. Vestibulum placerat libero vel ligula posuere laoreet sed in nisi. Vivamus eget nisi nec nisi pulvinar mollis. Pellentesque egestas sapien sed arcu commodo ornare. Ut sed dui dolor, vitae rhoncus mi. Vivamus vulputate ullamcorper dui, et feugiat elit mollis at. Nullam sodales interdum facilisis. Aenean facilisis mauris et arcu congue ut scelerisque lectus porta. Phasellus quis dictum turpis. Suspendisse rutrum elementum pellentesque. Pellentesque bibendum nisi sit amet quam tempor interdum. Fusce malesuada, ipsum eget tincidunt molestie, justo lacus eleifend elit, quis rhoncus sem turpis a nunc.</p>
<p id="para5">Ut sed tortor nibh. Aliquam posuere posuere ligula, eu pretium metus porttitor non. Quisque tempor vulputate tellus, ac placerat massa sollicitudin sit amet. Proin at turpis nisl, id tempus velit. Sed rhoncus tellus in nunc congue in tincidunt lacus tincidunt. Aenean faucibus lobortis nunc, eget commodo ante tincidunt sit amet. Ut vestibulum mattis molestie. Vestibulum a tellus lectus, rhoncus ullamcorper ante. Sed et elementum nisi.</p>
</div>
</body>
</html>
/**
* hoverIntent is similar to jQuery's built-in "hover" method except that
* instead of firing the handlerIn function immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the event. The handlerOut function is only
* called after a matching handlerIn.
*
* hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+
* http://cherne.net/brian/resources/jquery.hoverIntent.html
*
* You may use hoverIntent under the terms of the MIT license. Basically that
* means you are free to use hoverIntent as long as this header is left intact.
* Copyright 2007, 2013 Brian Cherne
*
* // basic usage ... just like .hover()
* .hoverIntent( handlerIn, handlerOut )
* .hoverIntent( handlerInOut )
*
* // basic usage ... with event delegation!
* .hoverIntent( handlerIn, handlerOut, selector )
* .hoverIntent( handlerInOut, selector )
*
* // using a basic configuration object
* .hoverIntent( config )
*
* @param handlerIn function OR configuration object
* @param handlerOut function OR selector for delegation OR undefined
* @param selector selector OR undefined
* @author Brian Cherne <brian(at)cherne(dot)net>
**/
(function($) {
$.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
// default configuration values
var cfg = {
interval: 100,
sensitivity: 7,
timeout: 0
};
if ( typeof handlerIn === "object" ) {
cfg = $.extend(cfg, handlerIn );
} else if ($.isFunction(handlerOut)) {
cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
} else {
cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
}
// instantiate variables
// cX, cY = current X and Y position of mouse, updated by mousemove event
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
var cX, cY, pX, pY;
// A private function for getting mouse position
var track = function(ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// A private function for comparing current and previous mouse position
var compare = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
$(ob).off("mousemove.hoverIntent",track);
// set hoverIntent state to true (so mouseOut can be called)
ob.hoverIntent_s = 1;
return cfg.over.apply(ob,[ev]);
} else {
// set previous coordinates for next time
pX = cX; pY = cY;
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
}
};
// A private function for delaying the mouseOut function
var delay = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
return cfg.out.apply(ob,[ev]);
};
// A private function for handling mouse 'hovering'
var handleHover = function(e) {
// copy objects to be passed into t (required for event object to be passed in IE)
var ev = jQuery.extend({},e);
var ob = this;
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
// if e.type == "mouseenter"
if (e.type == "mouseenter") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX; pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).on("mousemove.hoverIntent",track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
// else e.type == "mouseleave"
} else {
// unbind expensive mousemove event
$(ob).off("mousemove.hoverIntent",track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
}
};
// listen for mouseenter and mouseleave
return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
};
})(jQuery);
/*!
* jQuery BBQ: Back Button & Query Library - v1.3pre - 8/26/2010
* http://benalman.com/projects/jquery-bbq-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
// Script: jQuery BBQ: Back Button & Query Library
//
// *Version: 1.3pre, Last updated: 8/26/2010*
//
// Project Home - http://benalman.com/projects/jquery-bbq-plugin/
// GitHub - http://github.com/cowboy/jquery-bbq/
// Source - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.js
// (Minified) - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.min.js (2.2kb gzipped)
//
// About: License
//
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
//
// About: Examples
//
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
//
// Basic AJAX - http://benalman.com/code/projects/jquery-bbq/examples/fragment-basic/
// Advanced AJAX - http://benalman.com/code/projects/jquery-bbq/examples/fragment-advanced/
// jQuery UI Tabs - http://benalman.com/code/projects/jquery-bbq/examples/fragment-jquery-ui-tabs/
// Deparam - http://benalman.com/code/projects/jquery-bbq/examples/deparam/
//
// About: Support and Testing
//
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
//
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
// Unit Tests - http://benalman.com/code/projects/jquery-bbq/unit/
//
// About: Release History
//
// 1.3pre - (8/26/2010) Integrated <jQuery hashchange event> v1.3, which adds
// document.title and document.domain support in IE6/7, BlackBerry
// support, better Iframe hiding for accessibility reasons, and the new
// <jQuery.fn.hashchange> "shortcut" method. Added the
// <jQuery.param.sorted> method which reduces the possibility of
// extraneous hashchange event triggering. Added the
// <jQuery.param.fragment.ajaxCrawlable> method which can be used to
// enable Google "AJAX Crawlable mode."
// 1.2.1 - (2/17/2010) Actually fixed the stale window.location Safari bug from
// <jQuery hashchange event> in BBQ, which was the main reason for the
// previous release!
// 1.2 - (2/16/2010) Integrated <jQuery hashchange event> v1.2, which fixes a
// Safari bug, the event can now be bound before DOM ready, and IE6/7
// page should no longer scroll when the event is first bound. Also
// added the <jQuery.param.fragment.noEscape> method, and reworked the
// <hashchange event (BBQ)> internal "add" method to be compatible with
// changes made to the jQuery 1.4.2 special events API.
// 1.1.1 - (1/22/2010) Integrated <jQuery hashchange event> v1.1, which fixes an
// obscure IE8 EmulateIE7 meta tag compatibility mode bug.
// 1.1 - (1/9/2010) Broke out the jQuery BBQ event.special <hashchange event>
// functionality into a separate plugin for users who want just the
// basic event & back button support, without all the extra awesomeness
// that BBQ provides. This plugin will be included as part of jQuery BBQ,
// but also be available separately. See <jQuery hashchange event>
// plugin for more information. Also added the <jQuery.bbq.removeState>
// method and added additional <jQuery.deparam> examples.
// 1.0.3 - (12/2/2009) Fixed an issue in IE 6 where location.search and
// location.hash would report incorrectly if the hash contained the ?
// character. Also <jQuery.param.querystring> and <jQuery.param.fragment>
// will no longer parse params out of a URL that doesn't contain ? or #,
// respectively.
// 1.0.2 - (10/10/2009) Fixed an issue in IE 6/7 where the hidden IFRAME caused
// a "This page contains both secure and nonsecure items." warning when
// used on an https:// page.
// 1.0.1 - (10/7/2009) Fixed an issue in IE 8. Since both "IE7" and "IE8
// Compatibility View" modes erroneously report that the browser
// supports the native window.onhashchange event, a slightly more
// robust test needed to be added.
// 1.0 - (10/2/2009) Initial release
(function($,window){
'$:nomunge'; // Used by YUI compressor.
// Some convenient shortcuts.
var undefined,
aps = Array.prototype.slice,
decode = decodeURIComponent,
// Method / object references.
jq_param = $.param,
jq_param_sorted,
jq_param_fragment,
jq_deparam,
jq_deparam_fragment,
jq_bbq = $.bbq = $.bbq || {},
jq_bbq_pushState,
jq_bbq_getState,
jq_elemUrlAttr,
special = $.event.special,
// Reused strings.
str_hashchange = 'hashchange',
str_querystring = 'querystring',
str_fragment = 'fragment',
str_elemUrlAttr = 'elemUrlAttr',
str_href = 'href',
str_src = 'src',
// Reused RegExp.
re_params_querystring = /^.*\?|#.*$/g,
re_params_fragment,
re_fragment,
re_no_escape,
ajax_crawlable,
fragment_prefix,
// Used by jQuery.elemUrlAttr.
elemUrlAttr_cache = {};
// A few commonly used bits, broken out to help reduce minified file size.
function is_string( arg ) {
return typeof arg === 'string';
};
// Why write the same function twice? Let's curry! Mmmm, curry..
function curry( func ) {
var args = aps.call( arguments, 1 );
return function() {
return func.apply( this, args.concat( aps.call( arguments ) ) );
};
};
// Get location.hash (or what you'd expect location.hash to be) sans any
// leading #. Thanks for making this necessary, Firefox!
function get_fragment( url ) {
return url.replace( re_fragment, '$2' );
};
// Get location.search (or what you'd expect location.search to be) sans any
// leading #. Thanks for making this necessary, IE6!
function get_querystring( url ) {
return url.replace( /(?:^[^?#]*\?([^#]*).*$)?.*/, '$1' );
};
// Section: Param (to string)
//
// Method: jQuery.param.querystring
//
// Retrieve the query string from a URL or if no arguments are passed, the
// current window.location.href.
//
// Usage:
//
// > jQuery.param.querystring( [ url ] );
//
// Arguments:
//
// url - (String) A URL containing query string params to be parsed. If url
// is not passed, the current window.location.href is used.
//
// Returns:
//
// (String) The parsed query string, with any leading "?" removed.
//
// Method: jQuery.param.querystring (build url)
//
// Merge a URL, with or without pre-existing query string params, plus any
// object, params string or URL containing query string params into a new URL.
//
// Usage:
//
// > jQuery.param.querystring( url, params [, merge_mode ] );
//
// Arguments:
//
// url - (String) A valid URL for params to be merged into. This URL may
// contain a query string and/or fragment (hash).
// params - (String) A params string or URL containing query string params to
// be merged into url.
// params - (Object) A params object to be merged into url.
// merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
// specified, and is as-follows:
//
// * 0: params in the params argument will override any query string
// params in url.
// * 1: any query string params in url will override params in the params
// argument.
// * 2: params argument will completely replace any query string in url.
//
// Returns:
//
// (String) A URL with a urlencoded query string in the format '?a=b&c=d&e=f'.
// Method: jQuery.param.fragment
//
// Retrieve the fragment (hash) from a URL or if no arguments are passed, the
// current window.location.href.
//
// Usage:
//
// > jQuery.param.fragment( [ url ] );
//
// Arguments:
//
// url - (String) A URL containing fragment (hash) params to be parsed. If
// url is not passed, the current window.location.href is used.
//
// Returns:
//
// (String) The parsed fragment (hash) string, with any leading "#" removed.
// Method: jQuery.param.fragment (build url)
//
// Merge a URL, with or without pre-existing fragment (hash) params, plus any
// object, params string or URL containing fragment (hash) params into a new
// URL.
//
// Usage:
//
// > jQuery.param.fragment( url, params [, merge_mode ] );
//
// Arguments:
//
// url - (String) A valid URL for params to be merged into. This URL may
// contain a query string and/or fragment (hash).
// params - (String) A params string or URL containing fragment (hash) params
// to be merged into url.
// params - (Object) A params object to be merged into url.
// merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
// specified, and is as-follows:
//
// * 0: params in the params argument will override any fragment (hash)
// params in url.
// * 1: any fragment (hash) params in url will override params in the
// params argument.
// * 2: params argument will completely replace any query string in url.
//
// Returns:
//
// (String) A URL with a urlencoded fragment (hash) in the format '#a=b&c=d&e=f'.
function jq_param_sub( is_fragment, get_func, url, params, merge_mode ) {
var result,
qs,
matches,
url_params,
hash;
if ( params !== undefined ) {
// Build URL by merging params into url string.
// matches[1] = url part that precedes params, not including trailing ?/#
// matches[2] = params, not including leading ?/#
// matches[3] = if in 'querystring' mode, hash including leading #, otherwise ''
matches = url.match( is_fragment ? re_fragment : /^([^#?]*)\??([^#]*)(#?.*)/ );
// Get the hash if in 'querystring' mode, and it exists.
hash = matches[3] || '';
if ( merge_mode === 2 && is_string( params ) ) {
// If merge_mode is 2 and params is a string, merge the fragment / query
// string into the URL wholesale, without converting it into an object.
qs = params.replace( is_fragment ? re_params_fragment : re_params_querystring, '' );
} else {
// Convert relevant params in url to object.
url_params = jq_deparam( matches[2] );
params = is_string( params )
// Convert passed params string into object.
? jq_deparam[ is_fragment ? str_fragment : str_querystring ]( params )
// Passed params object.
: params;
qs = merge_mode === 2 ? params // passed params replace url params
: merge_mode === 1 ? $.extend( {}, params, url_params ) // url params override passed params
: $.extend( {}, url_params, params ); // passed params override url params
// Convert params object into a sorted params string.
qs = jq_param_sorted( qs );
// Unescape characters specified via $.param.noEscape. Since only hash-
// history users have requested this feature, it's only enabled for
// fragment-related params strings.
if ( is_fragment ) {
qs = qs.replace( re_no_escape, decode );
}
}
// Build URL from the base url, querystring and hash. In 'querystring'
// mode, ? is only added if a query string exists. In 'fragment' mode, #
// is always added.
result = matches[1] + ( is_fragment ? fragment_prefix : qs || !matches[1] ? '?' : '' ) + qs + hash;
} else {
// If URL was passed in, parse params from URL string, otherwise parse
// params from window.location.href.
result = get_func( url !== undefined ? url : location.href );
}
return result;
};
jq_param[ str_querystring ] = curry( jq_param_sub, 0, get_querystring );
jq_param[ str_fragment ] = jq_param_fragment = curry( jq_param_sub, 1, get_fragment );
// Method: jQuery.param.sorted
//
// Returns a params string equivalent to that returned by the internal
// jQuery.param method, but sorted, which makes it suitable for use as a
// cache key.
//
// For example, in most browsers jQuery.param({z:1,a:2}) returns "z=1&a=2"
// and jQuery.param({a:2,z:1}) returns "a=2&z=1". Even though both the
// objects being serialized and the resulting params strings are equivalent,
// if these params strings were set into the location.hash fragment
// sequentially, the hashchange event would be triggered unnecessarily, since
// the strings are different (even though the data described by them is the
// same). By sorting the params string, unecessary hashchange event triggering
// can be avoided.
//
// Usage:
//
// > jQuery.param.sorted( obj [, traditional ] );
//
// Arguments:
//
// obj - (Object) An object to be serialized.
// traditional - (Boolean) Params deep/shallow serialization mode. See the
// documentation at http://api.jquery.com/jQuery.param/ for more detail.
//
// Returns:
//
// (String) A sorted params string.
jq_param.sorted = jq_param_sorted = function( a, traditional ) {
var arr = [],
obj = {};
$.each( jq_param( a, traditional ).split( '&' ), function(i,v){
var key = v.replace( /(?:%5B|=).*$/, '' ),
key_obj = obj[ key ];
if ( !key_obj ) {
key_obj = obj[ key ] = [];
arr.push( key );
}
key_obj.push( v );
});
return $.map( arr.sort(), function(v){
return obj[ v ];
}).join( '&' );
};
// Method: jQuery.param.fragment.noEscape
//
// Specify characters that will be left unescaped when fragments are created
// or merged using <jQuery.param.fragment>, or when the fragment is modified
// using <jQuery.bbq.pushState>. This option only applies to serialized data
// object fragments, and not set-as-string fragments. Does not affect the
// query string. Defaults to ",/" (comma, forward slash).
//
// Note that this is considered a purely aesthetic option, and will help to
// create URLs that "look pretty" in the address bar or bookmarks, without
// affecting functionality in any way. That being said, be careful to not
// unescape characters that are used as delimiters or serve a special
// purpose, such as the "#?&=+" (octothorpe, question mark, ampersand,
// equals, plus) characters.
//
// Usage:
//
// > jQuery.param.fragment.noEscape( [ chars ] );
//
// Arguments:
//
// chars - (String) The characters to not escape in the fragment. If
// unspecified, defaults to empty string (escape all characters).
//
// Returns:
//
// Nothing.
jq_param_fragment.noEscape = function( chars ) {
chars = chars || '';
var arr = $.map( chars.split(''), encodeURIComponent );
re_no_escape = new RegExp( arr.join('|'), 'g' );
};
// A sensible default. These are the characters people seem to complain about
// "uglifying up the URL" the most.
jq_param_fragment.noEscape( ',/' );
// Method: jQuery.param.fragment.ajaxCrawlable
//
// TODO: DESCRIBE
//
// Usage:
//
// > jQuery.param.fragment.ajaxCrawlable( [ state ] );
//
// Arguments:
//
// state - (Boolean) TODO: DESCRIBE
//
// Returns:
//
// (Boolean) The current ajaxCrawlable state.
jq_param_fragment.ajaxCrawlable = function( state ) {
if ( state !== undefined ) {
if ( state ) {
re_params_fragment = /^.*(?:#!|#)/;
re_fragment = /^([^#]*)(?:#!|#)?(.*)$/;
fragment_prefix = '#!';
} else {
re_params_fragment = /^.*#/;
re_fragment = /^([^#]*)#?(.*)$/;
fragment_prefix = '#';
}
ajax_crawlable = !!state;
}
return ajax_crawlable;
};
jq_param_fragment.ajaxCrawlable( 0 );
// Section: Deparam (from string)
//
// Method: jQuery.deparam
//
// Deserialize a params string into an object, optionally coercing numbers,
// booleans, null and undefined values; this method is the counterpart to the
// internal jQuery.param method.
//
// Usage:
//
// > jQuery.deparam( params [, coerce ] );
//
// Arguments:
//
// params - (String) A params string to be parsed.
// coerce - (Boolean) If true, coerces any numbers or true, false, null, and
// undefined to their actual value. Defaults to false if omitted.
//
// Returns:
//
// (Object) An object representing the deserialized params string.
$.deparam = jq_deparam = function( params, coerce ) {
var obj = {},
coerce_types = { 'true': !0, 'false': !1, 'null': null };
// Iterate over all name=value pairs.
$.each( params.replace( /\+/g, ' ' ).split( '&' ), function(j,v){
var param = v.split( '=' ),
key = decode( param[0] ),
val,
cur = obj,
i = 0,
// If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
// into its component parts.
keys = key.split( '][' ),
keys_last = keys.length - 1;
// If the first keys part contains [ and the last ends with ], then []
// are correctly balanced.
if ( /\[/.test( keys[0] ) && /\]$/.test( keys[ keys_last ] ) ) {
// Remove the trailing ] from the last keys part.
keys[ keys_last ] = keys[ keys_last ].replace( /\]$/, '' );
// Split first keys part into two parts on the [ and add them back onto
// the beginning of the keys array.
keys = keys.shift().split('[').concat( keys );
keys_last = keys.length - 1;
} else {
// Basic 'foo' style key.
keys_last = 0;
}
// Are we dealing with a name=value pair, or just a name?
if ( param.length === 2 ) {
val = decode( param[1] );
// Coerce values.
if ( coerce ) {
val = val && !isNaN(val) ? +val // number
: val === 'undefined' ? undefined // undefined
: coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
: val; // string
}
if ( keys_last ) {
// Complex key, build deep object structure based on a few rules:
// * The 'cur' pointer starts at the object top-level.
// * [] = array push (n is set to array length), [n] = array if n is
// numeric, otherwise object.
// * If at the last keys part, set the value.
// * For each keys part, if the current level is undefined create an
// object or array based on the type of the next keys part.
// * Move the 'cur' pointer to the next level.
// * Rinse & repeat.
for ( ; i <= keys_last; i++ ) {
key = keys[i] === '' ? cur.length : keys[i];
cur = cur[key] = i < keys_last
? cur[key] || ( keys[i+1] && isNaN( keys[i+1] ) ? {} : [] )
: val;
}
} else {
// Simple key, even simpler rules, since only scalars and shallow
// arrays are allowed.
if ( $.isArray( obj[key] ) ) {
// val is already an array, so push on the next value.
obj[key].push( val );
} else if ( obj[key] !== undefined ) {
// val isn't an array, but since a second value has been specified,
// convert val into an array.
obj[key] = [ obj[key], val ];
} else {
// val is a scalar.
obj[key] = val;
}
}
} else if ( key ) {
// No value was defined, so set something meaningful.
obj[key] = coerce
? undefined
: '';
}
});
return obj;
};
// Method: jQuery.deparam.querystring
//
// Parse the query string from a URL or the current window.location.href,
// deserializing it into an object, optionally coercing numbers, booleans,
// null and undefined values.
//
// Usage:
//
// > jQuery.deparam.querystring( [ url ] [, coerce ] );
//
// Arguments:
//
// url - (String) An optional params string or URL containing query string
// params to be parsed. If url is omitted, the current
// window.location.href is used.
// coerce - (Boolean) If true, coerces any numbers or true, false, null, and
// undefined to their actual value. Defaults to false if omitted.
//
// Returns:
//
// (Object) An object representing the deserialized params string.
// Method: jQuery.deparam.fragment
//
// Parse the fragment (hash) from a URL or the current window.location.href,
// deserializing it into an object, optionally coercing numbers, booleans,
// null and undefined values.
//
// Usage:
//
// > jQuery.deparam.fragment( [ url ] [, coerce ] );
//
// Arguments:
//
// url - (String) An optional params string or URL containing fragment (hash)
// params to be parsed. If url is omitted, the current window.location.href
// is used.
// coerce - (Boolean) If true, coerces any numbers or true, false, null, and
// undefined to their actual value. Defaults to false if omitted.
//
// Returns:
//
// (Object) An object representing the deserialized params string.
function jq_deparam_sub( is_fragment, url_or_params, coerce ) {
if ( url_or_params === undefined || typeof url_or_params === 'boolean' ) {
// url_or_params not specified.
coerce = url_or_params;
url_or_params = jq_param[ is_fragment ? str_fragment : str_querystring ]();
} else {
url_or_params = is_string( url_or_params )
? url_or_params.replace( is_fragment ? re_params_fragment : re_params_querystring, '' )
: url_or_params;
}
return jq_deparam( url_or_params, coerce );
};
jq_deparam[ str_querystring ] = curry( jq_deparam_sub, 0 );
jq_deparam[ str_fragment ] = jq_deparam_fragment = curry( jq_deparam_sub, 1 );
// Section: Element manipulation
//
// Method: jQuery.elemUrlAttr
//
// Get the internal "Default URL attribute per tag" list, or augment the list
// with additional tag-attribute pairs, in case the defaults are insufficient.
//
// In the <jQuery.fn.querystring> and <jQuery.fn.fragment> methods, this list
// is used to determine which attribute contains the URL to be modified, if
// an "attr" param is not specified.
//
// Default Tag-Attribute List:
//
// a - href
// base - href
// iframe - src
// img - src
// input - src
// form - action
// link - href
// script - src
//
// Usage:
//
// > jQuery.elemUrlAttr( [ tag_attr ] );
//
// Arguments:
//
// tag_attr - (Object) An object containing a list of tag names and their
// associated default attribute names in the format { tag: 'attr', ... } to
// be merged into the internal tag-attribute list.
//
// Returns:
//
// (Object) An object containing all stored tag-attribute values.
// Only define function and set defaults if function doesn't already exist, as
// the urlInternal plugin will provide this method as well.
$[ str_elemUrlAttr ] || ($[ str_elemUrlAttr ] = function( obj ) {
return $.extend( elemUrlAttr_cache, obj );
})({
a: str_href,
base: str_href,
iframe: str_src,
img: str_src,
input: str_src,
form: 'action',
link: str_href,
script: str_src
});
jq_elemUrlAttr = $[ str_elemUrlAttr ];
// Method: jQuery.fn.querystring
//
// Update URL attribute in one or more elements, merging the current URL (with
// or without pre-existing query string params) plus any params object or
// string into a new URL, which is then set into that attribute. Like
// <jQuery.param.querystring (build url)>, but for all elements in a jQuery
// collection.
//
// Usage:
//
// > jQuery('selector').querystring( [ attr, ] params [, merge_mode ] );
//
// Arguments:
//
// attr - (String) Optional name of an attribute that will contain a URL to
// merge params or url into. See <jQuery.elemUrlAttr> for a list of default
// attributes.
// params - (Object) A params object to be merged into the URL attribute.
// params - (String) A URL containing query string params, or params string
// to be merged into the URL attribute.
// merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
// specified, and is as-follows:
//
// * 0: params in the params argument will override any params in attr URL.
// * 1: any params in attr URL will override params in the params argument.
// * 2: params argument will completely replace any query string in attr
// URL.
//
// Returns:
//
// (jQuery) The initial jQuery collection of elements, but with modified URL
// attribute values.
// Method: jQuery.fn.fragment
//
// Update URL attribute in one or more elements, merging the current URL (with
// or without pre-existing fragment/hash params) plus any params object or
// string into a new URL, which is then set into that attribute. Like
// <jQuery.param.fragment (build url)>, but for all elements in a jQuery
// collection.
//
// Usage:
//
// > jQuery('selector').fragment( [ attr, ] params [, merge_mode ] );
//
// Arguments:
//
// attr - (String) Optional name of an attribute that will contain a URL to
// merge params into. See <jQuery.elemUrlAttr> for a list of default
// attributes.
// params - (Object) A params object to be merged into the URL attribute.
// params - (String) A URL containing fragment (hash) params, or params
// string to be merged into the URL attribute.
// merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
// specified, and is as-follows:
//
// * 0: params in the params argument will override any params in attr URL.
// * 1: any params in attr URL will override params in the params argument.
// * 2: params argument will completely replace any fragment (hash) in attr
// URL.
//
// Returns:
//
// (jQuery) The initial jQuery collection of elements, but with modified URL
// attribute values.
function jq_fn_sub( mode, force_attr, params, merge_mode ) {
if ( !is_string( params ) && typeof params !== 'object' ) {
// force_attr not specified.
merge_mode = params;
params = force_attr;
force_attr = undefined;
}
return this.each(function(){
var that = $(this),
// Get attribute specified, or default specified via $.elemUrlAttr.
attr = force_attr || jq_elemUrlAttr()[ ( this.nodeName || '' ).toLowerCase() ] || '',
// Get URL value.
url = attr && that.attr( attr ) || '';
// Update attribute with new URL.
that.attr( attr, jq_param[ mode ]( url, params, merge_mode ) );
});
};
$.fn[ str_querystring ] = curry( jq_fn_sub, str_querystring );
$.fn[ str_fragment ] = curry( jq_fn_sub, str_fragment );
// Section: History, hashchange event
//
// Method: jQuery.bbq.pushState
//
// Adds a 'state' into the browser history at the current position, setting
// location.hash and triggering any bound <hashchange event> callbacks
// (provided the new state is different than the previous state).
//
// If no arguments are passed, an empty state is created, which is just a
// shortcut for jQuery.bbq.pushState( {}, 2 ).
//
// Usage:
//
// > jQuery.bbq.pushState( [ params [, merge_mode ] ] );
//
// Arguments:
//
// params - (String) A serialized params string or a hash string beginning
// with # to merge into location.hash.
// params - (Object) A params object to merge into location.hash.
// merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
// specified (unless a hash string beginning with # is specified, in which
// case merge behavior defaults to 2), and is as-follows:
//
// * 0: params in the params argument will override any params in the
// current state.
// * 1: any params in the current state will override params in the params
// argument.
// * 2: params argument will completely replace current state.
//
// Returns:
//
// Nothing.
//
// Additional Notes:
//
// * Setting an empty state may cause the browser to scroll.
// * Unlike the fragment and querystring methods, if a hash string beginning
// with # is specified as the params agrument, merge_mode defaults to 2.
jq_bbq.pushState = jq_bbq_pushState = function( params, merge_mode ) {
if ( is_string( params ) && /^#/.test( params ) && merge_mode === undefined ) {
// Params string begins with # and merge_mode not specified, so completely
// overwrite window.location.hash.
merge_mode = 2;
}
var has_args = params !== undefined,
// Merge params into window.location using $.param.fragment.
url = jq_param_fragment( location.href,
has_args ? params : {}, has_args ? merge_mode : 2 );
// Set new window.location.href. Note that Safari 3 & Chrome barf on
// location.hash = '#' so the entire URL is set.
location.href = url;
};
// Method: jQuery.bbq.getState
//
// Retrieves the current 'state' from the browser history, parsing
// location.hash for a specific key or returning an object containing the
// entire state, optionally coercing numbers, booleans, null and undefined
// values.
//
// Usage:
//
// > jQuery.bbq.getState( [ key ] [, coerce ] );
//
// Arguments:
//
// key - (String) An optional state key for which to return a value.
// coerce - (Boolean) If true, coerces any numbers or true, false, null, and
// undefined to their actual value. Defaults to false.
//
// Returns:
//
// (Anything) If key is passed, returns the value corresponding with that key
// in the location.hash 'state', or undefined. If not, an object
// representing the entire 'state' is returned.
jq_bbq.getState = jq_bbq_getState = function( key, coerce ) {
return key === undefined || typeof key === 'boolean'
? jq_deparam_fragment( key ) // 'key' really means 'coerce' here
: jq_deparam_fragment( coerce )[ key ];
};
// Method: jQuery.bbq.removeState
//
// Remove one or more keys from the current browser history 'state', creating
// a new state, setting location.hash and triggering any bound
// <hashchange event> callbacks (provided the new state is different than
// the previous state).
//
// If no arguments are passed, an empty state is created, which is just a
// shortcut for jQuery.bbq.pushState( {}, 2 ).
//
// Usage:
//
// > jQuery.bbq.removeState( [ key [, key ... ] ] );
//
// Arguments:
//
// key - (String) One or more key values to remove from the current state,
// passed as individual arguments.
// key - (Array) A single array argument that contains a list of key values
// to remove from the current state.
//
// Returns:
//
// Nothing.
//
// Additional Notes:
//
// * Setting an empty state may cause the browser to scroll.
jq_bbq.removeState = function( arr ) {
var state = {};
// If one or more arguments is passed..
if ( arr !== undefined ) {
// Get the current state.
state = jq_bbq_getState();
// For each passed key, delete the corresponding property from the current
// state.
$.each( $.isArray( arr ) ? arr : arguments, function(i,v){
delete state[ v ];
});
}
// Set the state, completely overriding any existing state.
jq_bbq_pushState( state, 2 );
};
// Event: hashchange event (BBQ)
//
// Usage in jQuery 1.4 and newer:
//
// In jQuery 1.4 and newer, the event object passed into any hashchange event
// callback is augmented with a copy of the location.hash fragment at the time
// the event was triggered as its event.fragment property. In addition, the
// event.getState method operates on this property (instead of location.hash)
// which allows this fragment-as-a-state to be referenced later, even after
// window.location may have changed.
//
// Note that event.fragment and event.getState are not defined according to
// W3C (or any other) specification, but will still be available whether or
// not the hashchange event exists natively in the browser, because of the
// utility they provide.
//
// The event.fragment property contains the output of <jQuery.param.fragment>
// and the event.getState method is equivalent to the <jQuery.bbq.getState>
// method.
//
// > $(window).bind( 'hashchange', function( event ) {
// > var hash_str = event.fragment,
// > param_obj = event.getState(),
// > param_val = event.getState( 'param_name' ),
// > param_val_coerced = event.getState( 'param_name', true );
// > ...
// > });
//
// Usage in jQuery 1.3.2:
//
// In jQuery 1.3.2, the event object cannot to be augmented as in jQuery 1.4+,
// so the fragment state isn't bound to the event object and must instead be
// parsed using the <jQuery.param.fragment> and <jQuery.bbq.getState> methods.
//
// > $(window).bind( 'hashchange', function( event ) {
// > var hash_str = $.param.fragment(),
// > param_obj = $.bbq.getState(),
// > param_val = $.bbq.getState( 'param_name' ),
// > param_val_coerced = $.bbq.getState( 'param_name', true );
// > ...
// > });
//
// Additional Notes:
//
// * Due to changes in the special events API, jQuery BBQ v1.2 or newer is
// required to enable the augmented event object in jQuery 1.4.2 and newer.
// * See <jQuery hashchange event> for more detailed information.
special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
// Augmenting the event object with the .fragment property and .getState
// method requires jQuery 1.4 or newer. Note: with 1.3.2, everything will
// work, but the event won't be augmented)
add: function( handleObj ) {
var old_handler;
function new_handler(e) {
// e.fragment is set to the value of location.hash (with any leading #
// removed) at the time the event is triggered.
var hash = e[ str_fragment ] = jq_param_fragment();
// e.getState() works just like $.bbq.getState(), but uses the
// e.fragment property stored on the event object.
e.getState = function( key, coerce ) {
return key === undefined || typeof key === 'boolean'
? jq_deparam( hash, key ) // 'key' really means 'coerce' here
: jq_deparam( hash, coerce )[ key ];
};
old_handler.apply( this, arguments );
};
// This may seem a little complicated, but it normalizes the special event
// .add method between jQuery 1.4/1.4.1 and 1.4.2+
if ( $.isFunction( handleObj ) ) {
// 1.4, 1.4.1
old_handler = handleObj;
return new_handler;
} else {
// 1.4.2+
old_handler = handleObj.handler;
handleObj.handler = new_handler;
}
}
});
})(jQuery,this);
/*!
* jQuery hashchange event - v1.3 - 7/21/2010
* http://benalman.com/projects/jquery-hashchange-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
// Script: jQuery hashchange event
//
// *Version: 1.3, Last updated: 7/21/2010*
//
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
// GitHub - http://github.com/cowboy/jquery-hashchange/
// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
//
// About: License
//
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
//
// About: Examples
//
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
//
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
//
// About: Support and Testing
//
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
//
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/
//
// About: Known issues
//
// While this jQuery hashchange event implementation is quite stable and
// robust, there are a few unfortunate browser bugs surrounding expected
// hashchange event-based behaviors, independent of any JavaScript
// window.onhashchange abstraction. See the following examples for more
// information:
//
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
//
// Also note that should a browser natively support the window.onhashchange
// event, but not report that it does, the fallback polling loop will be used.
//
// About: Release History
//
// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
// "removable" for mobile-only development. Added IE6/7 document.title
// support. Attempted to make Iframe as hidden as possible by using
// techniques from http://www.paciellogroup.com/blog/?p=604. Added
// support for the "shortcut" format $(window).hashchange( fn ) and
// $(window).hashchange() like jQuery provides for built-in events.
// Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
// lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
// and <jQuery.fn.hashchange.src> properties plus document-domain.html
// file to address access denied issues when setting document.domain in
// IE6/7.
// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin
// from a page on another domain would cause an error in Safari 4. Also,
// IE6/7 Iframe is now inserted after the body (this actually works),
// which prevents the page from scrolling when the event is first bound.
// Event can also now be bound before DOM ready, but it won't be usable
// before then in IE6/7.
// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
// where browser version is incorrectly reported as 8.0, despite
// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
// window.onhashchange functionality into a separate plugin for users
// who want just the basic event & back button support, without all the
// extra awesomeness that BBQ provides. This plugin will be included as
// part of jQuery BBQ, but also be available separately.
(function($,window,undefined){
'$:nomunge'; // Used by YUI compressor.
// Reused string.
var str_hashchange = 'hashchange',
// Method / object references.
doc = document,
fake_onhashchange,
special = $.event.special,
// Does the browser support window.onhashchange? Note that IE8 running in
// IE7 compatibility mode reports true for 'onhashchange' in window, even
// though the event isn't supported, so also test document.documentMode.
doc_mode = doc.documentMode,
supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
// Get location.hash (or what you'd expect location.hash to be) sans any
// leading #. Thanks for making this necessary, Firefox!
function get_fragment( url ) {
url = url || location.href;
return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
};
// Method: jQuery.fn.hashchange
//
// Bind a handler to the window.onhashchange event or trigger all bound
// window.onhashchange event handlers. This behavior is consistent with
// jQuery's built-in event handlers.
//
// Usage:
//
// > jQuery(window).hashchange( [ handler ] );
//
// Arguments:
//
// handler - (Function) Optional handler to be bound to the hashchange
// event. This is a "shortcut" for the more verbose form:
// jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
// all bound window.onhashchange event handlers will be triggered. This
// is a shortcut for the more verbose
// jQuery(window).trigger( 'hashchange' ). These forms are described in
// the <hashchange event> section.
//
// Returns:
//
// (jQuery) The initial jQuery collection of elements.
// Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
// $(elem).hashchange() for triggering, like jQuery does for built-in events.
$.fn[ str_hashchange ] = function( fn ) {
return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
};
// Property: jQuery.fn.hashchange.delay
//
// The numeric interval (in milliseconds) at which the <hashchange event>
// polling loop executes. Defaults to 50.
// Property: jQuery.fn.hashchange.domain
//
// If you're setting document.domain in your JavaScript, and you want hash
// history to work in IE6/7, not only must this property be set, but you must
// also set document.domain BEFORE jQuery is loaded into the page. This
// property is only applicable if you are supporting IE6/7 (or IE8 operating
// in "IE7 compatibility" mode).
//
// In addition, the <jQuery.fn.hashchange.src> property must be set to the
// path of the included "document-domain.html" file, which can be renamed or
// modified if necessary (note that the document.domain specified must be the
// same in both your main JavaScript as well as in this file).
//
// Usage:
//
// jQuery.fn.hashchange.domain = document.domain;
// Property: jQuery.fn.hashchange.src
//
// If, for some reason, you need to specify an Iframe src file (for example,
// when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
// do so using this property. Note that when using this property, history
// won't be recorded in IE6/7 until the Iframe src file loads. This property
// is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
// compatibility" mode).
//
// Usage:
//
// jQuery.fn.hashchange.src = 'path/to/file.html';
$.fn[ str_hashchange ].delay = 50;
/*
$.fn[ str_hashchange ].domain = null;
$.fn[ str_hashchange ].src = null;
*/
// Event: hashchange event
//
// Fired when location.hash changes. In browsers that support it, the native
// HTML5 window.onhashchange event is used, otherwise a polling loop is
// initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
// see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
// compatibility" mode), a hidden Iframe is created to allow the back button
// and hash-based history to work.
//
// Usage as described in <jQuery.fn.hashchange>:
//
// > // Bind an event handler.
// > jQuery(window).hashchange( function(e) {
// > var hash = location.hash;
// > ...
// > });
// >
// > // Manually trigger the event handler.
// > jQuery(window).hashchange();
//
// A more verbose usage that allows for event namespacing:
//
// > // Bind an event handler.
// > jQuery(window).bind( 'hashchange', function(e) {
// > var hash = location.hash;
// > ...
// > });
// >
// > // Manually trigger the event handler.
// > jQuery(window).trigger( 'hashchange' );
//
// Additional Notes:
//
// * The polling loop and Iframe are not created until at least one handler
// is actually bound to the 'hashchange' event.
// * If you need the bound handler(s) to execute immediately, in cases where
// a location.hash exists on page load, via bookmark or page refresh for
// example, use jQuery(window).hashchange() or the more verbose
// jQuery(window).trigger( 'hashchange' ).
// * The event can be bound before DOM ready, but since it won't be usable
// before then in IE6/7 (due to the necessary Iframe), recommended usage is
// to bind it inside a DOM ready handler.
// Override existing $.event.special.hashchange methods (allowing this plugin
// to be defined after jQuery BBQ in BBQ's source code).
special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
// Called only when the first 'hashchange' event is bound to window.
setup: function() {
// If window.onhashchange is supported natively, there's nothing to do..
if ( supports_onhashchange ) { return false; }
// Otherwise, we need to create our own. And we don't want to call this
// until the user binds to the event, just in case they never do, since it
// will create a polling loop and possibly even a hidden Iframe.
$( fake_onhashchange.start );
},
// Called only when the last 'hashchange' event is unbound from window.
teardown: function() {
// If window.onhashchange is supported natively, there's nothing to do..
if ( supports_onhashchange ) { return false; }
// Otherwise, we need to stop ours (if possible).
$( fake_onhashchange.stop );
}
});
// fake_onhashchange does all the work of triggering the window.onhashchange
// event for browsers that don't natively support it, including creating a
// polling loop to watch for hash changes and in IE 6/7 creating a hidden
// Iframe to enable back and forward.
fake_onhashchange = (function(){
var self = {},
timeout_id,
// Remember the initial hash so it doesn't get triggered immediately.
last_hash = get_fragment(),
fn_retval = function(val){ return val; },
history_set = fn_retval,
history_get = fn_retval;
// Start the polling loop.
self.start = function() {
timeout_id || poll();
};
// Stop the polling loop.
self.stop = function() {
timeout_id && clearTimeout( timeout_id );
timeout_id = undefined;
};
// This polling loop checks every $.fn.hashchange.delay milliseconds to see
// if location.hash has changed, and triggers the 'hashchange' event on
// window when necessary.
function poll() {
var hash = get_fragment(),
history_hash = history_get( last_hash );
if ( hash !== last_hash ) {
history_set( last_hash = hash, history_hash );
$(window).trigger( str_hashchange );
} else if ( history_hash !== last_hash ) {
location.href = location.href.replace( /#.*/, '' ) + history_hash;
}
timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
};
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
$.browser.msie && !supports_onhashchange && (function(){
// Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8
// when running in "IE7 compatibility" mode.
var iframe,
iframe_src;
// When the event is bound and polling starts in IE 6/7, create a hidden
// Iframe for history handling.
self.start = function(){
if ( !iframe ) {
iframe_src = $.fn[ str_hashchange ].src;
iframe_src = iframe_src && iframe_src + get_fragment();
// Create hidden Iframe. Attempt to make Iframe as hidden as possible
// by using techniques from http://www.paciellogroup.com/blog/?p=604.
iframe = $('<iframe tabindex="-1" title="empty"/>').hide()
// When Iframe has completely loaded, initialize the history and
// start polling.
.one( 'load', function(){
iframe_src || history_set( get_fragment() );
poll();
})
// Load Iframe src if specified, otherwise nothing.
.attr( 'src', iframe_src || 'javascript:0' )
// Append Iframe after the end of the body to prevent unnecessary
// initial page scrolling (yes, this works).
.insertAfter( 'body' )[0].contentWindow;
// Whenever `document.title` changes, update the Iframe's title to
// prettify the back/next history menu entries. Since IE sometimes
// errors with "Unspecified error" the very first time this is set
// (yes, very useful) wrap this with a try/catch block.
doc.onpropertychange = function(){
try {
if ( event.propertyName === 'title' ) {
iframe.document.title = doc.title;
}
} catch(e) {}
};
}
};
// Override the "stop" method since an IE6/7 Iframe was created. Even
// if there are no longer any bound event handlers, the polling loop
// is still necessary for back/next to work at all!
self.stop = fn_retval;
// Get history by looking at the hidden Iframe's location.hash.
history_get = function() {
return get_fragment( iframe.location.href );
};
// Set a new history item by opening and then closing the Iframe
// document, *then* setting its location.hash. If document.domain has
// been set, update that as well.
history_set = function( hash, history_hash ) {
var iframe_doc = iframe.document,
domain = $.fn[ str_hashchange ].domain;
if ( hash !== history_hash ) {
// Update Iframe with any initial `document.title` that might be set.
iframe_doc.title = doc.title;
// Opening the Iframe's document after it has been closed is what
// actually adds a history entry.
iframe_doc.open();
// Set document.domain for the Iframe document as well, if necessary.
domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' );
iframe_doc.close();
// Update the Iframe's hash, for great justice.
iframe.location.hash = hash;
}
};
})();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return self;
})();
})(jQuery,this);
/*!
jQuery ColorBox v1.4.6 - 2013-03-19
(c) 2013 Jack Moore - jacklmoore.com/colorbox
license: http://www.opensource.org/licenses/mit-license.php
*/
(function ($, document, window) {
var
// Default settings object.
// See http://jacklmoore.com/colorbox for details.
defaults = {
transition: "elastic",
speed: 300,
width: false,
initialWidth: "600",
innerWidth: false,
maxWidth: false,
height: false,
initialHeight: "450",
innerHeight: false,
maxHeight: false,
scalePhotos: true,
scrolling: true,
inline: false,
html: false,
iframe: false,
fastIframe: true,
photo: false,
href: false,
title: false,
rel: false,
opacity: 0.9,
preloading: true,
className: false,
// alternate image paths for high-res displays
retinaImage: false,
retinaUrl: false,
retinaSuffix: '@2x.$1',
// internationalization
current: "image {current} of {total}",
previous: "previous",
next: "next",
close: "close",
xhrError: "This content failed to load.",
imgError: "This image failed to load.",
open: false,
returnFocus: true,
reposition: true,
loop: true,
slideshow: false,
slideshowAuto: true,
slideshowSpeed: 2500,
slideshowStart: "start slideshow",
slideshowStop: "stop slideshow",
photoRegex: /\.(gif|png|jp(e|g|eg)|bmp|ico)((#|\?).*)?$/i,
onOpen: false,
onLoad: false,
onComplete: false,
onCleanup: false,
onClosed: false,
overlayClose: true,
escKey: true,
arrowKey: true,
top: false,
bottom: false,
left: false,
right: false,
fixed: false,
data: undefined
},
// Abstracting the HTML and event identifiers for easy rebranding
colorbox = 'colorbox',
prefix = 'cbox',
boxElement = prefix + 'Element',
// Events
event_open = prefix + '_open',
event_load = prefix + '_load',
event_complete = prefix + '_complete',
event_cleanup = prefix + '_cleanup',
event_closed = prefix + '_closed',
event_purge = prefix + '_purge',
// Special Handling for IE
isIE = !$.support.leadingWhitespace, // IE6 to IE8
isIE6 = isIE && !window.XMLHttpRequest, // IE6
event_ie6 = prefix + '_IE6',
// Cached jQuery Object Variables
$overlay,
$box,
$wrap,
$content,
$topBorder,
$leftBorder,
$rightBorder,
$bottomBorder,
$related,
$window,
$loaded,
$loadingBay,
$loadingOverlay,
$title,
$current,
$slideshow,
$next,
$prev,
$close,
$groupControls,
$events = $('<a/>'),
// Variables for cached values or use across multiple functions
settings,
interfaceHeight,
interfaceWidth,
loadedHeight,
loadedWidth,
element,
index,
photo,
open,
active,
closing,
loadingTimer,
publicMethod,
div = "div",
className,
requests = 0,
init;
// ****************
// HELPER FUNCTIONS
// ****************
// Convience function for creating new jQuery objects
function $tag(tag, id, css) {
var element = document.createElement(tag);
if (id) {
element.id = prefix + id;
}
if (css) {
element.style.cssText = css;
}
return $(element);
}
// Get the window height using innerHeight when available to avoid an issue with iOS
// http://bugs.jquery.com/ticket/6724
function winheight() {
return window.innerHeight ? window.innerHeight : $(window).height();
}
// Determine the next and previous members in a group.
function getIndex(increment) {
var
max = $related.length,
newIndex = (index + increment) % max;
return (newIndex < 0) ? max + newIndex : newIndex;
}
// Convert '%' and 'px' values to integers
function setSize(size, dimension) {
return Math.round((/%/.test(size) ? ((dimension === 'x' ? $window.width() : winheight()) / 100) : 1) * parseInt(size, 10));
}
// Checks an href to see if it is a photo.
// There is a force photo option (photo: true) for hrefs that cannot be matched by the regex.
function isImage(settings, url) {
return settings.photo || settings.photoRegex.test(url);
}
function retinaUrl(settings, url) {
return settings.retinaUrl && window.devicePixelRatio > 1 ? url.replace(settings.photoRegex, settings.retinaSuffix) : url;
}
function trapFocus(e) {
if ('contains' in $box[0] && !$box[0].contains(e.target)) {
e.stopPropagation();
$box.focus();
}
}
// Assigns function results to their respective properties
function makeSettings() {
var i,
data = $.data(element, colorbox);
if (data == null) {
settings = $.extend({}, defaults);
if (console && console.log) {
console.log('Error: cboxElement missing settings object');
}
} else {
settings = $.extend({}, data);
}
for (i in settings) {
if ($.isFunction(settings[i]) && i.slice(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time.
settings[i] = settings[i].call(element);
}
}
settings.rel = settings.rel || element.rel || $(element).data('rel') || 'nofollow';
settings.href = settings.href || $(element).attr('href');
settings.title = settings.title || element.title;
if (typeof settings.href === "string") {
settings.href = $.trim(settings.href);
}
}
function trigger(event, callback) {
// for external use
$(document).trigger(event);
// for internal use
$events.trigger(event);
if ($.isFunction(callback)) {
callback.call(element);
}
}
// Slideshow functionality
function slideshow() {
var
timeOut,
className = prefix + "Slideshow_",
click = "click." + prefix,
clear,
set,
start,
stop;
if (settings.slideshow && $related[1]) {
clear = function () {
clearTimeout(timeOut);
};
set = function () {
if (settings.loop || $related[index + 1]) {
timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
}
};
start = function () {
$slideshow
.html(settings.slideshowStop)
.unbind(click)
.one(click, stop);
$events
.bind(event_complete, set)
.bind(event_load, clear)
.bind(event_cleanup, stop);
$box.removeClass(className + "off").addClass(className + "on");
};
stop = function () {
clear();
$events
.unbind(event_complete, set)
.unbind(event_load, clear)
.unbind(event_cleanup, stop);
$slideshow
.html(settings.slideshowStart)
.unbind(click)
.one(click, function () {
publicMethod.next();
start();
});
$box.removeClass(className + "on").addClass(className + "off");
};
if (settings.slideshowAuto) {
start();
} else {
stop();
}
} else {
$box.removeClass(className + "off " + className + "on");
}
}
function launch(target) {
if (!closing) {
element = target;
makeSettings();
$related = $(element);
index = 0;
if (settings.rel !== 'nofollow') {
$related = $('.' + boxElement).filter(function () {
var data = $.data(this, colorbox),
relRelated;
if (data) {
relRelated = $(this).data('rel') || data.rel || this.rel;
}
return (relRelated === settings.rel);
});
index = $related.index(element);
// Check direct calls to ColorBox.
if (index === -1) {
$related = $related.add(element);
index = $related.length - 1;
}
}
$overlay.css({
opacity: parseFloat(settings.opacity),
cursor: settings.overlayClose ? "pointer" : "auto",
visibility: 'visible'
}).show();
if (className) {
$box.add($overlay).removeClass(className);
}
if (settings.className) {
$box.add($overlay).addClass(settings.className);
}
className = settings.className;
$close.html(settings.close).show();
if (!open) {
open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.
// Show colorbox so the sizes can be calculated in older versions of jQuery
$box.css({visibility:'hidden', display:'block'});
$loaded = $tag(div, 'LoadedContent', 'width:0; height:0; overflow:hidden').appendTo($content);
// Cache values needed for size calculations
interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6
interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
loadedHeight = $loaded.outerHeight(true);
loadedWidth = $loaded.outerWidth(true);
// Opens inital empty ColorBox prior to content being loaded.
settings.w = setSize(settings.initialWidth, 'x');
settings.h = setSize(settings.initialHeight, 'y');
publicMethod.position();
if (isIE6) {
$window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () {
$overlay.css({width: $window.width(), height: winheight(), top: $window.scrollTop(), left: $window.scrollLeft()});
}).trigger('resize.' + event_ie6);
}
slideshow();
trigger(event_open, settings.onOpen);
$groupControls.add($title).hide();
$box.focus();
// Confine focus to the modal
// Uses event capturing that is not supported in IE8-
if (document.addEventListener) {
document.addEventListener('focus', trapFocus, true);
$events.one(event_closed, function () {
document.removeEventListener('focus', trapFocus, true);
});
}
// Return focus on closing
if (settings.returnFocus) {
$events.one(event_closed, function () {
$(element).focus();
});
}
}
load();
}
}
// ColorBox's markup needs to be added to the DOM prior to being called
// so that the browser will go ahead and load the CSS background images.
function appendHTML() {
if (!$box && document.body) {
init = false;
$window = $(window);
$box = $tag(div).attr({
id: colorbox,
'class': isIE ? prefix + (isIE6 ? 'IE6' : 'IE') : '',
role: 'dialog',
tabindex: '-1'
}).hide();
$overlay = $tag(div, "Overlay", isIE6 ? 'position:absolute' : '').hide();
$loadingOverlay = $tag(div, "LoadingOverlay").add($tag(div, "LoadingGraphic"));
$wrap = $tag(div, "Wrapper");
$content = $tag(div, "Content").append(
$title = $tag(div, "Title"),
$current = $tag(div, "Current"),
$prev = $tag('button', "Previous"),
$next = $tag('button', "Next"),
$slideshow = $tag('button', "Slideshow"),
$loadingOverlay,
$close = $tag('button', "Close")
);
$wrap.append( // The 3x3 Grid that makes up ColorBox
$tag(div).append(
$tag(div, "TopLeft"),
$topBorder = $tag(div, "TopCenter"),
$tag(div, "TopRight")
),
$tag(div, false, 'clear:left').append(
$leftBorder = $tag(div, "MiddleLeft"),
$content,
$rightBorder = $tag(div, "MiddleRight")
),
$tag(div, false, 'clear:left').append(
$tag(div, "BottomLeft"),
$bottomBorder = $tag(div, "BottomCenter"),
$tag(div, "BottomRight")
)
).find('div div').css({'float': 'left'});
$loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none');
$groupControls = $next.add($prev).add($current).add($slideshow);
$(document.body).append($overlay, $box.append($wrap, $loadingBay));
}
}
// Add ColorBox's event bindings
function addBindings() {
function clickHandler(e) {
// ignore non-left-mouse-clicks and clicks modified with ctrl / command, shift, or alt.
// See: http://jacklmoore.com/notes/click-events/
if (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey)) {
e.preventDefault();
launch(this);
}
}
if ($box) {
if (!init) {
init = true;
// Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly.
$next.click(function () {
publicMethod.next();
});
$prev.click(function () {
publicMethod.prev();
});
$close.click(function () {
publicMethod.close();
});
$overlay.click(function () {
if (settings.overlayClose) {
publicMethod.close();
}
});
// Key Bindings
$(document).bind('keydown.' + prefix, function (e) {
var key = e.keyCode;
if (open && settings.escKey && key === 27) {
e.preventDefault();
publicMethod.close();
}
if (open && settings.arrowKey && $related[1] && !e.altKey) {
if (key === 37) {
e.preventDefault();
$prev.click();
} else if (key === 39) {
e.preventDefault();
$next.click();
}
}
});
if ($.isFunction($.fn.on)) {
// For jQuery 1.7+
$(document).on('click.'+prefix, '.'+boxElement, clickHandler);
} else {
// For jQuery 1.3.x -> 1.6.x
// This code is never reached in jQuery 1.9, so do not contact me about 'live' being removed.
// This is not here for jQuery 1.9, it's here for legacy users.
$('.'+boxElement).live('click.'+prefix, clickHandler);
}
}
return true;
}
return false;
}
// Don't do anything if ColorBox already exists.
if ($.colorbox) {
return;
}
// Append the HTML when the DOM loads
$(appendHTML);
// ****************
// PUBLIC FUNCTIONS
// Usage format: $.fn.colorbox.close();
// Usage from within an iframe: parent.$.fn.colorbox.close();
// ****************
publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
var $this = this;
options = options || {};
appendHTML();
if (addBindings()) {
if ($.isFunction($this)) { // assume a call to $.colorbox
$this = $('<a/>');
options.open = true;
} else if (!$this[0]) { // colorbox being applied to empty collection
return $this;
}
if (callback) {
options.onComplete = callback;
}
$this.each(function () {
$.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options));
}).addClass(boxElement);
if (($.isFunction(options.open) && options.open.call($this)) || options.open) {
launch($this[0]);
}
}
return $this;
};
publicMethod.position = function (speed, loadedCallback) {
var
css,
top = 0,
left = 0,
offset = $box.offset(),
scrollTop,
scrollLeft;
$window.unbind('resize.' + prefix);
// remove the modal so that it doesn't influence the document width/height
$box.css({top: -9e4, left: -9e4});
scrollTop = $window.scrollTop();
scrollLeft = $window.scrollLeft();
if (settings.fixed && !isIE6) {
offset.top -= scrollTop;
offset.left -= scrollLeft;
$box.css({position: 'fixed'});
} else {
top = scrollTop;
left = scrollLeft;
$box.css({position: 'absolute'});
}
// keeps the top and left positions within the browser's viewport.
if (settings.right !== false) {
left += Math.max($window.width() - settings.w - loadedWidth - interfaceWidth - setSize(settings.right, 'x'), 0);
} else if (settings.left !== false) {
left += setSize(settings.left, 'x');
} else {
left += Math.round(Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2);
}
if (settings.bottom !== false) {
top += Math.max(winheight() - settings.h - loadedHeight - interfaceHeight - setSize(settings.bottom, 'y'), 0);
} else if (settings.top !== false) {
top += setSize(settings.top, 'y');
} else {
top += Math.round(Math.max(winheight() - settings.h - loadedHeight - interfaceHeight, 0) / 2);
}
$box.css({top: offset.top, left: offset.left, visibility:'visible'});
// setting the speed to 0 to reduce the delay between same-sized content.
speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed || 0;
// this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
// but it has to be shrank down around the size of div#colorbox when it's done. If not,
// it can invoke an obscure IE bug when using iframes.
$wrap[0].style.width = $wrap[0].style.height = "9999px";
function modalDimensions(that) {
$topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = (parseInt(that.style.width,10) - interfaceWidth)+'px';
$content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = (parseInt(that.style.height,10) - interfaceHeight)+'px';
}
css = {width: settings.w + loadedWidth + interfaceWidth, height: settings.h + loadedHeight + interfaceHeight, top: top, left: left};
if(speed===0){ // temporary workaround to side-step jQuery-UI 1.8 bug (http://bugs.jquery.com/ticket/12273)
$box.css(css);
}
$box.dequeue().animate(css, {
duration: speed,
complete: function () {
modalDimensions(this);
active = false;
// shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.
$wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px";
$wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px";
if (settings.reposition) {
setTimeout(function () { // small delay before binding onresize due to an IE8 bug.
$window.bind('resize.' + prefix, publicMethod.position);
}, 1);
}
if (loadedCallback) {
loadedCallback();
}
},
step: function () {
modalDimensions(this);
}
});
};
publicMethod.resize = function (options) {
if (open) {
options = options || {};
if (options.width) {
settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;
}
if (options.innerWidth) {
settings.w = setSize(options.innerWidth, 'x');
}
$loaded.css({width: settings.w});
if (options.height) {
settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;
}
if (options.innerHeight) {
settings.h = setSize(options.innerHeight, 'y');
}
if (!options.innerHeight && !options.height) {
$loaded.css({height: "auto"});
settings.h = $loaded.height();
}
$loaded.css({height: settings.h});
publicMethod.position(settings.transition === "none" ? 0 : settings.speed);
}
};
publicMethod.prep = function (object) {
if (!open) {
return;
}
var callback, speed = settings.transition === "none" ? 0 : settings.speed;
$loaded.empty().remove(); // Using empty first may prevent some IE7 issues.
$loaded = $tag(div, 'LoadedContent').append(object);
function getWidth() {
settings.w = settings.w || $loaded.width();
settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;
return settings.w;
}
function getHeight() {
settings.h = settings.h || $loaded.height();
settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;
return settings.h;
}
$loaded.hide()
.appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.
.css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'})
.css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.
.prependTo($content);
$loadingBay.hide();
// floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.
$(photo).css({'float': 'none'});
callback = function () {
var total = $related.length,
iframe,
frameBorder = 'frameBorder',
allowTransparency = 'allowTransparency',
complete;
if (!open) {
return;
}
function removeFilter() {
if (isIE) {
$box[0].style.removeAttribute('filter');
}
}
complete = function () {
clearTimeout(loadingTimer);
$loadingOverlay.hide();
trigger(event_complete, settings.onComplete);
};
if (isIE) {
//This fadeIn helps the bicubic resampling to kick-in.
if (photo) {
$loaded.fadeIn(100);
}
}
$title.html(settings.title).add($loaded).show();
if (total > 1) { // handle grouping
if (typeof settings.current === "string") {
$current.html(settings.current.replace('{current}', index + 1).replace('{total}', total)).show();
}
$next[(settings.loop || index < total - 1) ? "show" : "hide"]().html(settings.next);
$prev[(settings.loop || index) ? "show" : "hide"]().html(settings.previous);
if (settings.slideshow) {
$slideshow.show();
}
// Preloads images within a rel group
if (settings.preloading) {
$.each([getIndex(-1), getIndex(1)], function(){
var src,
img,
i = $related[this],
data = $.data(i, colorbox);
if (data && data.href) {
src = data.href;
if ($.isFunction(src)) {
src = src.call(i);
}
} else {
src = $(i).attr('href');
}
if (src && isImage(data, src)) {
src = retinaUrl(data, src);
img = new Image();
img.src = src;
}
});
}
} else {
$groupControls.hide();
}
if (settings.iframe) {
iframe = $tag('iframe')[0];
if (frameBorder in iframe) {
iframe[frameBorder] = 0;
}
if (allowTransparency in iframe) {
iframe[allowTransparency] = "true";
}
if (!settings.scrolling) {
iframe.scrolling = "no";
}
$(iframe)
.attr({
src: settings.href,
name: (new Date()).getTime(), // give the iframe a unique name to prevent caching
'class': prefix + 'Iframe',
allowFullScreen : true, // allow HTML5 video to go fullscreen
webkitAllowFullScreen : true,
mozallowfullscreen : true
})
.one('load', complete)
.appendTo($loaded);
$events.one(event_purge, function () {
iframe.src = "//about:blank";
});
if (settings.fastIframe) {
$(iframe).trigger('load');
}
} else {
complete();
}
if (settings.transition === 'fade') {
$box.fadeTo(speed, 1, removeFilter);
} else {
removeFilter();
}
};
if (settings.transition === 'fade') {
$box.fadeTo(speed, 0, function () {
publicMethod.position(0, callback);
});
} else {
publicMethod.position(speed, callback);
}
};
function load () {
var href, setResize, prep = publicMethod.prep, $inline, request = ++requests;
active = true;
photo = false;
element = $related[index];
makeSettings();
trigger(event_purge);
trigger(event_load, settings.onLoad);
settings.h = settings.height ?
setSize(settings.height, 'y') - loadedHeight - interfaceHeight :
settings.innerHeight && setSize(settings.innerHeight, 'y');
settings.w = settings.width ?
setSize(settings.width, 'x') - loadedWidth - interfaceWidth :
settings.innerWidth && setSize(settings.innerWidth, 'x');
// Sets the minimum dimensions for use in image scaling
settings.mw = settings.w;
settings.mh = settings.h;
// Re-evaluate the minimum width and height based on maxWidth and maxHeight values.
// If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.
if (settings.maxWidth) {
settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth;
settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;
}
if (settings.maxHeight) {
settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight;
settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;
}
href = settings.href;
loadingTimer = setTimeout(function () {
$loadingOverlay.show();
}, 100);
if (settings.inline) {
// Inserts an empty placeholder where inline content is being pulled from.
// An event is bound to put inline content back when ColorBox closes or loads new content.
$inline = $tag(div).hide().insertBefore($(href)[0]);
$events.one(event_purge, function () {
$inline.replaceWith($loaded.children());
});
prep($(href));
} else if (settings.iframe) {
// IFrame element won't be added to the DOM until it is ready to be displayed,
// to avoid problems with DOM-ready JS that might be trying to run in that iframe.
prep(" ");
} else if (settings.html) {
prep(settings.html);
} else if (isImage(settings, href)) {
href = retinaUrl(settings, href);
$(photo = new Image())
.addClass(prefix + 'Photo')
.bind('error',function () {
settings.title = false;
prep($tag(div, 'Error').html(settings.imgError));
})
.one('load', function () {
var percent;
if (request !== requests) {
return;
}
if (settings.retinaImage && window.devicePixelRatio > 1) {
photo.height = photo.height / window.devicePixelRatio;
photo.width = photo.width / window.devicePixelRatio;
}
if (settings.scalePhotos) {
setResize = function () {
photo.height -= photo.height * percent;
photo.width -= photo.width * percent;
};
if (settings.mw && photo.width > settings.mw) {
percent = (photo.width - settings.mw) / photo.width;
setResize();
}
if (settings.mh && photo.height > settings.mh) {
percent = (photo.height - settings.mh) / photo.height;
setResize();
}
}
if (settings.h) {
photo.style.marginTop = Math.max(settings.mh - photo.height, 0) / 2 + 'px';
}
if ($related[1] && (settings.loop || $related[index + 1])) {
photo.style.cursor = 'pointer';
photo.onclick = function () {
publicMethod.next();
};
}
if (isIE) {
photo.style.msInterpolationMode = 'bicubic';
}
setTimeout(function () { // A pause because Chrome will sometimes report a 0 by 0 size otherwise.
prep(photo);
}, 1);
});
setTimeout(function () { // A pause because Opera 10.6+ will sometimes not run the onload function otherwise.
photo.src = href;
}, 1);
} else if (href) {
$loadingBay.load(href, settings.data, function (data, status) {
if (request === requests) {
prep(status === 'error' ? $tag(div, 'Error').html(settings.xhrError) : $(this).contents());
}
});
}
}
// Navigates to the next page/image in a set.
publicMethod.next = function () {
if (!active && $related[1] && (settings.loop || $related[index + 1])) {
index = getIndex(1);
launch($related[index]);
}
};
publicMethod.prev = function () {
if (!active && $related[1] && (settings.loop || index)) {
index = getIndex(-1);
launch($related[index]);
}
};
// Note: to use this within an iframe use the following format: parent.$.fn.colorbox.close();
publicMethod.close = function () {
if (open && !closing) {
closing = true;
open = false;
trigger(event_cleanup, settings.onCleanup);
$window.unbind('.' + prefix + ' .' + event_ie6);
$overlay.fadeTo(200, 0);
$box.stop().fadeTo(300, 0, function () {
$box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide();
trigger(event_purge);
$loaded.empty().remove(); // Using empty first may prevent some IE7 issues.
setTimeout(function () {
closing = false;
trigger(event_closed, settings.onClosed);
}, 1);
});
}
};
// Removes changes ColorBox made to the document, but does not remove the plugin
// from jQuery.
publicMethod.remove = function () {
$([]).add($box).add($overlay).remove();
$box = null;
$('.' + boxElement)
.removeData(colorbox)
.removeClass(boxElement);
$(document).unbind('click.'+prefix);
};
// A method for fetching the current element ColorBox is referencing.
// returns a jQuery object.
publicMethod.element = function () {
return $(element);
};
publicMethod.settings = defaults;
}(jQuery, document, window));
/**
* jQuery Galleriffic plugin
*
* Copyright (c) 2008 Trent Foley (http://trentacular.com)
* Licensed under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*
* Much thanks to primary contributer Ponticlaro (http://www.ponticlaro.com)
*
* Modifed by Jay Hayes (http://iamvery.com)
*/
;(function($) {
// Globally keep track of all images by their unique hash. Each item is an image data object.
var allImages = {};
var imageCounter = 0;
// Galleriffic static class
$.galleriffic = {
version: '2.0.3',
// Strips invalid characters and any leading # characters
normalizeHash: function(hash) {
return hash.replace(/^.*#/, '').replace(/\?.*$/, '');
},
getImage: function(hash) {
if (!hash)
return undefined;
hash = $.galleriffic.normalizeHash(hash);
return allImages[hash];
},
// Global function that looks up an image by its hash and displays the image.
// Returns false when an image is not found for the specified hash.
// @param {String} hash This is the unique hash value assigned to an image.
gotoImage: function(hash) {
var imageData = $.galleriffic.getImage(hash);
if (!imageData)
return false;
var gallery = imageData.gallery;
gallery.gotoImage(imageData);
return true;
},
// Removes an image from its respective gallery by its hash.
// Returns false when an image is not found for the specified hash or the
// specified owner gallery does match the located images gallery.
// @param {String} hash This is the unique hash value assigned to an image.
// @param {Object} ownerGallery (Optional) When supplied, the located images
// gallery is verified to be the same as the specified owning gallery before
// performing the remove operation.
removeImageByHash: function(hash, ownerGallery) {
var imageData = $.galleriffic.getImage(hash);
if (!imageData)
return false;
var gallery = imageData.gallery;
if (ownerGallery && ownerGallery != gallery)
return false;
return gallery.removeImageByIndex(imageData.index);
}
};
var defaults = {
delay: 3000,
numThumbs: 20,
preloadAhead: 40, // Set to -1 to preload all images
enableTopPager: false,
enableBottomPager: true,
maxPagesToShow: 7,
imageContainerSel: '',
captionContainerSel: '',
ssControlsContainerSel: '',
navControlsContainerSel: '',
loadingContainerSel: '',
playLinkText: 'Play',
pauseLinkText: 'Pause',
prevLinkText: 'Previous',
nextLinkText: 'Next',
nextPageLinkText: 'Next &rsaquo;',
prevPageLinkText: '&lsaquo; Prev',
enableHistory: false,
enableKeyboardNavigation: true,
autoStart: false,
syncTransitions: false,
defaultTransitionDuration: 1000,
onSlideChange: undefined, // accepts a delegate like such: function(prevIndex, nextIndex) { ... }
onTransitionOut: undefined, // accepts a delegate like such: function(slide, caption, isSync, callback) { ... }
onTransitionIn: undefined, // accepts a delegate like such: function(slide, caption, isSync) { ... }
onPageTransitionOut: undefined, // accepts a delegate like such: function(callback) { ... }
onPageTransitionIn: undefined, // accepts a delegate like such: function() { ... }
onImageAdded: undefined, // accepts a delegate like such: function(imageData, $li) { ... }
onImageRemoved: undefined // accepts a delegate like such: function(imageData, $li) { ... }
};
// Primary Galleriffic initialization function that should be called on the thumbnail container.
$.fn.galleriffic = function(settings) {
// Extend Gallery Object
$.extend(this, {
// Returns the version of the script
version: $.galleriffic.version,
// Current state of the slideshow
isSlideshowRunning: false,
slideshowTimeout: undefined,
// This function is attached to the click event of generated hyperlinks within the gallery
clickHandler: function(e, link) {
this.pause();
if (!this.enableHistory) {
// The href attribute holds the unique hash for an image
var hash = $.galleriffic.normalizeHash($(link).attr('href'));
$.galleriffic.gotoImage(hash);
e.preventDefault();
}
},
// Appends an image to the end of the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html.
// @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
appendImage: function(listItem) {
this.addImage(listItem, false, false);
return this;
},
// Inserts an image into the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html.
// @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
// @param {Integer} position The index within the gallery where the item shouold be added.
insertImage: function(listItem, position) {
this.addImage(listItem, false, true, position);
return this;
},
// Adds an image to the gallery and optionally inserts/appends it to the DOM (thumbExists)
// @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
// @param {Boolean} thumbExists Specifies whether the thumbnail already exists in the DOM or if it needs to be added.
// @param {Boolean} insert Specifies whether the the image is appended to the end or inserted into the gallery.
// @param {Integer} position The index within the gallery where the item shouold be added.
addImage: function(listItem, thumbExists, insert, position) {
var $li = ( typeof listItem === "string" ) ? $(listItem) : listItem;
var $aThumb = $li.find('a.thumb');
var slideUrl = $aThumb.attr('href');
var title = $aThumb.attr('title');
var $caption = $li.find('.caption').remove();
var hash = $aThumb.attr('name');
// Increment the image counter
imageCounter++;
// Autogenerate a hash value if none is present or if it is a duplicate
if (!hash || allImages[''+hash]) {
hash = imageCounter;
}
// Set position to end when not specified
if (!insert)
position = this.data.length;
var imageData = {
title:title,
slideUrl:slideUrl,
caption:$caption,
hash:hash,
gallery:this,
index:position
};
// Add the imageData to this gallery's array of images
if (insert) {
this.data.splice(position, 0, imageData);
// Reset index value on all imageData objects
this.updateIndices(position);
}
else {
this.data.push(imageData);
}
var gallery = this;
// Add the element to the DOM
if (!thumbExists) {
// Update thumbs passing in addition post transition out handler
this.updateThumbs(function() {
var $thumbsUl = gallery.find('ul.thumbs');
if (insert)
$thumbsUl.children(':eq('+position+')').before($li);
else
$thumbsUl.append($li);
if (gallery.onImageAdded)
gallery.onImageAdded(imageData, $li);
});
}
// Register the image globally
allImages[''+hash] = imageData;
// Setup attributes and click handler
$aThumb.attr('rel', 'history')
.attr('href', '#'+hash)
.removeAttr('name')
.click(function(e) {
gallery.clickHandler(e, this);
});
return this;
},
// Removes an image from the gallery based on its index.
// Returns false when the index is out of range.
removeImageByIndex: function(index) {
if (index < 0 || index >= this.data.length)
return false;
var imageData = this.data[index];
if (!imageData)
return false;
this.removeImage(imageData);
return true;
},
// Convenience method that simply calls the global removeImageByHash method.
removeImageByHash: function(hash) {
return $.galleriffic.removeImageByHash(hash, this);
},
// Removes an image from the gallery.
removeImage: function(imageData) {
var index = imageData.index;
// Remove the image from the gallery data array
this.data.splice(index, 1);
// Remove the global registration
delete allImages[''+imageData.hash];
// Remove the image's list item from the DOM
this.updateThumbs(function() {
var $li = gallery.find('ul.thumbs')
.children(':eq('+index+')')
.remove();
if (gallery.onImageRemoved)
gallery.onImageRemoved(imageData, $li);
});
// Update each image objects index value
this.updateIndices(index);
return this;
},
// Updates the index values of the each of the images in the gallery after the specified index
updateIndices: function(startIndex) {
for (i = startIndex; i < this.data.length; i++) {
this.data[i].index = i;
}
return this;
},
// Scraped the thumbnail container for thumbs and adds each to the gallery
initializeThumbs: function() {
this.data = [];
var gallery = this;
this.find('ul.thumbs > li').each(function(i) {
gallery.addImage($(this), true, false);
});
return this;
},
isPreloadComplete: false,
// Initalizes the image preloader
preloadInit: function() {
if (this.preloadAhead == 0) return this;
this.preloadStartIndex = this.currentImage.index;
var nextIndex = this.getNextIndex(this.preloadStartIndex);
return this.preloadRecursive(this.preloadStartIndex, nextIndex);
},
// Changes the location in the gallery the preloader should work
// @param {Integer} index The index of the image where the preloader should restart at.
preloadRelocate: function(index) {
// By changing this startIndex, the current preload script will restart
this.preloadStartIndex = index;
return this;
},
// Recursive function that performs the image preloading
// @param {Integer} startIndex The index of the first image the current preloader started on.
// @param {Integer} currentIndex The index of the current image to preload.
preloadRecursive: function(startIndex, currentIndex) {
// Check if startIndex has been relocated
if (startIndex != this.preloadStartIndex) {
var nextIndex = this.getNextIndex(this.preloadStartIndex);
return this.preloadRecursive(this.preloadStartIndex, nextIndex);
}
var gallery = this;
// Now check for preloadAhead count
var preloadCount = currentIndex - startIndex;
if (preloadCount < 0)
preloadCount = this.data.length-1-startIndex+currentIndex;
if (this.preloadAhead >= 0 && preloadCount > this.preloadAhead) {
// Do this in order to keep checking for relocated start index
setTimeout(function() { gallery.preloadRecursive(startIndex, currentIndex); }, 500);
return this;
}
var imageData = this.data[currentIndex];
if (!imageData)
return this;
// If already loaded, continue
if (imageData.image)
return this.preloadNext(startIndex, currentIndex);
// Preload the image
var image = new Image();
image.onload = function() {
imageData.image = this;
gallery.preloadNext(startIndex, currentIndex);
};
image.alt = imageData.title;
image.src = imageData.slideUrl;
return this;
},
// Called by preloadRecursive in order to preload the next image after the previous has loaded.
// @param {Integer} startIndex The index of the first image the current preloader started on.
// @param {Integer} currentIndex The index of the current image to preload.
preloadNext: function(startIndex, currentIndex) {
var nextIndex = this.getNextIndex(currentIndex);
if (nextIndex == startIndex) {
this.isPreloadComplete = true;
} else {
// Use setTimeout to free up thread
var gallery = this;
setTimeout(function() { gallery.preloadRecursive(startIndex, nextIndex); }, 100);
}
return this;
},
// Safe way to get the next image index relative to the current image.
// If the current image is the last, returns 0
getNextIndex: function(index) {
var nextIndex = index+1;
if (nextIndex >= this.data.length)
nextIndex = 0;
return nextIndex;
},
// Safe way to get the previous image index relative to the current image.
// If the current image is the first, return the index of the last image in the gallery.
getPrevIndex: function(index) {
var prevIndex = index-1;
if (prevIndex < 0)
prevIndex = this.data.length-1;
return prevIndex;
},
// Pauses the slideshow
pause: function() {
this.isSlideshowRunning = false;
if (this.slideshowTimeout) {
clearTimeout(this.slideshowTimeout);
this.slideshowTimeout = undefined;
}
if (this.$ssControlsContainer) {
this.$ssControlsContainer
.find('div.ss-controls a').removeClass().addClass('play')
.attr('title', this.playLinkText)
.attr('href', '#play')
.html(this.playLinkText);
}
return this;
},
// Plays the slideshow
play: function() {
this.isSlideshowRunning = true;
if (this.$ssControlsContainer) {
this.$ssControlsContainer
.find('div.ss-controls a').removeClass().addClass('pause')
.attr('title', this.pauseLinkText)
.attr('href', '#pause')
.html(this.pauseLinkText);
}
if (!this.slideshowTimeout) {
var gallery = this;
this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);
}
return this;
},
// Toggles the state of the slideshow (playing/paused)
toggleSlideshow: function() {
if (this.isSlideshowRunning)
this.pause();
else
this.play();
return this;
},
// Advances the slideshow to the next image and delegates navigation to the
// history plugin when history is enabled
// enableHistory is true
ssAdvance: function() {
if (this.isSlideshowRunning)
this.next(true);
return this;
},
// Advances the gallery to the next image.
// @param {Boolean} dontPause Specifies whether to pause the slideshow.
// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
next: function(dontPause, bypassHistory) {
this.gotoIndex(this.getNextIndex(this.currentImage.index), dontPause, bypassHistory);
return this;
},
// Navigates to the previous image in the gallery.
// @param {Boolean} dontPause Specifies whether to pause the slideshow.
// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
previous: function(dontPause, bypassHistory) {
this.gotoIndex(this.getPrevIndex(this.currentImage.index), dontPause, bypassHistory);
return this;
},
// Navigates to the next page in the gallery.
// @param {Boolean} dontPause Specifies whether to pause the slideshow.
// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
nextPage: function(dontPause, bypassHistory) {
var page = this.getCurrentPage();
var lastPage = this.getNumPages() - 1;
if (page < lastPage) {
var startIndex = page * this.numThumbs;
var nextPage = startIndex + this.numThumbs;
this.gotoIndex(nextPage, dontPause, bypassHistory);
}
return this;
},
// Navigates to the previous page in the gallery.
// @param {Boolean} dontPause Specifies whether to pause the slideshow.
// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
previousPage: function(dontPause, bypassHistory) {
var page = this.getCurrentPage();
if (page > 0) {
var startIndex = page * this.numThumbs;
var prevPage = startIndex - this.numThumbs;
this.gotoIndex(prevPage, dontPause, bypassHistory);
}
return this;
},
// Navigates to the image at the specified index in the gallery
// @param {Integer} index The index of the image in the gallery to display.
// @param {Boolean} dontPause Specifies whether to pause the slideshow.
// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
gotoIndex: function(index, dontPause, bypassHistory) {
if (!dontPause)
this.pause();
if (index < 0) index = 0;
else if (index >= this.data.length) index = this.data.length-1;
var imageData = this.data[index];
if (!bypassHistory && this.enableHistory)
$.history.load(String(imageData.hash)); // At the moment, history.load only accepts string arguments
else
this.gotoImage(imageData);
return this;
},
// This function is garaunteed to be called anytime a gallery slide changes.
// @param {Object} imageData An object holding the image metadata of the image to navigate to.
gotoImage: function(imageData) {
var index = imageData.index;
// Prevent reloading same image
if (this.currentImage && this.currentImage.index == index)
return this;
if (this.onSlideChange && this.currentImage)
this.onSlideChange(this.currentImage.index, index);
this.currentImage = imageData;
this.preloadRelocate(index);
this.refresh();
return this;
},
// Returns the default transition duration value. The value is halved when not
// performing a synchronized transition.
// @param {Boolean} isSync Specifies whether the transitions are synchronized.
getDefaultTransitionDuration: function(isSync) {
if (isSync)
return this.defaultTransitionDuration;
return this.defaultTransitionDuration / 2;
},
// Rebuilds the slideshow image and controls and performs transitions
refresh: function() {
var imageData = this.currentImage;
if (!imageData)
return this;
var index = imageData.index;
// Update Controls
if (this.$navControlsContainer) {
this.$navControlsContainer
.find('div.nav-controls a.prev').attr('href', '#'+this.data[this.getPrevIndex(index)].hash).end()
.find('div.nav-controls a.next').attr('href', '#'+this.data[this.getNextIndex(index)].hash);
}
var previousSlide = this.$imageContainer.find('span.current').addClass('previous').removeClass('current');
var previousCaption = 0;
if (this.$captionContainer) {
previousCaption = this.$captionContainer.find('span.current').addClass('previous').removeClass('current');
}
// Perform transitions simultaneously if syncTransitions is true and the next image is already preloaded
var isSync = this.syncTransitions && imageData.image;
// Flag we are transitioning
var isTransitioning = true;
var gallery = this;
var transitionOutCallback = function() {
// Flag that the transition has completed
isTransitioning = false;
// Remove the old slide
previousSlide.remove();
// Remove old caption
if (previousCaption)
previousCaption.remove();
if (!isSync) {
if (imageData.image && imageData.hash == gallery.data[gallery.currentImage.index].hash) {
gallery.buildImage(imageData, isSync);
} else {
// Show loading container
if (gallery.$loadingContainer) {
gallery.$loadingContainer.show();
}
}
}
};
if (previousSlide.length == 0) {
// For the first slide, the previous slide will be empty, so we will call the callback immediately
transitionOutCallback();
} else {
if (this.onTransitionOut) {
this.onTransitionOut(previousSlide, previousCaption, isSync, transitionOutCallback);
} else {
previousSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0, transitionOutCallback);
if (previousCaption)
previousCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0);
}
}
// Go ahead and begin transitioning in of next image
if (isSync)
this.buildImage(imageData, isSync);
if (!imageData.image) {
var image = new Image();
// Wire up mainImage onload event
image.onload = function() {
imageData.image = this;
// Only build image if the out transition has completed and we are still on the same image hash
if (!isTransitioning && imageData.hash == gallery.data[gallery.currentImage.index].hash) {
gallery.buildImage(imageData, isSync);
}
};
// set alt and src
image.alt = imageData.title;
image.src = imageData.slideUrl;
}
// This causes the preloader (if still running) to relocate out from the currentIndex
this.relocatePreload = true;
return this.syncThumbs();
},
// Called by the refresh method after the previous image has been transitioned out or at the same time
// as the out transition when performing a synchronous transition.
// @param {Object} imageData An object holding the image metadata of the image to build.
// @param {Boolean} isSync Specifies whether the transitions are synchronized.
buildImage: function(imageData, isSync) {
var gallery = this;
var nextIndex = this.getNextIndex(imageData.index);
// Construct new hidden span for the image
var newSlide = this.$imageContainer
.append('<span class="image-wrapper current"><a class="advance-link" rel="history" href="#'+this.data[nextIndex].hash+'" title="'+imageData.title+'">&nbsp;</a></span>')
.find('span.current').css('opacity', '0');
newSlide.find('a')
.append(imageData.image)
.click(function(e) {
gallery.clickHandler(e, this);
});
var newCaption = 0;
if (this.$captionContainer) {
// Construct new hidden caption for the image
newCaption = this.$captionContainer
.append('<span class="image-caption current"></span>')
.find('span.current').css('opacity', '0')
.append(imageData.caption);
}
// Hide the loading conatiner
if (this.$loadingContainer) {
this.$loadingContainer.hide();
}
// Transition in the new image
if (this.onTransitionIn) {
this.onTransitionIn(newSlide, newCaption, isSync);
} else {
newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
if (newCaption)
newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
}
if (this.isSlideshowRunning) {
if (this.slideshowTimeout)
clearTimeout(this.slideshowTimeout);
this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);
}
return this;
},
// Returns the current page index that should be shown for the currentImage
getCurrentPage: function() {
return Math.floor(this.currentImage.index / this.numThumbs);
},
// Applies the selected class to the current image's corresponding thumbnail.
// Also checks if the current page has changed and updates the displayed page of thumbnails if necessary.
syncThumbs: function() {
var page = this.getCurrentPage();
if (page != this.displayedPage)
this.updateThumbs();
// Remove existing selected class and add selected class to new thumb
var $thumbs = this.find('ul.thumbs').children();
$thumbs.filter('.selected').removeClass('selected');
$thumbs.eq(this.currentImage.index).addClass('selected');
return this;
},
// Performs transitions on the thumbnails container and updates the set of
// thumbnails that are to be displayed and the navigation controls.
// @param {Delegate} postTransitionOutHandler An optional delegate that is called after
// the thumbnails container has transitioned out and before the thumbnails are rebuilt.
updateThumbs: function(postTransitionOutHandler) {
var gallery = this;
var transitionOutCallback = function() {
// Call the Post-transition Out Handler
if (postTransitionOutHandler)
postTransitionOutHandler();
gallery.rebuildThumbs();
// Transition In the thumbsContainer
if (gallery.onPageTransitionIn)
gallery.onPageTransitionIn();
else
gallery.show();
};
// Transition Out the thumbsContainer
if (this.onPageTransitionOut) {
this.onPageTransitionOut(transitionOutCallback);
} else {
this.hide();
transitionOutCallback();
}
return this;
},
// Updates the set of thumbnails that are to be displayed and the navigation controls.
rebuildThumbs: function() {
var needsPagination = this.data.length > this.numThumbs;
// Rebuild top pager
if (this.enableTopPager) {
var $topPager = this.find('div.top');
if ($topPager.length == 0)
$topPager = this.prepend('<div class="top pagination"></div>').find('div.top');
else
$topPager.empty();
if (needsPagination)
this.buildPager($topPager);
}
// Rebuild bottom pager
if (this.enableBottomPager) {
var $bottomPager = this.find('div.bottom');
if ($bottomPager.length == 0)
$bottomPager = this.append('<div class="bottom pagination"></div>').find('div.bottom');
else
$bottomPager.empty();
if (needsPagination)
this.buildPager($bottomPager);
}
var page = this.getCurrentPage();
var startIndex = page*this.numThumbs;
var stopIndex = startIndex+this.numThumbs-1;
if (stopIndex >= this.data.length)
stopIndex = this.data.length-1;
// Show/Hide thumbs
var $thumbsUl = this.find('ul.thumbs');
$thumbsUl.find('li').each(function(i) {
var $li = $(this);
if (i >= startIndex && i <= stopIndex) {
$li.show();
} else {
$li.hide();
}
});
this.displayedPage = page;
// Remove the noscript class from the thumbs container ul
$thumbsUl.removeClass('noscript');
return this;
},
// Returns the total number of pages required to display all the thumbnails.
getNumPages: function() {
return Math.ceil(this.data.length/this.numThumbs);
},
// Rebuilds the pager control in the specified matched element.
// @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.
buildPager: function(pager) {
var gallery = this;
var numPages = this.getNumPages();
var page = this.getCurrentPage();
var startIndex = page * this.numThumbs;
var pagesRemaining = this.maxPagesToShow - 1;
var pageNum = page - Math.floor((this.maxPagesToShow - 1) / 2) + 1;
if (pageNum > 0) {
var remainingPageCount = numPages - pageNum;
if (remainingPageCount < pagesRemaining) {
pageNum = pageNum - (pagesRemaining - remainingPageCount);
}
}
if (pageNum < 0) {
pageNum = 0;
}
// Prev Page Link
if (page > 0) {
var prevPage = startIndex - this.numThumbs;
pager.append('<a rel="history" href="#'+this.data[prevPage].hash+'" title="'+this.prevPageLinkText+'">'+this.prevPageLinkText+'</a>');
}
// Create First Page link if needed
if (pageNum > 0) {
this.buildPageLink(pager, 0, numPages);
if (pageNum > 1)
pager.append('<span class="ellipsis">&hellip;</span>');
pagesRemaining--;
}
// Page Index Links
while (pagesRemaining > 0) {
this.buildPageLink(pager, pageNum, numPages);
pagesRemaining--;
pageNum++;
}
// Create Last Page link if needed
if (pageNum < numPages) {
var lastPageNum = numPages - 1;
if (pageNum < lastPageNum)
pager.append('<span class="ellipsis">&hellip;</span>');
this.buildPageLink(pager, lastPageNum, numPages);
}
// Next Page Link
var nextPage = startIndex + this.numThumbs;
if (nextPage < this.data.length) {
pager.append('<a rel="history" href="#'+this.data[nextPage].hash+'" title="'+this.nextPageLinkText+'">'+this.nextPageLinkText+'</a>');
}
pager.find('a').click(function(e) {
gallery.clickHandler(e, this);
});
return this;
},
// Builds a single page link within a pager. This function is called by buildPager
// @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.
// @param {Integer} pageNum The page number of the page link to build.
// @param {Integer} numPages The total number of pages required to display all thumbnails.
buildPageLink: function(pager, pageNum, numPages) {
var pageLabel = pageNum + 1;
var currentPage = this.getCurrentPage();
if (pageNum == currentPage)
pager.append('<span class="current">'+pageLabel+'</span>');
else if (pageNum < numPages) {
var imageIndex = pageNum*this.numThumbs;
pager.append('<a rel="history" href="#'+this.data[imageIndex].hash+'" title="'+pageLabel+'">'+pageLabel+'</a>');
}
return this;
}
});
// Now initialize the gallery
$.extend(this, defaults, settings);
// Verify the history plugin is available
if (this.enableHistory && !$.history)
this.enableHistory = false;
// Select containers
if (this.imageContainerSel) this.$imageContainer = $(this.imageContainerSel);
if (this.captionContainerSel) this.$captionContainer = $(this.captionContainerSel);
if (this.loadingContainerSel) this.$loadingContainer = $(this.loadingContainerSel);
// Initialize the thumbails
this.initializeThumbs();
if (this.maxPagesToShow < 3)
this.maxPagesToShow = 3;
this.displayedPage = -1;
var gallery = this;
// Hide the loadingContainer
if (this.$loadingContainer)
this.$loadingContainer.hide();
// Setup controls
if (this.ssControlsContainerSel) {
this.$ssControlsContainer = $(this.ssControlsContainerSel).empty();
if (this.autoStart) {
this.$ssControlsContainer
.append('<div class="ss-controls"><a href="#pause" class="pause" title="'+this.pauseLinkText+'">'+this.pauseLinkText+'</a></div>');
} else {
this.$ssControlsContainer
.append('<div class="ss-controls"><a href="#play" class="play" title="'+this.playLinkText+'">'+this.playLinkText+'</a></div>');
}
this.$ssControlsContainer.find('div.ss-controls a')
.click(function(e) {
gallery.toggleSlideshow();
e.preventDefault();
return false;
});
}
if (this.navControlsContainerSel) {
this.$navControlsContainer = $(this.navControlsContainerSel).empty();
this.$navControlsContainer
.append('<div class="nav-controls"><a class="prev" rel="history" title="'+this.prevLinkText+'">'+this.prevLinkText+'</a><a class="next" rel="history" title="'+this.nextLinkText+'">'+this.nextLinkText+'</a></div>')
.find('div.nav-controls a')
.click(function(e) {
gallery.clickHandler(e, this);
});
}
var initFirstImage = !this.enableHistory || !location.hash;
if (this.enableHistory && location.hash) {
var hash = $.galleriffic.normalizeHash(location.hash);
var imageData = allImages[hash];
if (!imageData)
initFirstImage = true;
}
// Setup gallery to show the first image
if (initFirstImage)
this.gotoIndex(0, false, true);
// Setup Keyboard Navigation
if (this.enableKeyboardNavigation) {
$(document).keydown(function(e) {
var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
switch(key) {
case 32: // space
gallery.next();
e.preventDefault();
break;
case 33: // Page Up
gallery.previousPage();
e.preventDefault();
break;
case 34: // Page Down
gallery.nextPage();
e.preventDefault();
break;
case 35: // End
gallery.gotoIndex(gallery.data.length-1);
e.preventDefault();
break;
case 36: // Home
gallery.gotoIndex(0);
e.preventDefault();
break;
case 37: // left arrow
gallery.previous();
e.preventDefault();
break;
case 39: // right arrow
gallery.next();
e.preventDefault();
break;
}
});
}
// Auto start the slideshow
if (this.autoStart)
this.play();
// Kickoff Image Preloader after 1 second
setTimeout(function() { gallery.preloadInit(); }, 1000);
return this;
};
})(jQuery);
/*
* CSS Styles that are needed by jScrollPane for it to operate correctly.
*
* Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane
* may not operate correctly without them.
*/
.jspContainer
{
overflow: hidden;
position: relative;
}
.jspPane
{
position: absolute;
}
.jspVerticalBar
{
position: absolute;
top: 0;
right: 0;
width: 16px;
height: 100%;
background: red;
}
.jspHorizontalBar
{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 16px;
background: red;
}
.jspVerticalBar *,
.jspHorizontalBar *
{
margin: 0;
padding: 0;
}
.jspCap
{
display: none;
}
.jspHorizontalBar .jspCap
{
float: left;
}
.jspTrack
{
background: #dde;
position: relative;
}
.jspDrag
{
background: #bbd;
position: relative;
top: 0;
left: 0;
cursor: pointer;
}
.jspHorizontalBar .jspTrack,
.jspHorizontalBar .jspDrag
{
float: left;
height: 100%;
}
.jspArrow
{
background: #50506d;
text-indent: -20000px;
display: block;
cursor: pointer;
}
.jspArrow.jspDisabled
{
cursor: default;
background: #80808d;
}
.jspVerticalBar .jspArrow
{
height: 16px;
}
.jspHorizontalBar .jspArrow
{
width: 16px;
float: left;
height: 100%;
}
.jspVerticalBar .jspArrow:focus
{
outline: none;
}
.jspCorner
{
background: #eeeef4;
float: left;
height: 100%;
}
/* Yuk! CSS Hack for IE6 3 pixel bug :( */
* html .jspCorner
{
margin: 0 -3px 0 0;
}
/*
* jScrollPane - v2.0.0beta12 - 2012-09-27
* http://jscrollpane.kelvinluck.com/
*
* Copyright (c) 2010 Kelvin Luck
* Dual licensed under the MIT or GPL licenses.
*/
(function(b,a,c){b.fn.jScrollPane=function(e){function d(D,O){var ay,Q=this,Y,aj,v,al,T,Z,y,q,az,aE,au,i,I,h,j,aa,U,ap,X,t,A,aq,af,am,G,l,at,ax,x,av,aH,f,L,ai=true,P=true,aG=false,k=false,ao=D.clone(false,false).empty(),ac=b.fn.mwheelIntent?"mwheelIntent.jsp":"mousewheel.jsp";aH=D.css("paddingTop")+" "+D.css("paddingRight")+" "+D.css("paddingBottom")+" "+D.css("paddingLeft");f=(parseInt(D.css("paddingLeft"),10)||0)+(parseInt(D.css("paddingRight"),10)||0);function ar(aQ){var aL,aN,aM,aJ,aI,aP,aO=false,aK=false;ay=aQ;if(Y===c){aI=D.scrollTop();aP=D.scrollLeft();D.css({overflow:"hidden",padding:0});aj=D.innerWidth()+f;v=D.innerHeight();D.width(aj);Y=b('<div class="jspPane" />').css("padding",aH).append(D.children());al=b('<div class="jspContainer" />').css({width:aj+"px",height:v+"px"}).append(Y).appendTo(D)}else{D.css("width","");aO=ay.stickToBottom&&K();aK=ay.stickToRight&&B();aJ=D.innerWidth()+f!=aj||D.outerHeight()!=v;if(aJ){aj=D.innerWidth()+f;v=D.innerHeight();al.css({width:aj+"px",height:v+"px"})}if(!aJ&&L==T&&Y.outerHeight()==Z){D.width(aj);return}L=T;Y.css("width","");D.width(aj);al.find(">.jspVerticalBar,>.jspHorizontalBar").remove().end()}Y.css("overflow","auto");if(aQ.contentWidth){T=aQ.contentWidth}else{T=Y[0].scrollWidth}Z=Y[0].scrollHeight;Y.css("overflow","");y=T/aj;q=Z/v;az=q>1;aE=y>1;if(!(aE||az)){D.removeClass("jspScrollable");Y.css({top:0,width:al.width()-f});n();E();R();w()}else{D.addClass("jspScrollable");aL=ay.maintainPosition&&(I||aa);if(aL){aN=aC();aM=aA()}aF();z();F();if(aL){N(aK?(T-aj):aN,false);M(aO?(Z-v):aM,false)}J();ag();an();if(ay.enableKeyboardNavigation){S()}if(ay.clickOnTrack){p()}C();if(ay.hijackInternalLinks){m()}}if(ay.autoReinitialise&&!av){av=setInterval(function(){ar(ay)},ay.autoReinitialiseDelay)}else{if(!ay.autoReinitialise&&av){clearInterval(av)}}aI&&D.scrollTop(0)&&M(aI,false);aP&&D.scrollLeft(0)&&N(aP,false);D.trigger("jsp-initialised",[aE||az])}function aF(){if(az){al.append(b('<div class="jspVerticalBar" />').append(b('<div class="jspCap jspCapTop" />'),b('<div class="jspTrack" />').append(b('<div class="jspDrag" />').append(b('<div class="jspDragTop" />'),b('<div class="jspDragBottom" />'))),b('<div class="jspCap jspCapBottom" />')));U=al.find(">.jspVerticalBar");ap=U.find(">.jspTrack");au=ap.find(">.jspDrag");if(ay.showArrows){aq=b('<a class="jspArrow jspArrowUp" />').bind("mousedown.jsp",aD(0,-1)).bind("click.jsp",aB);af=b('<a class="jspArrow jspArrowDown" />').bind("mousedown.jsp",aD(0,1)).bind("click.jsp",aB);if(ay.arrowScrollOnHover){aq.bind("mouseover.jsp",aD(0,-1,aq));af.bind("mouseover.jsp",aD(0,1,af))}ak(ap,ay.verticalArrowPositions,aq,af)}t=v;al.find(">.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow").each(function(){t-=b(this).outerHeight()});au.hover(function(){au.addClass("jspHover")},function(){au.removeClass("jspHover")}).bind("mousedown.jsp",function(aI){b("html").bind("dragstart.jsp selectstart.jsp",aB);au.addClass("jspActive");var s=aI.pageY-au.position().top;b("html").bind("mousemove.jsp",function(aJ){V(aJ.pageY-s,false)}).bind("mouseup.jsp mouseleave.jsp",aw);return false});o()}}function o(){ap.height(t+"px");I=0;X=ay.verticalGutter+ap.outerWidth();Y.width(aj-X-f);try{if(U.position().left===0){Y.css("margin-left",X+"px")}}catch(s){}}function z(){if(aE){al.append(b('<div class="jspHorizontalBar" />').append(b('<div class="jspCap jspCapLeft" />'),b('<div class="jspTrack" />').append(b('<div class="jspDrag" />').append(b('<div class="jspDragLeft" />'),b('<div class="jspDragRight" />'))),b('<div class="jspCap jspCapRight" />')));am=al.find(">.jspHorizontalBar");G=am.find(">.jspTrack");h=G.find(">.jspDrag");if(ay.showArrows){ax=b('<a class="jspArrow jspArrowLeft" />').bind("mousedown.jsp",aD(-1,0)).bind("click.jsp",aB);x=b('<a class="jspArrow jspArrowRight" />').bind("mousedown.jsp",aD(1,0)).bind("click.jsp",aB);
if(ay.arrowScrollOnHover){ax.bind("mouseover.jsp",aD(-1,0,ax));x.bind("mouseover.jsp",aD(1,0,x))}ak(G,ay.horizontalArrowPositions,ax,x)}h.hover(function(){h.addClass("jspHover")},function(){h.removeClass("jspHover")}).bind("mousedown.jsp",function(aI){b("html").bind("dragstart.jsp selectstart.jsp",aB);h.addClass("jspActive");var s=aI.pageX-h.position().left;b("html").bind("mousemove.jsp",function(aJ){W(aJ.pageX-s,false)}).bind("mouseup.jsp mouseleave.jsp",aw);return false});l=al.innerWidth();ah()}}function ah(){al.find(">.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow").each(function(){l-=b(this).outerWidth()});G.width(l+"px");aa=0}function F(){if(aE&&az){var aI=G.outerHeight(),s=ap.outerWidth();t-=aI;b(am).find(">.jspCap:visible,>.jspArrow").each(function(){l+=b(this).outerWidth()});l-=s;v-=s;aj-=aI;G.parent().append(b('<div class="jspCorner" />').css("width",aI+"px"));o();ah()}if(aE){Y.width((al.outerWidth()-f)+"px")}Z=Y.outerHeight();q=Z/v;if(aE){at=Math.ceil(1/y*l);if(at>ay.horizontalDragMaxWidth){at=ay.horizontalDragMaxWidth}else{if(at<ay.horizontalDragMinWidth){at=ay.horizontalDragMinWidth}}h.width(at+"px");j=l-at;ae(aa)}if(az){A=Math.ceil(1/q*t);if(A>ay.verticalDragMaxHeight){A=ay.verticalDragMaxHeight}else{if(A<ay.verticalDragMinHeight){A=ay.verticalDragMinHeight}}au.height(A+"px");i=t-A;ad(I)}}function ak(aJ,aL,aI,s){var aN="before",aK="after",aM;if(aL=="os"){aL=/Mac/.test(navigator.platform)?"after":"split"}if(aL==aN){aK=aL}else{if(aL==aK){aN=aL;aM=aI;aI=s;s=aM}}aJ[aN](aI)[aK](s)}function aD(aI,s,aJ){return function(){H(aI,s,this,aJ);this.blur();return false}}function H(aL,aK,aO,aN){aO=b(aO).addClass("jspActive");var aM,aJ,aI=true,s=function(){if(aL!==0){Q.scrollByX(aL*ay.arrowButtonSpeed)}if(aK!==0){Q.scrollByY(aK*ay.arrowButtonSpeed)}aJ=setTimeout(s,aI?ay.initialDelay:ay.arrowRepeatFreq);aI=false};s();aM=aN?"mouseout.jsp":"mouseup.jsp";aN=aN||b("html");aN.bind(aM,function(){aO.removeClass("jspActive");aJ&&clearTimeout(aJ);aJ=null;aN.unbind(aM)})}function p(){w();if(az){ap.bind("mousedown.jsp",function(aN){if(aN.originalTarget===c||aN.originalTarget==aN.currentTarget){var aL=b(this),aO=aL.offset(),aM=aN.pageY-aO.top-I,aJ,aI=true,s=function(){var aR=aL.offset(),aS=aN.pageY-aR.top-A/2,aP=v*ay.scrollPagePercent,aQ=i*aP/(Z-v);if(aM<0){if(I-aQ>aS){Q.scrollByY(-aP)}else{V(aS)}}else{if(aM>0){if(I+aQ<aS){Q.scrollByY(aP)}else{V(aS)}}else{aK();return}}aJ=setTimeout(s,aI?ay.initialDelay:ay.trackClickRepeatFreq);aI=false},aK=function(){aJ&&clearTimeout(aJ);aJ=null;b(document).unbind("mouseup.jsp",aK)};s();b(document).bind("mouseup.jsp",aK);return false}})}if(aE){G.bind("mousedown.jsp",function(aN){if(aN.originalTarget===c||aN.originalTarget==aN.currentTarget){var aL=b(this),aO=aL.offset(),aM=aN.pageX-aO.left-aa,aJ,aI=true,s=function(){var aR=aL.offset(),aS=aN.pageX-aR.left-at/2,aP=aj*ay.scrollPagePercent,aQ=j*aP/(T-aj);if(aM<0){if(aa-aQ>aS){Q.scrollByX(-aP)}else{W(aS)}}else{if(aM>0){if(aa+aQ<aS){Q.scrollByX(aP)}else{W(aS)}}else{aK();return}}aJ=setTimeout(s,aI?ay.initialDelay:ay.trackClickRepeatFreq);aI=false},aK=function(){aJ&&clearTimeout(aJ);aJ=null;b(document).unbind("mouseup.jsp",aK)};s();b(document).bind("mouseup.jsp",aK);return false}})}}function w(){if(G){G.unbind("mousedown.jsp")}if(ap){ap.unbind("mousedown.jsp")}}function aw(){b("html").unbind("dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp");if(au){au.removeClass("jspActive")}if(h){h.removeClass("jspActive")}}function V(s,aI){if(!az){return}if(s<0){s=0}else{if(s>i){s=i}}if(aI===c){aI=ay.animateScroll}if(aI){Q.animate(au,"top",s,ad)}else{au.css("top",s);ad(s)}}function ad(aI){if(aI===c){aI=au.position().top}al.scrollTop(0);I=aI;var aL=I===0,aJ=I==i,aK=aI/i,s=-aK*(Z-v);if(ai!=aL||aG!=aJ){ai=aL;aG=aJ;D.trigger("jsp-arrow-change",[ai,aG,P,k])}u(aL,aJ);Y.css("top",s);D.trigger("jsp-scroll-y",[-s,aL,aJ]).trigger("scroll")}function W(aI,s){if(!aE){return}if(aI<0){aI=0}else{if(aI>j){aI=j}}if(s===c){s=ay.animateScroll}if(s){Q.animate(h,"left",aI,ae)
}else{h.css("left",aI);ae(aI)}}function ae(aI){if(aI===c){aI=h.position().left}al.scrollTop(0);aa=aI;var aL=aa===0,aK=aa==j,aJ=aI/j,s=-aJ*(T-aj);if(P!=aL||k!=aK){P=aL;k=aK;D.trigger("jsp-arrow-change",[ai,aG,P,k])}r(aL,aK);Y.css("left",s);D.trigger("jsp-scroll-x",[-s,aL,aK]).trigger("scroll")}function u(aI,s){if(ay.showArrows){aq[aI?"addClass":"removeClass"]("jspDisabled");af[s?"addClass":"removeClass"]("jspDisabled")}}function r(aI,s){if(ay.showArrows){ax[aI?"addClass":"removeClass"]("jspDisabled");x[s?"addClass":"removeClass"]("jspDisabled")}}function M(s,aI){var aJ=s/(Z-v);V(aJ*i,aI)}function N(aI,s){var aJ=aI/(T-aj);W(aJ*j,s)}function ab(aV,aQ,aJ){var aN,aK,aL,s=0,aU=0,aI,aP,aO,aS,aR,aT;try{aN=b(aV)}catch(aM){return}aK=aN.outerHeight();aL=aN.outerWidth();al.scrollTop(0);al.scrollLeft(0);while(!aN.is(".jspPane")){s+=aN.position().top;aU+=aN.position().left;aN=aN.offsetParent();if(/^body|html$/i.test(aN[0].nodeName)){return}}aI=aA();aO=aI+v;if(s<aI||aQ){aR=s-ay.verticalGutter}else{if(s+aK>aO){aR=s-v+aK+ay.verticalGutter}}if(aR){M(aR,aJ)}aP=aC();aS=aP+aj;if(aU<aP||aQ){aT=aU-ay.horizontalGutter}else{if(aU+aL>aS){aT=aU-aj+aL+ay.horizontalGutter}}if(aT){N(aT,aJ)}}function aC(){return -Y.position().left}function aA(){return -Y.position().top}function K(){var s=Z-v;return(s>20)&&(s-aA()<10)}function B(){var s=T-aj;return(s>20)&&(s-aC()<10)}function ag(){al.unbind(ac).bind(ac,function(aL,aM,aK,aI){var aJ=aa,s=I;Q.scrollBy(aK*ay.mouseWheelSpeed,-aI*ay.mouseWheelSpeed,false);return aJ==aa&&s==I})}function n(){al.unbind(ac)}function aB(){return false}function J(){Y.find(":input,a").unbind("focus.jsp").bind("focus.jsp",function(s){ab(s.target,false)})}function E(){Y.find(":input,a").unbind("focus.jsp")}function S(){var s,aI,aK=[];aE&&aK.push(am[0]);az&&aK.push(U[0]);Y.focus(function(){D.focus()});D.attr("tabindex",0).unbind("keydown.jsp keypress.jsp").bind("keydown.jsp",function(aN){if(aN.target!==this&&!(aK.length&&b(aN.target).closest(aK).length)){return}var aM=aa,aL=I;switch(aN.keyCode){case 40:case 38:case 34:case 32:case 33:case 39:case 37:s=aN.keyCode;aJ();break;case 35:M(Z-v);s=null;break;case 36:M(0);s=null;break}aI=aN.keyCode==s&&aM!=aa||aL!=I;return !aI}).bind("keypress.jsp",function(aL){if(aL.keyCode==s){aJ()}return !aI});if(ay.hideFocus){D.css("outline","none");if("hideFocus" in al[0]){D.attr("hideFocus",true)}}else{D.css("outline","");if("hideFocus" in al[0]){D.attr("hideFocus",false)}}function aJ(){var aM=aa,aL=I;switch(s){case 40:Q.scrollByY(ay.keyboardSpeed,false);break;case 38:Q.scrollByY(-ay.keyboardSpeed,false);break;case 34:case 32:Q.scrollByY(v*ay.scrollPagePercent,false);break;case 33:Q.scrollByY(-v*ay.scrollPagePercent,false);break;case 39:Q.scrollByX(ay.keyboardSpeed,false);break;case 37:Q.scrollByX(-ay.keyboardSpeed,false);break}aI=aM!=aa||aL!=I;return aI}}function R(){D.attr("tabindex","-1").removeAttr("tabindex").unbind("keydown.jsp keypress.jsp")}function C(){if(location.hash&&location.hash.length>1){var aK,aI,aJ=escape(location.hash.substr(1));try{aK=b("#"+aJ+', a[name="'+aJ+'"]')}catch(s){return}if(aK.length&&Y.find(aJ)){if(al.scrollTop()===0){aI=setInterval(function(){if(al.scrollTop()>0){ab(aK,true);b(document).scrollTop(al.position().top);clearInterval(aI)}},50)}else{ab(aK,true);b(document).scrollTop(al.position().top)}}}}function m(){if(b(document.body).data("jspHijack")){return}b(document.body).data("jspHijack",true);b(document.body).delegate("a[href*=#]","click",function(s){var aI=this.href.substr(0,this.href.indexOf("#")),aK=location.href,aO,aP,aJ,aM,aL,aN;if(location.href.indexOf("#")!==-1){aK=location.href.substr(0,location.href.indexOf("#"))}if(aI!==aK){return}aO=escape(this.href.substr(this.href.indexOf("#")+1));aP;try{aP=b("#"+aO+', a[name="'+aO+'"]')}catch(aQ){return}if(!aP.length){return}aJ=aP.closest(".jspScrollable");aM=aJ.data("jsp");aM.scrollToElement(aP,true);if(aJ[0].scrollIntoView){aL=b(a).scrollTop();aN=aP.offset().top;if(aN<aL||aN>aL+b(a).height()){aJ[0].scrollIntoView()}}s.preventDefault()
})}function an(){var aJ,aI,aL,aK,aM,s=false;al.unbind("touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick").bind("touchstart.jsp",function(aN){var aO=aN.originalEvent.touches[0];aJ=aC();aI=aA();aL=aO.pageX;aK=aO.pageY;aM=false;s=true}).bind("touchmove.jsp",function(aQ){if(!s){return}var aP=aQ.originalEvent.touches[0],aO=aa,aN=I;Q.scrollTo(aJ+aL-aP.pageX,aI+aK-aP.pageY);aM=aM||Math.abs(aL-aP.pageX)>5||Math.abs(aK-aP.pageY)>5;return aO==aa&&aN==I}).bind("touchend.jsp",function(aN){s=false}).bind("click.jsp-touchclick",function(aN){if(aM){aM=false;return false}})}function g(){var s=aA(),aI=aC();D.removeClass("jspScrollable").unbind(".jsp");D.replaceWith(ao.append(Y.children()));ao.scrollTop(s);ao.scrollLeft(aI);if(av){clearInterval(av)}}b.extend(Q,{reinitialise:function(aI){aI=b.extend({},ay,aI);ar(aI)},scrollToElement:function(aJ,aI,s){ab(aJ,aI,s)},scrollTo:function(aJ,s,aI){N(aJ,aI);M(s,aI)},scrollToX:function(aI,s){N(aI,s)},scrollToY:function(s,aI){M(s,aI)},scrollToPercentX:function(aI,s){N(aI*(T-aj),s)},scrollToPercentY:function(aI,s){M(aI*(Z-v),s)},scrollBy:function(aI,s,aJ){Q.scrollByX(aI,aJ);Q.scrollByY(s,aJ)},scrollByX:function(s,aJ){var aI=aC()+Math[s<0?"floor":"ceil"](s),aK=aI/(T-aj);W(aK*j,aJ)},scrollByY:function(s,aJ){var aI=aA()+Math[s<0?"floor":"ceil"](s),aK=aI/(Z-v);V(aK*i,aJ)},positionDragX:function(s,aI){W(s,aI)},positionDragY:function(aI,s){V(aI,s)},animate:function(aI,aL,s,aK){var aJ={};aJ[aL]=s;aI.animate(aJ,{duration:ay.animateDuration,easing:ay.animateEase,queue:false,step:aK})},getContentPositionX:function(){return aC()},getContentPositionY:function(){return aA()},getContentWidth:function(){return T},getContentHeight:function(){return Z},getPercentScrolledX:function(){return aC()/(T-aj)},getPercentScrolledY:function(){return aA()/(Z-v)},getIsScrollableH:function(){return aE},getIsScrollableV:function(){return az},getContentPane:function(){return Y},scrollToBottom:function(s){V(i,s)},hijackInternalLinks:b.noop,destroy:function(){g()}});ar(O)}e=b.extend({},b.fn.jScrollPane.defaults,e);b.each(["mouseWheelSpeed","arrowButtonSpeed","trackClickSpeed","keyboardSpeed"],function(){e[this]=e[this]||e.speed});return this.each(function(){var f=b(this),g=f.data("jsp");if(g){g.reinitialise(e)}else{b("script",f).filter('[type="text/javascript"],:not([type])').remove();g=new d(f,e);f.data("jsp",g)}})};b.fn.jScrollPane.defaults={showArrows:false,maintainPosition:true,stickToBottom:false,stickToRight:false,clickOnTrack:true,autoReinitialise:false,autoReinitialiseDelay:500,verticalDragMinHeight:0,verticalDragMaxHeight:99999,horizontalDragMinWidth:0,horizontalDragMaxWidth:99999,contentWidth:c,animateScroll:false,animateDuration:300,animateEase:"linear",hijackInternalLinks:false,verticalGutter:4,horizontalGutter:4,mouseWheelSpeed:0,arrowButtonSpeed:0,arrowRepeatFreq:50,arrowScrollOnHover:false,trackClickSpeed:0,trackClickRepeatFreq:70,verticalArrowPositions:"split",horizontalArrowPositions:"split",enableKeyboardNavigation:true,hideFocus:false,keyboardSpeed:0,initialDelay:300,speed:30,scrollPagePercent:0.8}})(jQuery,this);
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
*
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
* Thanks to: Seamus Leahy for adding deltaX and deltaY
*
* Version: 3.0.6
*
* Requires: 1.2.2+
*/
(function($) {
var types = ['DOMMouseScroll', 'mousewheel'];
if ($.event.fixHooks) {
for ( var i=types.length; i; ) {
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
}
}
$.event.special.mousewheel = {
setup: function() {
if ( this.addEventListener ) {
for ( var i=types.length; i; ) {
this.addEventListener( types[--i], handler, false );
}
} else {
this.onmousewheel = handler;
}
},
teardown: function() {
if ( this.removeEventListener ) {
for ( var i=types.length; i; ) {
this.removeEventListener( types[--i], handler, false );
}
} else {
this.onmousewheel = null;
}
}
};
$.fn.extend({
mousewheel: function(fn) {
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
},
unmousewheel: function(fn) {
return this.unbind("mousewheel", fn);
}
});
function handler(event) {
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
event = $.event.fix(orgEvent);
event.type = "mousewheel";
// Old school scrollwheel delta
if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }
// New school multidimensional scroll (touchpads) deltas
deltaY = delta;
// Gecko
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaY = 0;
deltaX = -1*delta;
}
// Webkit
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
return ($.event.dispatch || $.event.handle).apply(this, args);
}
})(jQuery);
/*
* jQuery Nivo Slider v3.2
* http://nivo.dev7studios.com
*
* Copyright 2012, Dev7studios
* Free to use and abuse under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
(function($) {
var NivoSlider = function(element, options){
// Defaults are below
var settings = $.extend({}, $.fn.nivoSlider.defaults, options);
// Useful variables. Play carefully.
var vars = {
currentSlide: 0,
currentImage: '',
totalSlides: 0,
running: false,
paused: false,
stop: false,
controlNavEl: false
};
// Get this slider
var slider = $(element);
slider.data('nivo:vars', vars).addClass('nivoSlider');
// Find our slider children
var kids = slider.children();
kids.each(function() {
var child = $(this);
var link = '';
if(!child.is('img')){
if(child.is('a')){
child.addClass('nivo-imageLink');
link = child;
}
child = child.find('img:first');
}
// Get img width & height
var childWidth = (childWidth === 0) ? child.attr('width') : child.width(),
childHeight = (childHeight === 0) ? child.attr('height') : child.height();
if(link !== ''){
link.css('display','none');
}
child.css('display','none');
vars.totalSlides++;
});
// If randomStart
if(settings.randomStart){
settings.startSlide = Math.floor(Math.random() * vars.totalSlides);
}
// Set startSlide
if(settings.startSlide > 0){
if(settings.startSlide >= vars.totalSlides) { settings.startSlide = vars.totalSlides - 1; }
vars.currentSlide = settings.startSlide;
}
// Get initial image
if($(kids[vars.currentSlide]).is('img')){
vars.currentImage = $(kids[vars.currentSlide]);
} else {
vars.currentImage = $(kids[vars.currentSlide]).find('img:first');
}
// Show initial link
if($(kids[vars.currentSlide]).is('a')){
$(kids[vars.currentSlide]).css('display','block');
}
// Set first background
var sliderImg = $('<img/>').addClass('nivo-main-image');
sliderImg.attr('src', vars.currentImage.attr('src')).show();
slider.append(sliderImg);
// Detect Window Resize
$(window).resize(function() {
slider.children('img').width(slider.width());
sliderImg.attr('src', vars.currentImage.attr('src'));
sliderImg.stop().height('auto');
$('.nivo-slice').remove();
$('.nivo-box').remove();
});
//Create caption
slider.append($('<div class="nivo-caption"></div>'));
// Process caption function
var processCaption = function(settings){
var nivoCaption = $('.nivo-caption', slider);
if(vars.currentImage.attr('title') != '' && vars.currentImage.attr('title') != undefined){
var title = vars.currentImage.attr('title');
if(title.substr(0,1) == '#') title = $(title).html();
if(nivoCaption.css('display') == 'block'){
setTimeout(function(){
nivoCaption.html(title);
}, settings.animSpeed);
} else {
nivoCaption.html(title);
nivoCaption.stop().fadeIn(settings.animSpeed);
}
} else {
nivoCaption.stop().fadeOut(settings.animSpeed);
}
}
//Process initial caption
processCaption(settings);
// In the words of Super Mario "let's a go!"
var timer = 0;
if(!settings.manualAdvance && kids.length > 1){
timer = setInterval(function(){ nivoRun(slider, kids, settings, false); }, settings.pauseTime);
}
// Add Direction nav
if(settings.directionNav){
slider.append('<div class="nivo-directionNav"><a class="nivo-prevNav">'+ settings.prevText +'</a><a class="nivo-nextNav">'+ settings.nextText +'</a></div>');
$(slider).on('click', 'a.nivo-prevNav', function(){
if(vars.running) { return false; }
clearInterval(timer);
timer = '';
vars.currentSlide -= 2;
nivoRun(slider, kids, settings, 'prev');
});
$(slider).on('click', 'a.nivo-nextNav', function(){
if(vars.running) { return false; }
clearInterval(timer);
timer = '';
nivoRun(slider, kids, settings, 'next');
});
}
// Add Control nav
if(settings.controlNav){
vars.controlNavEl = $('<div class="nivo-controlNav"></div>');
slider.after(vars.controlNavEl);
for(var i = 0; i < kids.length; i++){
if(settings.controlNavThumbs){
vars.controlNavEl.addClass('nivo-thumbs-enabled');
var child = kids.eq(i);
if(!child.is('img')){
child = child.find('img:first');
}
if(child.attr('data-thumb')) vars.controlNavEl.append('<a class="nivo-control" rel="'+ i +'"><img src="'+ child.attr('data-thumb') +'" alt="" /></a>');
} else {
vars.controlNavEl.append('<a class="nivo-control" rel="'+ i +'">'+ (i + 1) +'</a>');
}
}
//Set initial active link
$('a:eq('+ vars.currentSlide +')', vars.controlNavEl).addClass('active');
$('a', vars.controlNavEl).bind('click', function(){
if(vars.running) return false;
if($(this).hasClass('active')) return false;
clearInterval(timer);
timer = '';
sliderImg.attr('src', vars.currentImage.attr('src'));
vars.currentSlide = $(this).attr('rel') - 1;
nivoRun(slider, kids, settings, 'control');
});
}
//For pauseOnHover setting
if(settings.pauseOnHover){
slider.hover(function(){
vars.paused = true;
clearInterval(timer);
timer = '';
}, function(){
vars.paused = false;
// Restart the timer
if(timer === '' && !settings.manualAdvance){
timer = setInterval(function(){ nivoRun(slider, kids, settings, false); }, settings.pauseTime);
}
});
}
// Event when Animation finishes
slider.bind('nivo:animFinished', function(){
sliderImg.attr('src', vars.currentImage.attr('src'));
vars.running = false;
// Hide child links
$(kids).each(function(){
if($(this).is('a')){
$(this).css('display','none');
}
});
// Show current link
if($(kids[vars.currentSlide]).is('a')){
$(kids[vars.currentSlide]).css('display','block');
}
// Restart the timer
if(timer === '' && !vars.paused && !settings.manualAdvance){
timer = setInterval(function(){ nivoRun(slider, kids, settings, false); }, settings.pauseTime);
}
// Trigger the afterChange callback
settings.afterChange.call(this);
});
// Add slices for slice animations
var createSlices = function(slider, settings, vars) {
if($(vars.currentImage).parent().is('a')) $(vars.currentImage).parent().css('display','block');
$('img[src="'+ vars.currentImage.attr('src') +'"]', slider).not('.nivo-main-image,.nivo-control img').width(slider.width()).css('visibility', 'hidden').show();
var sliceHeight = ($('img[src="'+ vars.currentImage.attr('src') +'"]', slider).not('.nivo-main-image,.nivo-control img').parent().is('a')) ? $('img[src="'+ vars.currentImage.attr('src') +'"]', slider).not('.nivo-main-image,.nivo-control img').parent().height() : $('img[src="'+ vars.currentImage.attr('src') +'"]', slider).not('.nivo-main-image,.nivo-control img').height();
for(var i = 0; i < settings.slices; i++){
var sliceWidth = Math.round(slider.width()/settings.slices);
if(i === settings.slices-1){
slider.append(
$('<div class="nivo-slice" name="'+i+'"><img src="'+ vars.currentImage.attr('src') +'" style="position:absolute; width:'+ slider.width() +'px; height:auto; display:block !important; top:0; left:-'+ ((sliceWidth + (i * sliceWidth)) - sliceWidth) +'px;" /></div>').css({
left:(sliceWidth*i)+'px',
width:(slider.width()-(sliceWidth*i))+'px',
height:sliceHeight+'px',
opacity:'0',
overflow:'hidden'
})
);
} else {
slider.append(
$('<div class="nivo-slice" name="'+i+'"><img src="'+ vars.currentImage.attr('src') +'" style="position:absolute; width:'+ slider.width() +'px; height:auto; display:block !important; top:0; left:-'+ ((sliceWidth + (i * sliceWidth)) - sliceWidth) +'px;" /></div>').css({
left:(sliceWidth*i)+'px',
width:sliceWidth+'px',
height:sliceHeight+'px',
opacity:'0',
overflow:'hidden'
})
);
}
}
$('.nivo-slice', slider).height(sliceHeight);
sliderImg.stop().animate({
height: $(vars.currentImage).height()
}, settings.animSpeed);
};
// Add boxes for box animations
var createBoxes = function(slider, settings, vars){
if($(vars.currentImage).parent().is('a')) $(vars.currentImage).parent().css('display','block');
$('img[src="'+ vars.currentImage.attr('src') +'"]', slider).not('.nivo-main-image,.nivo-control img').width(slider.width()).css('visibility', 'hidden').show();
var boxWidth = Math.round(slider.width()/settings.boxCols),
boxHeight = Math.round($('img[src="'+ vars.currentImage.attr('src') +'"]', slider).not('.nivo-main-image,.nivo-control img').height() / settings.boxRows);
for(var rows = 0; rows < settings.boxRows; rows++){
for(var cols = 0; cols < settings.boxCols; cols++){
if(cols === settings.boxCols-1){
slider.append(
$('<div class="nivo-box" name="'+ cols +'" rel="'+ rows +'"><img src="'+ vars.currentImage.attr('src') +'" style="position:absolute; width:'+ slider.width() +'px; height:auto; display:block; top:-'+ (boxHeight*rows) +'px; left:-'+ (boxWidth*cols) +'px;" /></div>').css({
opacity:0,
left:(boxWidth*cols)+'px',
top:(boxHeight*rows)+'px',
width:(slider.width()-(boxWidth*cols))+'px'
})
);
$('.nivo-box[name="'+ cols +'"]', slider).height($('.nivo-box[name="'+ cols +'"] img', slider).height()+'px');
} else {
slider.append(
$('<div class="nivo-box" name="'+ cols +'" rel="'+ rows +'"><img src="'+ vars.currentImage.attr('src') +'" style="position:absolute; width:'+ slider.width() +'px; height:auto; display:block; top:-'+ (boxHeight*rows) +'px; left:-'+ (boxWidth*cols) +'px;" /></div>').css({
opacity:0,
left:(boxWidth*cols)+'px',
top:(boxHeight*rows)+'px',
width:boxWidth+'px'
})
);
$('.nivo-box[name="'+ cols +'"]', slider).height($('.nivo-box[name="'+ cols +'"] img', slider).height()+'px');
}
}
}
sliderImg.stop().animate({
height: $(vars.currentImage).height()
}, settings.animSpeed);
};
// Private run method
var nivoRun = function(slider, kids, settings, nudge){
// Get our vars
var vars = slider.data('nivo:vars');
// Trigger the lastSlide callback
if(vars && (vars.currentSlide === vars.totalSlides - 1)){
settings.lastSlide.call(this);
}
// Stop
if((!vars || vars.stop) && !nudge) { return false; }
// Trigger the beforeChange callback
settings.beforeChange.call(this);
// Set current background before change
if(!nudge){
sliderImg.attr('src', vars.currentImage.attr('src'));
} else {
if(nudge === 'prev'){
sliderImg.attr('src', vars.currentImage.attr('src'));
}
if(nudge === 'next'){
sliderImg.attr('src', vars.currentImage.attr('src'));
}
}
vars.currentSlide++;
// Trigger the slideshowEnd callback
if(vars.currentSlide === vars.totalSlides){
vars.currentSlide = 0;
settings.slideshowEnd.call(this);
}
if(vars.currentSlide < 0) { vars.currentSlide = (vars.totalSlides - 1); }
// Set vars.currentImage
if($(kids[vars.currentSlide]).is('img')){
vars.currentImage = $(kids[vars.currentSlide]);
} else {
vars.currentImage = $(kids[vars.currentSlide]).find('img:first');
}
// Set active links
if(settings.controlNav){
$('a', vars.controlNavEl).removeClass('active');
$('a:eq('+ vars.currentSlide +')', vars.controlNavEl).addClass('active');
}
// Process caption
processCaption(settings);
// Remove any slices from last transition
$('.nivo-slice', slider).remove();
// Remove any boxes from last transition
$('.nivo-box', slider).remove();
var currentEffect = settings.effect,
anims = '';
// Generate random effect
if(settings.effect === 'random'){
anims = new Array('sliceDownRight','sliceDownLeft','sliceUpRight','sliceUpLeft','sliceUpDown','sliceUpDownLeft','fold','fade',
'boxRandom','boxRain','boxRainReverse','boxRainGrow','boxRainGrowReverse');
currentEffect = anims[Math.floor(Math.random()*(anims.length + 1))];
if(currentEffect === undefined) { currentEffect = 'fade'; }
}
// Run random effect from specified set (eg: effect:'fold,fade')
if(settings.effect.indexOf(',') !== -1){
anims = settings.effect.split(',');
currentEffect = anims[Math.floor(Math.random()*(anims.length))];
if(currentEffect === undefined) { currentEffect = 'fade'; }
}
// Custom transition as defined by "data-transition" attribute
if(vars.currentImage.attr('data-transition')){
currentEffect = vars.currentImage.attr('data-transition');
}
// Run effects
vars.running = true;
var timeBuff = 0,
i = 0,
slices = '',
firstSlice = '',
totalBoxes = '',
boxes = '';
if(currentEffect === 'sliceDown' || currentEffect === 'sliceDownRight' || currentEffect === 'sliceDownLeft'){
createSlices(slider, settings, vars);
timeBuff = 0;
i = 0;
slices = $('.nivo-slice', slider);
if(currentEffect === 'sliceDownLeft') { slices = $('.nivo-slice', slider)._reverse(); }
slices.each(function(){
var slice = $(this);
slice.css({ 'top': '0px' });
if(i === settings.slices-1){
setTimeout(function(){
slice.animate({opacity:'1.0' }, settings.animSpeed, '', function(){ slider.trigger('nivo:animFinished'); });
}, (100 + timeBuff));
} else {
setTimeout(function(){
slice.animate({opacity:'1.0' }, settings.animSpeed);
}, (100 + timeBuff));
}
timeBuff += 50;
i++;
});
} else if(currentEffect === 'sliceUp' || currentEffect === 'sliceUpRight' || currentEffect === 'sliceUpLeft'){
createSlices(slider, settings, vars);
timeBuff = 0;
i = 0;
slices = $('.nivo-slice', slider);
if(currentEffect === 'sliceUpLeft') { slices = $('.nivo-slice', slider)._reverse(); }
slices.each(function(){
var slice = $(this);
slice.css({ 'bottom': '0px' });
if(i === settings.slices-1){
setTimeout(function(){
slice.animate({opacity:'1.0' }, settings.animSpeed, '', function(){ slider.trigger('nivo:animFinished'); });
}, (100 + timeBuff));
} else {
setTimeout(function(){
slice.animate({opacity:'1.0' }, settings.animSpeed);
}, (100 + timeBuff));
}
timeBuff += 50;
i++;
});
} else if(currentEffect === 'sliceUpDown' || currentEffect === 'sliceUpDownRight' || currentEffect === 'sliceUpDownLeft'){
createSlices(slider, settings, vars);
timeBuff = 0;
i = 0;
var v = 0;
slices = $('.nivo-slice', slider);
if(currentEffect === 'sliceUpDownLeft') { slices = $('.nivo-slice', slider)._reverse(); }
slices.each(function(){
var slice = $(this);
if(i === 0){
slice.css('top','0px');
i++;
} else {
slice.css('bottom','0px');
i = 0;
}
if(v === settings.slices-1){
setTimeout(function(){
slice.animate({opacity:'1.0' }, settings.animSpeed, '', function(){ slider.trigger('nivo:animFinished'); });
}, (100 + timeBuff));
} else {
setTimeout(function(){
slice.animate({opacity:'1.0' }, settings.animSpeed);
}, (100 + timeBuff));
}
timeBuff += 50;
v++;
});
} else if(currentEffect === 'fold'){
createSlices(slider, settings, vars);
timeBuff = 0;
i = 0;
$('.nivo-slice', slider).each(function(){
var slice = $(this);
var origWidth = slice.width();
slice.css({ top:'0px', width:'0px' });
if(i === settings.slices-1){
setTimeout(function(){
slice.animate({ width:origWidth, opacity:'1.0' }, settings.animSpeed, '', function(){ slider.trigger('nivo:animFinished'); });
}, (100 + timeBuff));
} else {
setTimeout(function(){
slice.animate({ width:origWidth, opacity:'1.0' }, settings.animSpeed);
}, (100 + timeBuff));
}
timeBuff += 50;
i++;
});
} else if(currentEffect === 'fade'){
createSlices(slider, settings, vars);
firstSlice = $('.nivo-slice:first', slider);
firstSlice.css({
'width': slider.width() + 'px'
});
firstSlice.animate({ opacity:'1.0' }, (settings.animSpeed*2), '', function(){ slider.trigger('nivo:animFinished'); });
} else if(currentEffect === 'slideInRight'){
createSlices(slider, settings, vars);
firstSlice = $('.nivo-slice:first', slider);
firstSlice.css({
'width': '0px',
'opacity': '1'
});
firstSlice.animate({ width: slider.width() + 'px' }, (settings.animSpeed*2), '', function(){ slider.trigger('nivo:animFinished'); });
} else if(currentEffect === 'slideInLeft'){
createSlices(slider, settings, vars);
firstSlice = $('.nivo-slice:first', slider);
firstSlice.css({
'width': '0px',
'opacity': '1',
'left': '',
'right': '0px'
});
firstSlice.animate({ width: slider.width() + 'px' }, (settings.animSpeed*2), '', function(){
// Reset positioning
firstSlice.css({
'left': '0px',
'right': ''
});
slider.trigger('nivo:animFinished');
});
} else if(currentEffect === 'boxRandom'){
createBoxes(slider, settings, vars);
totalBoxes = settings.boxCols * settings.boxRows;
i = 0;
timeBuff = 0;
boxes = shuffle($('.nivo-box', slider));
boxes.each(function(){
var box = $(this);
if(i === totalBoxes-1){
setTimeout(function(){
box.animate({ opacity:'1' }, settings.animSpeed, '', function(){ slider.trigger('nivo:animFinished'); });
}, (100 + timeBuff));
} else {
setTimeout(function(){
box.animate({ opacity:'1' }, settings.animSpeed);
}, (100 + timeBuff));
}
timeBuff += 20;
i++;
});
} else if(currentEffect === 'boxRain' || currentEffect === 'boxRainReverse' || currentEffect === 'boxRainGrow' || currentEffect === 'boxRainGrowReverse'){
createBoxes(slider, settings, vars);
totalBoxes = settings.boxCols * settings.boxRows;
i = 0;
timeBuff = 0;
// Split boxes into 2D array
var rowIndex = 0;
var colIndex = 0;
var box2Darr = [];
box2Darr[rowIndex] = [];
boxes = $('.nivo-box', slider);
if(currentEffect === 'boxRainReverse' || currentEffect === 'boxRainGrowReverse'){
boxes = $('.nivo-box', slider)._reverse();
}
boxes.each(function(){
box2Darr[rowIndex][colIndex] = $(this);
colIndex++;
if(colIndex === settings.boxCols){
rowIndex++;
colIndex = 0;
box2Darr[rowIndex] = [];
}
});
// Run animation
for(var cols = 0; cols < (settings.boxCols * 2); cols++){
var prevCol = cols;
for(var rows = 0; rows < settings.boxRows; rows++){
if(prevCol >= 0 && prevCol < settings.boxCols){
/* Due to some weird JS bug with loop vars
being used in setTimeout, this is wrapped
with an anonymous function call */
(function(row, col, time, i, totalBoxes) {
var box = $(box2Darr[row][col]);
var w = box.width();
var h = box.height();
if(currentEffect === 'boxRainGrow' || currentEffect === 'boxRainGrowReverse'){
box.width(0).height(0);
}
if(i === totalBoxes-1){
setTimeout(function(){
box.animate({ opacity:'1', width:w, height:h }, settings.animSpeed/1.3, '', function(){ slider.trigger('nivo:animFinished'); });
}, (100 + time));
} else {
setTimeout(function(){
box.animate({ opacity:'1', width:w, height:h }, settings.animSpeed/1.3);
}, (100 + time));
}
})(rows, prevCol, timeBuff, i, totalBoxes);
i++;
}
prevCol--;
}
timeBuff += 100;
}
}
};
// Shuffle an array
var shuffle = function(arr){
for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i, 10), x = arr[--i], arr[i] = arr[j], arr[j] = x);
return arr;
};
// For debugging
var trace = function(msg){
if(this.console && typeof console.log !== 'undefined') { console.log(msg); }
};
// Start / Stop
this.stop = function(){
if(!$(element).data('nivo:vars').stop){
$(element).data('nivo:vars').stop = true;
trace('Stop Slider');
}
};
this.start = function(){
if($(element).data('nivo:vars').stop){
$(element).data('nivo:vars').stop = false;
trace('Start Slider');
}
};
// Trigger the afterLoad callback
settings.afterLoad.call(this);
return this;
};
$.fn.nivoSlider = function(options) {
return this.each(function(key, value){
var element = $(this);
// Return early if this element already has a plugin instance
if (element.data('nivoslider')) { return element.data('nivoslider'); }
// Pass options to plugin constructor
var nivoslider = new NivoSlider(this, options);
// Store plugin object in this element's data
element.data('nivoslider', nivoslider);
});
};
//Default settings
$.fn.nivoSlider.defaults = {
effect: 'random',
slices: 15,
boxCols: 8,
boxRows: 4,
animSpeed: 500,
pauseTime: 3000,
startSlide: 0,
directionNav: true,
controlNav: true,
controlNavThumbs: false,
pauseOnHover: true,
manualAdvance: false,
prevText: 'Prev',
nextText: 'Next',
randomStart: false,
beforeChange: function(){},
afterChange: function(){},
slideshowEnd: function(){},
lastSlide: function(){},
afterLoad: function(){}
};
$.fn._reverse = [].reverse;
})(jQuery);
<!doctype html>
<head>
<link rel="stylesheet" href="colorbox.css" />
<style>
#example-header { border-bottom:2px solid #586E75; border-top:2px solid #586E75;overflow:hidden;zoom:1; }
#example-header h1 { float:left;padding:0;margin:0; }
#example-header #login-form { float:right;padding-top:15px; }
#example-header #login-form div { display:inline; }
#login-link { display:block;float:right;padding-top:15px; }
#login-link:focus { outline:none; }
#cboxContent form div { padding:5px 0; }
#cboxContent label { display:block; }
#cboxContent input[type='text'] { font-size:1.2em;padding:5px;width:342px;border:1px solid #ccc;box-shadow:inset 2px 2px 2px #ddd;border-radius:5px; }
#cboxContent input[type='submit'] { font-size:1.2em;padding:10px; }
</style>
</head>
<body>
<div id="example-header">
<h1>Ireland: The Emerald Isle</h1>
<form action="#" id="login-form">
<div><label for="username">Username:</label> <input type="text" id="username"/></div>
<div><label for="password">Password:</label> <input type="text" id="password"/></div>
<div><input type="submit" value="Log In"/></div>
</form>
</div>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="jquery.colorbox.js"></script>
<script>
$(document).ready(function() {
var form = $('#login-form');
form.hide();
form.before('<a href="#login-form" id="login-link">Login</a>');
$('#login-link').colorbox({
width: '400px',
inline: true,
scrolling: false,
content: $(this).attr('href'),
onOpen: function(){form.show();},
onComplete: function(){$.colorbox.resize();},
onCleanup: function(){form.hide();}
});
});
</script>
</body>
</html>
<!doctype html>
<head>
<link rel="stylesheet" href="colorbox.css" />
<style>
</style>
</head>
<body>
<h3>Favorite Videos</h3>
<ul>
<li><a href="http://www.youtube.com/embed/itn8TwFCO4M?autoplay=1" rel="favorites" title="Louis CK and Everything is Amazing">Everything is Amazing</a></li>
<li><a href="http://www.youtube.com/embed/UN0A6h9Wc5c?autoplay=1" rel="favorites" title="All This Beauty by The Weepies">All This Beauty</a></li>
<li><a href="http://www.youtube.com/embed/ZWtZA-ZmOAM?autoplay=1" rel="favorites" title="ABC's That's Incredible">That's Incredible</a></li>
</ul>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="jquery.colorbox.js"></script>
<script>
$(document).ready(function() {
$('a[rel="favorites"]').colorbox({
iframe: true,
innerWidth: '640px',
innerHeight: '480px',
current: 'Video {current} of {total}'
});
});
</script>
</body>
</html>
<!doctype html>
<head>
<link rel="stylesheet" href="colorbox.css" />
<style>
ul.thumb-list { margin:20px 0;padding:0;text-align:center; }
ul.thumb-list li { margin:0;padding:0;display:inline-block; }
</style>
</head>
<body>
<ul class="thumb-list">
<li>
<a href="http://www.colorado.com/sites/colorado.com/master/files/styles/large/public/CO_PhotoProject2007_0391.jpg" title="Flowers" rel="colorado">
<img src="http://www.colorado.com/sites/colorado.com/master/files/styles/photo_gallery_thumbnail/public/CO_PhotoProject2007_0391.jpg" alt="Flowers"/></a>
</li>
<li>
<a href="http://www.colorado.com/sites/colorado.com/master/files/styles/large/public/CO_PhotoProject2007_0389.jpg" title="Biker" rel="colorado">
<img src="http://www.colorado.com/sites/colorado.com/master/files/styles/photo_gallery_thumbnail/public/CO_PhotoProject2007_0389.jpg" alt="Biker"/></a>
</li>
<li>
<a href="http://www.colorado.com/sites/colorado.com/master/files/styles/large/public/CO_PhotoProject2007_0384.jpg" title="Winding Road" rel="colorado">
<img src="http://www.colorado.com/sites/colorado.com/master/files/styles/photo_gallery_thumbnail/public/CO_PhotoProject2007_0384.jpg" alt="Winding Road"/></a>
</li>
<li>
<a href="http://www.colorado.com/sites/colorado.com/master/files/styles/large/public/CO_PhotoProject2007_0378.jpg" title="Sunset" rel="colorado">
<img src="http://www.colorado.com/sites/colorado.com/master/files/styles/photo_gallery_thumbnail/public/CO_PhotoProject2007_0378.jpg" alt="Sunset"/></a>
</li>
</ul>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="jquery.colorbox.js"></script>
<script>
$(document).ready(function() {
$('a[rel="colorado"]').colorbox({
transition: 'fade',
width: '90%',
height: '60%',
slideshow: true,
slideshowSpeed: 2000,
slideshowAuto: false,
slideshowStart: 'START > Let\'s get started!',
slideshowStop: 'STOP > Okay, that\'s enough!'
});
});
</script>
</body>
</html>
/**
* @author trixta
* @version 1.2
*/
(function($){
var mwheelI = {
pos: [-260, -260]
},
minDif = 3,
doc = document,
root = doc.documentElement,
body = doc.body,
longDelay, shortDelay
;
function unsetPos(){
if(this === mwheelI.elem){
mwheelI.pos = [-260, -260];
mwheelI.elem = false;
minDif = 3;
}
}
$.event.special.mwheelIntent = {
setup: function(){
var jElm = $(this).bind('mousewheel', $.event.special.mwheelIntent.handler);
if( this !== doc && this !== root && this !== body ){
jElm.bind('mouseleave', unsetPos);
}
jElm = null;
return true;
},
teardown: function(){
$(this)
.unbind('mousewheel', $.event.special.mwheelIntent.handler)
.unbind('mouseleave', unsetPos)
;
return true;
},
handler: function(e, d){
var pos = [e.clientX, e.clientY];
if( this === mwheelI.elem || Math.abs(mwheelI.pos[0] - pos[0]) > minDif || Math.abs(mwheelI.pos[1] - pos[1]) > minDif ){
mwheelI.elem = this;
mwheelI.pos = pos;
minDif = 250;
clearTimeout(shortDelay);
shortDelay = setTimeout(function(){
minDif = 10;
}, 200);
clearTimeout(longDelay);
longDelay = setTimeout(function(){
minDif = 3;
}, 1500);
e = $.extend({}, e, {type: 'mwheelIntent'});
return $.event.handle.apply(this, arguments);
}
}
};
$.fn.extend({
mwheelIntent: function(fn) {
return fn ? this.bind("mwheelIntent", fn) : this.trigger("mwheelIntent");
},
unmwheelIntent: function(fn) {
return this.unbind("mwheelIntent", fn);
}
});
$(function(){
body = doc.body;
//assume that document is always scrollable, doesn't hurt if not
$(doc).bind('mwheelIntent.mwheelIntentDefault', $.noop);
});
})(jQuery);
<!doctype html>
<head>
<!-- CSS -->
<link rel="stylesheet" href="superfish.css"/>
<link rel="stylesheet" href="superfish-vertical.css"/>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="hoverIntent.js"></script>
<script src="superfish.js"></script>
<script>
$(document).ready(function() {
$('#sfNav').superfish({
animation: {height: 'show'}
});
//externalLinks();
});
/* Open up a link in a new window using a class to define such */
//function externalLinks() {}
</script>
<style>
.sf-menu li.sfHover ul,
.sf-menu li:hover ul {
left: -1px;
top: 70px; /* match top ul list item height */
z-index: 99;
}
ul.sf-menu > li {
background: #cc0000; /* Dark red background */
}
ul.sf-menu li li {
background: #0000cc; /* Dark blue background */
}
ul.sf-menu li li li {
background: #00cc00; /* Dark green background */
}
.sf-menu ul li:last-child a {
-webkit-border-bottom-right-radius: 7px;
-webkit-border-bottom-left-radius: 7px;
-moz-border-radius-bottomright: 7px;
-moz-border-radius-bottomleft: 7px;
border-bottom-right-radius: 7px; /*future proof */
border-bottom-left-radius: 7px; /*future proof */
}
/**** Level 1 ****/
.sf-menu,
.sf-menu * {
list-style: none;
margin: 0;
padding: 0;
}
.sf-menu {
background: #f6f6f6; /* Old browsers */
background: -moz-linear-gradient(top, rgba(0,0,0,1) 1%, rgba(56,56,56,1) 16%, rgba(255,255,255,1) 17%, rgba(246,246,246,1) 47%, rgba(237,237,237,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(1%,rgba(0,0,0,1)), color-stop(16%,rgba(56,56,56,1)), color-stop(17%,rgba(255,255,255,1)), color-stop(47%,rgba(246,246,246,1)), color-stop(100%,rgba(237,237,237,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* W3C */
float: left;
font-family: georgia, times, 'times new roman', serif;
font-size: 16px;
line-height: 14px;
margin: 28px 0 14px 0;
padding: 0 14px;
}
.sf-menu li {
border-left: 1px solid transparent;
border-right: 1px solid transparent;
float: left;
position: relative;
}
.sf-menu li.sfHover,
.sf-menu li:hover {
visibility: inherit; /* fixes IE7 'sticky bug' */
}
.sf-menu li.sfHover,
.sf-menu li:hover {
background: #DF6EA5;
border-color: #a22361;
-webkit-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
-moz-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
}
.sf-menu a {
border-left: 1px solid transparent;
border-right: 1px solid transparent;
color: #444;
display: block;
padding: 28px 14px;
position: relative;
width: 98px;
text-decoration: none;
}
.sf-menu li.sfHover a,
.sf-menu li:hover a {
background: #DF6EA5;
border-color: #fff;
color: #fff;
outline: 0;
}
.sf-menu a,
.sf-menu a:visited {
color: #444;
}
/***** Level 2 ****/
.sf-menu ul {
background: rgb(223,110,165); /* Old browsers */
background: -moz-linear-gradient(top, rgba(223,110,165,1) 0%, rgba(211,54,130,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(223,110,165,1)), color-stop(100%,rgba(211,54,130,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#df6ea5', endColorstr='#d33682',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* W3C */
-webkit-border-bottom-right-radius: 7px;
-webkit-border-bottom-left-radius: 7px;
-moz-border-radius-bottomright: 7px;
-moz-border-radius-bottomleft: 7px;
border-bottom-right-radius: 7px;
border-bottom-left-radius: 7px;
border: 1px solid #a22361;
border-top: 0 none;
margin: 0;
padding: 0;
position: absolute;
top: -999em;
left: 0;
width: 128px;
-webkit-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
-moz-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
font-size: 14px;
}
.sf-menu ul li {
border-left: 1px solid #fff;
border-right: 1px solid #fff;
display: block;
float: none;
}
.sf-menu ul li:last-child {
border-bottom: 1px solid #fff;
-webkit-border-bottom-right-radius: 7px;
-webkit-border-bottom-left-radius: 7px;
-moz-border-radius-bottomright: 7px;
-moz-border-radius-bottomleft: 7px;
border-bottom-right-radius: 7px;
border-bottom-left-radius: 7px;
}
.sf-menu ul li:last-child a {
-webkit-border-bottom-right-radius: 7px;
-webkit-border-bottom-left-radius: 7px;
-moz-border-radius-bottomright: 7px;
-moz-border-radius-bottomleft: 7px;
border-bottom-right-radius: 7px;
border-bottom-left-radius: 7px;
}
.sf-menu li.sfHover li.sfHover,
.sf-menu li:hover li:hover {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.sf-menu li.sfHover li.sfHover {
border-right-color: #cb2d79
}
.sf-menu li li a {
border: 0 none;
padding: 14px;
}
.sf-menu li li:first-child a {
padding-top: 0;
}
.sf-menu li li.sfHover a,
.sf-menu li li:hover a {
background: transparent;
border: 0 none;
color: #f8ddea;
outline: 0;
}
.sf-menu li li a:hover {
color: #f8ddea;
}
.sf-menu li.sfHover li a,
.sf-menu li:hover li a {
background: transparent;
}
.sf-menu li.sfHover li.sfHover a {
background: #cb2d79;
}
.sf-menu li.sfHover ul,
.sf-menu li:hover ul {
left: -1px;
top: 70px; /* match top ul list item height */
z-index: 99;
}
.sf-menu li li.sfHover,
.sf-menu li li:hover {
background: transparent;
border-color: #fff;
}
/**** Level 3 ****/
ul.sf-menu li.sfHover li ul,
ul.sf-menu li:hover li ul {
background: #cb2d79;
top: -999em;
-webkit-border-radius: 7px;
-webkit-border-top-left-radius: 0;
-moz-border-radius: 7px;
-moz-border-radius-topleft: 0;
border-radius: 7px;
border-top-left-radius: 0;
}
ul.sf-menu li.sfHover li ul li,
ul.sf-menu li:hover li ul li {
background: transparent;
border: 0 none;
}
ul.sf-menu li li.sfHover ul,
ul.sf-menu li li:hover ul {
left: 9em; /* match ul width */
top: 0;
}
.sf-menu li.sfHover li.sfHover li a,
.sf-menu li:hover li:hover li a {
background: transparent;
}
.sf-menu li li li:first-child a {
padding-top: 14px;
}
.sf-menu li li li a:hover {
background: transparent;
color: #fff;
}
/*** ARROWS ***/
.sf-sub-indicator {
display: none;
}
</style>
</head>
<body>
<ul id="sfNav" class="sf-menu">
<li><a href="#">Papilionidae</a>
<ul>
<li><a href="#">Common Yellow Swallowtail</a></li>
<li><a href="#">Spicebush Swallowtail</a></li>
<li><a href="#">Lime Butterfly</a></li>
<li><a href="#">Ornithoptera</a>
<ul>
<li><a href="#">Queen Victoria's Birdwing</a></li>
<li><a href="#">Wallace's Golden Birdwing</a></li>
<li><a href="#">Cape York Birdwing</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Pieridae</a>
<ul>
<li><a href="#">Small White</a></li>
<li><a href="#">Green-veined White</a></li>
<li><a href="#">Common Jezebel</a></li>
</ul>
</li>
<li><a href="#">Lycaenidae</a>
<ul>
<li><a href="#">Xerces Blue</a></li>
<li><a href="#">Karner Blue</a></li>
<li><a href="#">Red Pierrot</a></li>
</ul>
</li>
<li><a href="#">Riodinidae</a>
<ul>
<li><a href="#">Duke of Burgundy</a></li>
<li><a href="#">Plum Judy</a></li>
</ul>
</li>
<li><a href="#">Nymphalidae</a>
<ul>
<li><a href="#">Painted Lady</a></li>
<li><a href="#">Monarch</a></li>
<li><a href="#">Morpho</a>
<ul>
<li><a href="#">Sunset Morpho</a></li>
<li><a href="#">Godart's Morpho</a></li>
</ul>
</li>
<li><a href="#">Speckled Wood</a></li>
</ul>
</li>
<li><a href="#">Hesperiidae</a>
<ul>
<li><a href="#">Mallow Skipper</a></li>
<li><a href="#">Zabulon Skipper</a></li>
</ul>
</li>
</ul>
<!--
<h2>Vertical Flyout added with a class</h2>
<ul id="sfNav" class="sf-menu sf-vertical">
<li><a href="#">Papilionidae</a>
<ul>
<li><a href="#">Common Yellow Swallowtail</a></li>
<li><a href="#">Spicebush Swallowtail</a></li>
<li><a href="#">Lime Butterfly</a></li>
<li><a href="#">Ornithoptera</a>
<ul>
<li><a href="#">Queen Victoria's Birdwing</a></li>
<li><a href="#">Wallace's Golden Birdwing</a></li>
<li><a href="#">Cape York Birdwing</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Pieridae</a>
<ul>
<li><a href="#">Small White</a></li>
<li><a href="#">Green-veined White</a></li>
<li><a href="#">Common Jezebel</a></li>
</ul>
</li>
<li><a href="#">Lycaenidae</a>
<ul>
<li><a href="#">Xerces Blue</a></li>
<li><a href="#">Karner Blue</a></li>
<li><a href="#">Red Pierrot</a></li>
</ul>
</li>
<li><a href="#">Riodinidae</a>
<ul>
<li><a href="#">Duke of Burgundy</a></li>
<li><a href="#">Plum Judy</a></li>
</ul>
</li>
<li><a href="#">Nymphalidae</a>
<ul>
<li><a href="#">Painted Lady</a></li>
<li><a href="#">Monarch</a></li>
<li><a href="#">Morpho</a>
<ul>
<li><a href="#">Sunset Morpho</a></li>
<li><a href="#">Godart's Morpho</a></li>
</ul>
</li>
<li><a href="#">Speckled Wood</a></li>
</ul>
</li>
<li><a href="#">Hesperiidae</a>
<ul>
<li><a href="#">Mallow Skipper</a></li>
<li><a href="#">Zabulon Skipper</a></li>
</ul>
</li>
</ul>
-->
</body>
</html>
/*
* jQuery Nivo Slider v3.2
* http://nivo.dev7studios.com
*
* Copyright 2012, Dev7studios
* Free to use and abuse under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
/* The Nivo Slider styles */
.nivoSlider {
position:relative;
width:100%;
height:auto;
overflow: hidden;
}
.nivoSlider img {
position:absolute;
top:0px;
left:0px;
max-width: none;
}
.nivo-main-image {
display: block !important;
position: relative !important;
width: 100% !important;
}
/* If an image is wrapped in a link */
.nivoSlider a.nivo-imageLink {
position:absolute;
top:0px;
left:0px;
width:100%;
height:100%;
border:0;
padding:0;
margin:0;
z-index:6;
display:none;
background:white;
filter:alpha(opacity=0);
opacity:0;
}
/* The slices and boxes in the Slider */
.nivo-slice {
display:block;
position:absolute;
z-index:5;
height:100%;
top:0;
}
.nivo-box {
display:block;
position:absolute;
z-index:5;
overflow:hidden;
}
.nivo-box img { display:block; }
/* Caption styles */
.nivo-caption {
position:absolute;
left:0px;
bottom:0px;
background:#000;
color:#fff;
width:100%;
z-index:8;
padding: 5px 10px;
opacity: 0.8;
overflow: hidden;
display: none;
-moz-opacity: 0.8;
filter:alpha(opacity=8);
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
.nivo-caption p {
padding:5px;
margin:0;
}
.nivo-caption a {
display:inline !important;
}
.nivo-html-caption {
display:none;
}
/* Direction nav styles (e.g. Next & Prev) */
.nivo-directionNav a {
position:absolute;
top:45%;
z-index:9;
cursor:pointer;
}
.nivo-prevNav {
left:0px;
}
.nivo-nextNav {
right:0px;
}
/* Control nav styles (e.g. 1,2,3...) */
.nivo-controlNav {
text-align:center;
padding: 15px 0;
}
.nivo-controlNav a {
cursor:pointer;
}
.nivo-controlNav a.active {
font-weight:bold;
}
<!doctype html>
<head>
<link rel="stylesheet" href="" />
<style>
.thumbs { margin:0;padding:0;line-height:normal; }
.thumbs li { display:inline-block;vertical-align:top; padding:0;list-style-type:none;margin:0; }
.jsOff .thumbs li { width:100px;margin-bottom:5px;background:#fff; border:5px solid #fff;box-shadow:1px 1px 2px rgba(0,0,0,0.1) }
.jsOff .caption { min-height:52px;font-size:12px; line-height:14px; }
.jsOff #gallery { display:none; }
.jsOn .thumbs { width:288px; }
.jsOn .thumbs li { width:86px; }
.jsOn .thumbs img { border:3px solid #fff;max-width:80px;opacity:0.6; }
.jsOn #thumbs { float:left; }
#gallery { float:left;width:600px;position:relative;background:#fff;padding:10px;margin-bottom:20px;line-height:18px; }
.ss-controls { text-align:right;float:right;width:40%; }
.nav-controls { float:left:width:40%; }
#controls a { font-size:14px;color:#002B36;background:100% 0px no-repeat url(images/controls/sprite.png);padding-right:18px; }
#controls a.pause { background-position: 100% -18px; }
#controls a.prev { background-position: 0 -36px;padding-right:0;padding-left:18px;margin-right:10px; }
#controls a.next { background-position: 100% -54px; }
.caption { font-size:24px;padding:5px 0; }
.thumbs li.selected img { border-color:#000;opacity:1; }
</style>
</head>
<body class="jsOff">
<div id="thumbs">
<ul class="thumbs">
<li>
<a class="thumb" title="Agua Azul, Mexico" href="http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Agua_azul_downwards.jpg/640px-Agua_azul_downwards.jpg"><img src="http://www.roas.us/wp-content/gallery/aguaazul/thumbs/thumbs_aquaazul.jpg" alt="Agua Azul"/></a>
<div class="caption">Agua Azul, Mexico</div>
</li>
<li>
<a class="thumb" title="Burney Falls, California, USA" href="http://i19.photobucket.com/albums/b177/nava_jo/burneyfallsfront.jpg"><img src="http://images01.imikimi.com/image/1IBxe-1bp-1.jpg?height=75&scale=zoom&width=100" alt="Burney Falls"/></a>
<div class="caption">Burney Falls, California, USA</div>
</li>
<li>
<a class="thumb" title="Cachoeira do Pacheco, Venezuela" href="http://farm3.staticflickr.com/2064/1669151737_77a9b84682_z.jpg"><img src="http://mw2.google.com/mw-panoramio/photos/thumbnail/910045.jpg" alt="Cachoeira do Pacheco"/></a>
<div class="caption">Cachoeira do Pacheco, Venezuela</div>
</li>
</ul>
</div>
<div id="thumbs">...</div>
<div id="gallery">
<div id="controls"></div>
<div id="slideshow-container">
<div id="loading"></div>
<div id="slideshow"></div>
</div>
<div id="caption"></div>
</div>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="jquery.galleriffic.js"></script>
<script>
$(document).ready(function(){
$('body').removeClass('jsOff').addClass('jsOn');
$('#thumbs').galleriffic({
imageContainerSel: '#slideshow',
controlsContainerSel: '#controls',
captionContainerSel: '#caption',
loadingContainerSel: '#loading',
autoStart: true
});
});
</script>
</body>
</html>
<!doctype html>
<head>
<link rel="stylesheet" href="nivo-slider.css" />
<style>
#slideshow { position:relative;width:640px;height:480px; }
#slideshow img { position:absolute;top:0;left:0; }
</style>
</head>
<body>
<div id="slideshow">
<a href="http://en.wikipedia.org/wiki/Agua_Azul"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Agua_azul_downwards.jpg/640px-Agua_azul_downwards.jpg" alt="Agua Azul" title="Agua Azul"/></a>
<a href="http://en.wikipedia.org/wiki/Burney_Falls"><img src="http://i19.photobucket.com/albums/b177/nava_jo/burneyfallsfront.jpg" alt="Burney Falls" title="Burney Falls"/></a>
<a href="http://en.wikipedia.org/wiki/Venezuala"><img src="http://farm3.staticflickr.com/2064/1669151737_77a9b84682_z.jpg" alt="Cachoeira do Pacheco" title="Cachoeira do Pacheco"/></a>
</div>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="jquery.nivo.slider.pack.js"></script>
<script>
$(document).ready(function(){
$('#slideshow').nivoSlider({
effect: 'boxRain',
boxCols: 10,
boxRows: 5,
animSpeed: 800,
pauseTime: 4000
});
});
</script>
</body>
</html>
<!doctype html>
<head>
<style>
#crossfade { position:relative;margin:0;padding:0;list-style-type:none;width:600px;height:400px;overflow:hidden; }
#crossfade li { position:absolute;width:600px;height:400px; }
</style>
</head>
<body>
<ul id="crossfade">
<li>
<a href="http://en.wikipedia.org/wiki/Agua_Azul"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Agua_azul_downwards.jpg/640px-Agua_azul_downwards.jpg" alt="Agua Azul"/></a>
</li>
<li>
<a href="http://en.wikipedia.org/wiki/Burney_Falls"><img src="http://i19.photobucket.com/albums/b177/nava_jo/burneyfallsfront.jpg" alt="Burney Falls"/></a>
</li>
<li>
<a href="http://en.wikipedia.org/wiki/Venezuala"><img src="http://farm3.staticflickr.com/2064/1669151737_77a9b84682_z.jpg" alt="Cachoeira do Pacheco"/></a>
</li>
</ul>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function slideshow() {
$('#crossfade li:first').fadeOut('slow').next().fadeIn('slow').end().appendTo('#crossfade');
}
$(document).ready(function(){
$('#crossfade li').hide().filter(':first').show();
setInterval(slideshow, 3000);
});
</script>
</body>
</html>
/*** adding sf-vertical in addition to sf-menu creates a vertical menu ***/
.sf-vertical, .sf-vertical li {
width: 10em;
}
/* this lacks ul at the start of the selector, so the styles from the main CSS file override it where needed */
.sf-vertical li:hover ul,
.sf-vertical li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
}
/*** alter arrow directions ***/
.sf-vertical .sf-sub-indicator { background-position: -10px 0; } /* IE6 gets solid image only */
.sf-vertical a > .sf-sub-indicator { background-position: 0 0; } /* use translucent arrow for modern browsers*/
/* hover arrow direction for modern browsers*/
.sf-vertical a:focus > .sf-sub-indicator,
.sf-vertical a:hover > .sf-sub-indicator,
.sf-vertical a:active > .sf-sub-indicator,
.sf-vertical li:hover > a > .sf-sub-indicator,
.sf-vertical li.sfHover > a > .sf-sub-indicator {
background-position: -10px 0; /* arrow hovers for modern browsers*/
}
/*** ESSENTIAL STYLES ***/
.sf-menu, .sf-menu * {
margin: 0;
padding: 0;
list-style: none;
}
.sf-menu {
line-height: 1.0;
}
.sf-menu ul {
position: absolute;
top: -999em;
width: 10em; /* left offset of submenus need to match (see below) */
}
.sf-menu ul li {
width: 100%;
}
.sf-menu li:hover {
visibility: inherit; /* fixes IE7 'sticky bug' */
}
.sf-menu li {
float: left;
position: relative;
}
.sf-menu a {
display: block;
position: relative;
}
.sf-menu li:hover ul,
.sf-menu li.sfHover ul {
left: 0;
top: 2.5em; /* match top ul list item height */
z-index: 99;
}
ul.sf-menu li:hover li ul,
ul.sf-menu li.sfHover li ul {
top: -999em;
}
ul.sf-menu li li:hover ul,
ul.sf-menu li li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
}
ul.sf-menu li li:hover li ul,
ul.sf-menu li li.sfHover li ul {
top: -999em;
}
ul.sf-menu li li li:hover ul,
ul.sf-menu li li li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
}
/*** DEMO SKIN ***/
.sf-menu {
float: left;
margin-bottom: 1em;
}
.sf-menu ul {
box-shadow: 2px 2px 6px rgba(0,0,0,.2);
}
.sf-menu a {
border-left: 1px solid #fff;
border-top: 1px solid #CFDEFF;
padding: .75em 1em;
text-decoration:none;
}
.sf-menu a, .sf-menu a:visited { /* visited pseudo selector so IE6 applies text colour*/
color: #13a;
}
.sf-menu li {
background: #BDD2FF;
}
.sf-menu li li {
background: #AABDE6;
}
.sf-menu li li li {
background: #9AAEDB;
}
.sf-menu li:hover, .sf-menu li.sfHover,
.sf-menu a:focus, .sf-menu a:hover, .sf-menu a:active {
background: #CFDEFF;
outline: 0;
}
/*** arrows **/
.sf-menu a.sf-with-ul {
padding-right: 2.25em;
min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */
}
.sf-sub-indicator {
position: absolute;
display: block;
right: .75em;
top: 1.05em; /* IE6 only */
width: 10px;
height: 10px;
text-indent: -999em;
overflow: hidden;
background: url('../images/arrows-ffffff.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */
}
a > .sf-sub-indicator { /* give all except IE6 the correct values */
top: .8em;
background-position: 0 -100px; /* use translucent arrow for modern browsers*/
}
/* apply hovers to modern browsers */
a:focus > .sf-sub-indicator,
a:hover > .sf-sub-indicator,
a:active > .sf-sub-indicator,
li:hover > a > .sf-sub-indicator,
li.sfHover > a > .sf-sub-indicator {
background-position: -10px -100px; /* arrow hovers for modern browsers*/
}
/* point right for anchors in subs */
.sf-menu ul .sf-sub-indicator { background-position: -10px 0; }
.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; }
/* apply hovers to modern browsers */
.sf-menu ul a:focus > .sf-sub-indicator,
.sf-menu ul a:hover > .sf-sub-indicator,
.sf-menu ul a:active > .sf-sub-indicator,
.sf-menu ul li:hover > a > .sf-sub-indicator,
.sf-menu ul li.sfHover > a > .sf-sub-indicator {
background-position: -10px 0; /* arrow hovers for modern browsers*/
}
/*
* Superfish v1.5.13 - jQuery menu widget
* Copyright (c) 2013 Joel Birch
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
;(function($){
$.fn.superfish = function(op){
var sf = $.fn.superfish,
c = sf.c,
$arrow = $('<span class="'+c.arrowClass+'"> &#187;</span>'),
over = function(){
var $$ = $(this), menu = getMenu($$);
clearTimeout(menu.sfTimer);
$$.showSuperfishUl().siblings().hideSuperfishUl();
},
out = function(e){
var $$ = $(this), menu = getMenu($$), o = sf.op;
var close = function(){
o.retainPath=($.inArray($$[0],o.$path)>-1);
$$.hideSuperfishUl();
if (o.$path.length && $$.parents('li.'+o.hoverClass).length<1){
o.onIdle.call();
$.proxy(over,o.$path,e)();
}
};
if (e.type === 'click'){
close();
} else {
clearTimeout(menu.sfTimer);
menu.sfTimer=setTimeout(close,o.delay);
}
},
getMenu = function($child){
if ($child.hasClass(c.menuClass)){
$.error('Superfish requires you to update to a version of hoverIntent that supports event-delegation, such as this one: https://github.com/joeldbirch/onHoverIntent');
}
var menu = $child.closest('.'+c.menuClass)[0];
sf.op = sf.o[menu.serial];
return menu;
},
applyTouchAction = function($menu){
//needed by MS pointer events
$menu.css('ms-touch-action','none');
},
applyHandlers = function($menu){
var targets = 'li:has(ul)';
if (!sf.op.useClick){
if ($.fn.hoverIntent && !sf.op.disableHI){
$menu.hoverIntent(over, out, targets);
} else {
$menu
.on('mouseenter', targets, over)
.on('mouseleave', targets, out);
}
}
var touchstart = 'MSPointerDown';
//Sorry, but avoiding weird glitches with touchstart. iOS doesn't need it, anyway.
if ( !navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad)/) ){
touchstart += ' touchstart';
}
$menu
.on('focusin', 'li', over)
.on('focusout', 'li', out)
.on('click', 'a', clickHandler)
.on(touchstart, 'a', touchHandler);
},
touchHandler = function(e){
var $$ = $(this),
$ul = $$.siblings('ul');
if ($ul.length > 0 && !$ul.is(':visible')){
$$.data('follow', false);
if (e.type === 'MSPointerDown'){
$$.trigger('focus');
return false;
}
}
},
clickHandler = function(e){
var $a = $(this),
$submenu = $a.siblings('ul'),
follow = ($a.data('follow') === false) ? false : true;
if ( $submenu.length && (sf.op.useClick || !follow) ){
e.preventDefault();
if (!$submenu.is(':visible')){
$.proxy(over,$a.parent('li'))();
} else if (sf.op.useClick && follow) {
$.proxy(out,$a.parent('li'),e)();
}
}
},
addArrows = function($li,o){
if (o.autoArrows) {
$li.children('a').each(function() {
addArrow( $(this) );
});
}
},
addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
return this.addClass(c.menuClass).each(function() {
var s = this.serial = sf.o.length;
var o = $.extend({},sf.defaults,op);
var $$ = $(this);
var $liHasUl = $$.find('li:has(ul)');
o.$path = $$.find('li.'+o.pathClass).slice(0,o.pathLevels).each(function(){
$(this).addClass(o.hoverClass+' '+c.bcClass)
.filter('li:has(ul)').removeClass(o.pathClass);
});
sf.o[s] = sf.op = o;
addArrows($liHasUl,o);
applyTouchAction($$);
applyHandlers($$);
$liHasUl.not('.'+c.bcClass).children('ul').show().hide();
o.onInit.call(this);
});
};
var sf = $.fn.superfish;
sf.o = [];
sf.op = {};
sf.c = {
bcClass : 'sf-breadcrumb',
menuClass : 'sf-js-enabled',
anchorClass : 'sf-with-ul',
arrowClass : 'sf-sub-indicator'
};
sf.defaults = {
hoverClass : 'sfHover',
pathClass : 'overideThisToUse',
pathLevels : 1,
delay : 800,
animation : {opacity:'show'},
animationOut: {opacity:'hide'},
speed : 'normal',
speedOut : 'fast',
autoArrows : true,
disableHI : false, // true disables hoverIntent detection
useClick : false,
onInit : function(){}, // callback functions
onBeforeShow: function(){},
onShow : function(){},
onHide : function(){},
onIdle : function(){}
};
$.fn.extend({
hideSuperfishUl : function(){
var o = sf.op,
$$ = this,
not = (o.retainPath===true) ? o.$path : '';
o.retainPath = false;
$('li.'+o.hoverClass,this).add(this).not(not)
.children('ul').stop(true,true).animate(o.animationOut,o.speedOut,function(){
$ul = $(this);
$ul.parent().removeClass(o.hoverClass);
o.onHide.call($ul);
if (sf.op.useClick){
$$.children('a').data('follow', false);
}
});
return this;
},
showSuperfishUl : function(){
var o = sf.op,
$$ = this,
$ul = this.children('ul');
$$.addClass(o.hoverClass);
o.onBeforeShow.call($ul);
$ul.stop(true,true).animate(o.animation,o.speed,function(){
o.onShow.call($ul);
$$.children('a').data('follow', true);
});
return this;
}
});
})(jQuery);
<!doctype html>
<head>
<title>Tooltips</title>
<link rel="stylesheet" href="http://craigsworks.com/projects/qtip_new/packages/nightly/jquery.qtip.css">
<link rel="stylesheet" href="http://media1.juggledesign.com/qtip2/css/demos.css">
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://craigsworks.com/projects/qtip_new/packages/nightly/jquery.qtip.js"></script>
<script>
$(document).ready(function() {
//Functions
//function();
$('a[title]').qtip({
postion: {
at: 'top right'
}
});
});
/* Javacript */
//function functionName() {}
</script>
<style>
/* CSS */
/* Set a slightly bigger max-width so we can fit in our photos */
.ui-tooltip-flickr{
max-width: 700px;
}
/* Adds the flickr favicon to the top right of the tooltip :) */
.ui-tooltip-flickr .ui-tooltip-titlebar{
background-image: url('http://l.yimg.com/g/favicon.ico');
background-repeat: no-repeat;
background-position: 97% 7px;
}
.ui-tooltip-flickr .ui-tooltip-title{
padding-right: 0;
}
.ui-tooltip-flickr img{
margin: 0 auto;
}
</style>
</head>
<body>
<p>Here's a list of links:</p>
<ul>
<li><a href="home.html" title="An introduction to who we are and what we do">Home</a></li>
<li><a href ="about.html" title="Learn more about our company">About</a></li>
<li><a href="contact.html" title="Send us a message. We'd love to hear from you!">Contact</a></li>
<li><a href="work.html" title="View a portfolio of the work we've done for our clients">Our Work</a></li>
</ul>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment