1 2 3 4 5/* 6 * Basic jQuery Slider plug-in v.1.3 7 * 8 * http://www.basic-slider.com 9 * 10 * Authored by John Cobb 11 * http://www.johncobb.name 12 * @john0514 13 * 14 * Copyright 2011, John Cobb 15 * License: GNU General Public License, version 3 (GPL-3.0) 16 * http://www.opensource.org/licenses/gpl-3.0.html 17 * 18 */ 19 20;(function($) { 21 22 "use strict"; 23 24 $.fn.bjqs = function(o) { 25 26 // slider default settings 27 var defaults = { 28 29 // w + h to enforce consistency 30 width : 700, 31 height : 300, 32 33 // transition valuess 34 animtype : 'fade', 35 animduration : 450, // length of transition 36 animspeed : 4000, // delay between transitions 37 automatic : true, // enable/disable automatic slide rotation 38 39 // control and marker configuration 40 showcontrols : true, // enable/disable next + previous UI elements 41 centercontrols : true, // vertically center controls 42 nexttext : 'Next', // text/html inside next UI element 43 prevtext : 'Prev', // text/html inside previous UI element 44 showmarkers : true, // enable/disable individual slide UI markers 45 centermarkers : true, // horizontally center markers 46 47 // interaction values 48 keyboardnav : true, // enable/disable keyboard navigation 49 hoverpause : true, // enable/disable pause slides on hover 50 51 // presentational options 52 usecaptions : true, // enable/disable captions using img title attribute 53 randomstart : false, // start from a random slide 54 responsive : false, // enable responsive behaviour 55 56 captionUrlArray : [] //Url for each of the captions 57 58 }; 59 60 // create settings from defauls and user options 61 var settings = $.extend({}, defaults, o); 62 63 // slider elements 64 var $wrapper = this, 65 $slider = $wrapper.find('ul.bjqs'), 66 $slides = $slider.children('li'), 67 68 // control elements 69 $c_wrapper = null, 70 $c_fwd = null, 71 $c_prev = null, 72 73 // marker elements 74 $m_wrapper = null, 75 $m_markers = null, 76 77 // elements for slide animation 78 $canvas = null, 79 $clone_first = null, 80 $clone_last = null; 81 82 // state management object 83 var state = { 84 slidecount : $slides.length, // total number of slides 85 animating : false, // bool: is transition is progress 86 paused : false, // bool: is the slider paused 87 currentslide : 1, // current slide being viewed (not 0 based) 88 nextslide : 0, // slide to view next (not 0 based) 89 currentindex : 0, // current slide being viewed (0 based) 90 nextindex : 0, // slide to view next (0 based) 91 interval : null // interval for automatic rotation 92 }; 93 94 var responsive = { 95 width : null, 96 height : null, 97 ratio : null 98 }; 99 100 // helpful variables 101 var vars = { 102 fwd : 'forward', 103 prev : 'previous' 104 }; 105 106 // run through options and initialise settings 107 var init = function() { 108 109 // differentiate slider li from content li 110 $slides.addClass('bjqs-slide'); 111 112 // conf dimensions, responsive or static 113 if( settings.responsive ){ 114 conf_responsive(); 115 } 116 else{ 117 conf_static(); 118 } 119 120 // configurations only avaliable if more than 1 slide 121 if( state.slidecount > 1 ){ 122 123 // enable random start 124 if (settings.randomstart){ 125 conf_random(); 126 } 127 128 // create and show controls 129 if( settings.showcontrols ){ 130 conf_controls(); 131 } 132 133 // create and show markers 134 if( settings.showmarkers ){ 135 conf_markers(); 136 } 137 138 // enable slidenumboard navigation 139 if( settings.keyboardnav ){ 140 conf_keynav(); 141 } 142 143 // enable pause on hover 144 if (settings.hoverpause && settings.automatic){ 145 conf_hoverpause(); 146 } 147 148 // conf slide animation 149 if (settings.animtype === 'slide'){ 150 conf_slide(); 151 } 152 153 } else { 154 // Stop automatic animation, because we only have one slide! 155 settings.automatic = false;
156 } 157 158 if(settings.usecaptions){ 159 conf_captions(); 160 } 161 162 // TODO: need to accomodate random start for slide transition setting 163 if(settings.animtype === 'slide' && !settings.randomstart){ 164 state.currentindex = 1; 165 state.currentslide = 2; 166 } 167 168 // slide components are hidden by default, show them now 169 $slider.show(); 170 $slides.eq(state.currentindex).show(); 171 172 // Finally, if automatic is set to true, kick off the interval 173 if(settings.automatic){ 174 state.interval = setInterval(function () { 175 go(vars.fwd, false); 176 }, settings.animspeed); 177 } 178 179 }; 180 181 var conf_responsive = function() { 182 183 responsive.width = $wrapper.outerWidth(); 184 responsive.ratio = responsive.width/settings.width, 185 responsive.height = settings.height * responsive.ratio; 186 187 if(settings.animtype === 'fade'){ 188 189 // initial setup 190 $slides.css({ 191 'height' : settings.height, 192 'width' : '100%' 193 }); 194 $slides.children('img').css({ 195 'height' : settings.height, 196 'width' : '100%' 197 }); 198 $slider.css({ 199 'height' : settings.height, 200 'width' : '100%' 201 }); 202 $wrapper.css({ 203 'height' : settings.height, 204 'max-width' : settings.width, 205 'position' : 'relative' 206 }); 207 208 if(responsive.width < settings.width){ 209 210 $slides.css({ 211 'height' : responsive.height 212 }); 213 $slides.children('img').css({ 214 'height' : responsive.height 215 }); 216 $slider.css({ 217 'height' : responsive.height 218 }); 219 $wrapper.css({ 220 'height' : responsive.height 221 }); 222 223 } 224 225 $(window).resize(function() { 226 227 // calculate and update dimensions 228 responsive.width = $wrapper.outerWidth(); 229 responsive.ratio = responsive.width/settings.width, 230 responsive.height = settings.height * responsive.ratio; 231 232 $slides.css({ 233 'height' : responsive.height 234 }); 235 $slides.children('img').css({ 236 'height' : responsive.height 237 }); 238 $slider.css({ 239 'height' : responsive.height 240 }); 241 $wrapper.css({ 242 'height' : responsive.height 243 }); 244 245 }); 246 247 } 248 249 if(settings.animtype === 'slide'){ 250 251 // initial setup 252 $slides.css({ 253 'height' : settings.height, 254 'width' : settings.width 255 }); 256 $slides.children('img').css({ 257 'height' : settings.height, 258 'width' : settings.width 259 }); 260 $slider.css({ 261 'height' : settings.height, 262 'width' : settings.width * settings.slidecount 263 }); 264 $wrapper.css({ 265 'height' : settings.height, 266 'max-width' : settings.width, 267 'position' : 'relative' 268 }); 269 270 if(responsive.width < settings.width){ 271 272 $slides.css({ 273 'height' : responsive.height 274 }); 275 $slides.children('img').css({ 276 'height' : responsive.height 277 }); 278 $slider.css({ 279 'height' : responsive.height 280 }); 281 $wrapper.css({ 282 'height' : responsive.height 283 }); 284 285 } 286 287 $(window).resize(function() { 288 289 // calculate and update dimensions 290 responsive.width = $wrapper.outerWidth(), 291 responsive.ratio = responsive.width/settings.width, 292 responsive.height = settings.height * responsive.ratio; 293 294 $slides.css({ 295 'height' : responsive.height, 296 'width' : responsive.width 297 }); 298 $slides.children('img').css({ 299 'height' : responsive.height, 300 'width' : responsive.width 301 }); 302 $slider.css({ 303 'height' : responsive.height, 304 'width' : responsive.width * settings.slidecount 305 }); 306 $wrapper.css({ 307 'height' : responsive.height 308 }); 309 $canvas.css({ 310 'height' : responsive.height, 311 'width' : responsive.width 312 }); 313 314 resize_complete(function(){ 315 go(false,state.currentslide); 316 }, 200, "some unique string"); 317 318 }); 319 320 } 321 322 }; 323 324 var resize_complete = (function () { 325 326 var timers = {}; 327 328 return function (callback, ms, uniqueId) { 329 if (!uniqueId) { 330 uniqueId = "Don't call this twice without a uniqueId"; 331 } 332 if (timers[uniqueId]) { 333 clearTimeout (timers[uniqueId]); 334 } 335 timers[uniqueId] = setTimeout(callback, ms); 336 }; 337 338 })(); 339 340 // enforce fixed sizing on slides, slider and wrapper 341 var conf_static = function() { 342 343 $slides.css({ 344 'height' : settings.height, 345 'width' : settings.width 346 }); 347 $slider.css({ 348 'height' : settings.height, 349 'width' : settings.width 350 }); 351 $wrapper.css({ 352 'height' : settings.height, 353 'width' : settings.width, 354 'position' : 'relative' 355 }); 356 357 }; 358 359 var conf_slide = function() { 360 361 // create two extra elements which are clones of the first and last slides 362 $clone_first = $slides.eq(0).clone(); 363 $clone_last = $slides.eq(state.slidecount-1).clone(); 364 365 // add them to the DOM where we need them
366 $clone_first.attr({'data-clone' : 'last', 'data-slide' : 0}).appendTo($slider).show(); 367 $clone_last.attr({'data-clone' : 'first', 'data-slide' : 0}).prependTo($slider).show(); 368 369 // update the elements object 370 $slides = $slider.children('li'); 371 state.slidecount = $slides.length; 372 373 // create a 'canvas' element which is neccessary for the slide animation to work 374 $canvas = $('<div class="bjqs-wrapper"></div>'); 375 376 // if the slider is responsive && the calculated width is less than the max width 377 if(settings.responsive && (responsive.width < settings.width)){ 378 379 $canvas.css({ 380 'width' : responsive.width, 381 'height' : responsive.height, 382 'overflow' : 'hidden', 383 'position' : 'relative' 384 }); 385 386 // update the dimensions to the slider to accomodate all the slides side by side 387 $slider.css({ 388 'width' : responsive.width * (state.slidecount + 2), 389 'left' : -responsive.width * state.currentslide 390 }); 391 392 } 393 else { 394 395 $canvas.css({ 396 'width' : settings.width, 397 'height' : settings.height, 398 'overflow' : 'hidden', 399 'position' : 'relative' 400 }); 401 402 // update the dimensions to the slider to accomodate all the slides side by side 403 $slider.css({ 404 'width' : settings.width * (state.slidecount + 2), 405 'left' : -settings.width * state.currentslide 406 }); 407 408 } 409 410 // add some inline styles which will align our slides for left-right sliding 411 $slides.css({ 412 'float' : 'left', 413 'position' : 'relative', 414 'display' : 'list-item' 415 }); 416 417 // 'everything.. in it's right place' 418 $canvas.prependTo($wrapper); 419 $slider.appendTo($canvas); 420 421 }; 422 423 var conf_controls = function() { 424 425 // create the elements for the controls 426 $c_wrapper = $('<ul class="bjqs-controls"></ul>'); 427 $c_fwd = $('<li class="bjqs-next"><a href="#" data-direction="'+ vars.fwd +'">' + settings.nexttext + '</a></li>'); 428 $c_prev = $('<li class="bjqs-prev"><a href="#" data-direction="'+ vars.prev +'">' + settings.prevtext + '</a></li>'); 429 430 // bind click events 431 $c_wrapper.on('click','a',function(e){ 432 433 e.preventDefault(); 434 var direction = $(this).attr('data-direction'); 435 436 if(!state.animating){ 437 438 if(direction === vars.fwd){ 439 go(vars.fwd,false); 440 } 441 442 if(direction === vars.prev){ 443 go(vars.prev,false); 444 } 445 446 } 447 448 }); 449 450 // put 'em all together 451 $c_prev.appendTo($c_wrapper); 452 $c_fwd.appendTo($c_wrapper); 453 $c_wrapper.appendTo($wrapper); 454 455 // vertically center the controls 456 if (settings.centercontrols) { 457 458 $c_wrapper.addClass('v-centered'); 459 460 // calculate offset % for vertical positioning 461 var offset_px = ($wrapper.height() - $c_fwd.children('a').outerHeight()) / 2, 462 ratio = (offset_px / settings.height) * 100, 463 offset = ratio + '%'; 464 465 $c_fwd.find('a').css('top', offset); 466 $c_prev.find('a').css('top', offset); 467 468 } 469 470 }; 471 472 var conf_markers = function() { 473 474 // create a wrapper for our markers 475 $m_wrapper = $('<ol class="bjqs-markers"></ol>'); 476 477 // for every slide, create a marker 478 $.each($slides, function(key, slide){ 479 480 var slidenum = $(slide).attr('title') === undefined ? key + 1 : $(slide).attr('title'), 481 gotoslide = key + 1; 482 483 if(settings.animtype === 'slide'){ 484 // + 2 to account for clones 485 gotoslide = key + 2; 486 } 487 488 var newUrl = settings.captionUrlArray[key]; 489 var marker = $('<li><a href="' + (newUrl?newUrl:'#') + '">'+ slidenum +'</a></li>'); 490 491 // set the first marker to be active 492 if(slidenum === state.currentslide){ marker.addClass('active-marker'); } 493 494 // bind hover event 495 marker.on('mouseover','a',function(e){ 496 e.preventDefault(); 497 if(!state.animating && state.currentslide !== gotoslide){ 498 go(false,gotoslide); 499 } 500 }); 501 502 // add the marker to the wrapper 503 marker.appendTo($m_wrapper); 504 505 }); 506 507 $m_wrapper.appendTo($wrapper); 508 $m_markers = $m_wrapper.find('li'); 509 510 // center the markers 511 if (settings.centermarkers) { 512 $m_wrapper.addClass('h-centered'); 513 var offset = (settings.width - $m_wrapper.width()) / 2; 514 $m_wrapper.css('left', offset); 515 } 516 517 }; 518 519 var conf_keynav = function() { 520 521 $(document).keyup(function (event) { 522 523 if (!state.paused) { 524 clearInterval(state.interval); 525 state.paused = true; 526 } 527 528 if (!state.animating) { 529 if (event.keyCode === 39) { 530 event.preventDefault(); 531 go(vars.fwd, false); 532 } else if (event.keyCode === 37) { 533 event.preventDefault(); 534 go(vars.prev, false); 535 } 536 } 537 538 if (state.paused && settings.automatic) { 539 state.interval = setInterval(function () { 540 go(vars.fwd); 541 }, settings.animspeed); 542 state.paused = false;
543 } 544 545 }); 546 547 }; 548 549 var conf_hoverpause = function() { 550 551 $wrapper.hover(function () { 552 if (!state.paused) { 553 clearInterval(state.interval); 554 state.paused = true; 555 } 556 }, function () { 557 if (state.paused) { 558 state.interval = setInterval(function () { 559 go(vars.fwd, false); 560 }, settings.animspeed); 561 state.paused = false; 562 } 563 }); 564 565 }; 566 567 var conf_captions = function() { 568 569 $.each($slides, function (key, slide) { 570 571 var caption = $(slide).children('img:first-child').attr('title'); 572 573 // Account for images wrapped in links 574 if(!caption){ 575 caption = $(slide).children('a').find('img:first-child').attr('title'); 576 } 577 578 if (caption) { 579 caption = $('<p class="bjqs-caption">' + caption + '</p>'); 580 caption.appendTo($(slide)); 581 } 582 583 }); 584 585 }; 586 587 var conf_random = function() { 588 589 var rand = Math.floor(Math.random() * state.slidecount) + 1; 590 state.currentslide = rand; 591 state.currentindex = rand-1; 592 593 }; 594 595 var set_next = function(direction) { 596 597 if(direction === vars.fwd){ 598 599 if($slides.eq(state.currentindex).next().length){ 600 state.nextindex = state.currentindex + 1; 601 state.nextslide = state.currentslide + 1; 602 } 603 else{ 604 state.nextindex = 0; 605 state.nextslide = 1; 606 } 607 608 } 609 else{ 610 611 if($slides.eq(state.currentindex).prev().length){ 612 state.nextindex = state.currentindex - 1; 613 state.nextslide = state.currentslide - 1; 614 } 615 else{ 616 state.nextindex = state.slidecount - 1; 617 state.nextslide = state.slidecount; 618 } 619 620 } 621 622 }; 623 624 var go = function(direction, position) { 625 626 // only if we're not already doing things 627 if(!state.animating){ 628 629 // doing things 630 state.animating = true; 631 632 if(position){ 633 state.nextslide = position; 634 state.nextindex = position-1; 635 } 636 else{ 637 set_next(direction); 638 } 639 640 // fade animation 641 if(settings.animtype === 'fade'){ 642 643 if(settings.showmarkers){ 644 $m_markers.removeClass('active-marker'); 645 $m_markers.eq(state.nextindex).addClass('active-marker'); 646 } 647 648 // fade out current 649 $slides.eq(state.currentindex).fadeOut(settings.animduration); 650 // fade in next 651 $slides.eq(state.nextindex).fadeIn(settings.animduration, function(){ 652 653 // update state variables 654 state.animating = false; 655 state.currentslide = state.nextslide; 656 state.currentindex = state.nextindex; 657 658 }); 659 660 } 661 662 // slide animation 663 if(settings.animtype === 'slide'){ 664 665 if(settings.showmarkers){ 666 667 var markerindex = state.nextindex-1; 668 669 if(markerindex === state.slidecount-2){ 670 markerindex = 0; 671 } 672 else if(markerindex === -1){ 673 markerindex = state.slidecount-3; 674 } 675 676 $m_markers.removeClass('active-marker'); 677 $m_markers.eq(markerindex).addClass('active-marker'); 678 } 679 680 // if the slider is responsive && the calculated width is less than the max width 681 if(settings.responsive && ( responsive.width < settings.width ) ){ 682 state.slidewidth = responsive.width; 683 } 684 else{ 685 state.slidewidth = settings.width; 686 } 687 688 $slider.animate({'left': -state.nextindex * state.slidewidth }, settings.animduration, function(){ 689 690 state.currentslide = state.nextslide; 691 state.currentindex = state.nextindex; 692 693 // is the current slide a clone? 694 if($slides.eq(state.currentindex).attr('data-clone') === 'last'){ 695 696 // affirmative, at the last slide (clone of first) 697 $slider.css({'left': -state.slidewidth }); 698 state.currentslide = 2; 699 state.currentindex = 1; 700 701 } 702 else if($slides.eq(state.currentindex).attr('data-clone') === 'first'){ 703 704 // affirmative, at the fist slide (clone of last) 705 $slider.css({'left': -state.slidewidth *(state.slidecount - 2)}); 706 state.currentslide = state.slidecount - 1; 707 state.currentindex = state.slidecount - 2; 708 709 } 710 711 state.animating = false;
712 713 }); 714 715 } 716 717 } 718 719 }; 720 721 // lets get the party started :) 722 init(); 723 724 }; 725 726})(jQuery); 727
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.