1/* 2 * jQuery SmoothDivScroll 1.3 3 * 4 * Copyright (c) 2013 Thomas Kahn 5 * Licensed under the GPL license. 6 * 7 * http://www.smoothdivscroll.com/ 8 * 9 * Depends: 10 * jquery-1.10.2.min.js 11 Please use https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js 12 ...or later 13 14 * jquery-ui-1.10.3.custom.min 15 Make your own custom download at http://jqueryui.com/download. 16 First deselect all components. Then check just "Widget" and "Effects Core". 17 Download the file and put it in your javascript folder. 18 19 * jquery.mousewheel.min.js 20 Used for mousewheel functionality. 21 Download the latest version at https://github.com/brandonaaron/jquery-mousewheel 22 * 23 24 * jquery.kinetic.min.js 25 Used for scrolling by dragging, mainly used on touch devices. 26 Download the latest version at https://github.com/davetayls/jquery.kinetic 27 * 28 */ 29(function($) { 30 31 $.widget("thomaskahn.smoothDivScroll", { 32 // Default options 33 options: { 34 // Classes for elements added by Smooth Div Scroll 35 scrollingHotSpotLeftClass: "scrollingHotSpotLeft", // String 36 scrollingHotSpotRightClass: "scrollingHotSpotRight", // String 37 scrollingHotSpotLeftVisibleClass: "scrollingHotSpotLeftVisible", // String 38 scrollingHotSpotRightVisibleClass: "scrollingHotSpotRightVisible", // String 39 scrollableAreaClass: "scrollableArea", // String 40 scrollWrapperClass: "scrollWrapper", // String 41 42 // Misc settings 43 hiddenOnStart: false, // Boolean 44 getContentOnLoad: {}, // Object 45 countOnlyClass: "", // String 46 startAtElementId: "", // String 47 48 // Hotspot scrolling 49 hotSpotScrolling: true, // Boolean 50 hotSpotScrollingStep: 1500, // Pixels 51 hotSpotScrollingInterval: 10, // Milliseconds 52 hotSpotMouseDownSpeedBooster: 3, // Integer 53 visibleHotSpotBackgrounds: "hover", // always, onStart, hover or empty (no visible hotspots) 54 hotSpotsVisibleTime: 5000, // Milliseconds 55 easingAfterHotSpotScrolling: true, // Boolean 56 easingAfterHotSpotScrollingDistance: 10, // Pixels 57 easingAfterHotSpotScrollingDuration: 300, // Milliseconds 58 easingAfterHotSpotScrollingFunction: "easeOutQuart", // String 59 60 // Mousewheel scrolling 61 mousewheelScrolling: "", // vertical, horizontal, allDirections or empty (no mousewheel scrolling) String 62 mousewheelScrollingStep: 70, // Pixels 63 easingAfterMouseWheelScrolling: true, // Boolean 64 easingAfterMouseWheelScrollingDuration: 300, // Milliseconds 65 easingAfterMouseWheelScrollingFunction: "easeOutQuart", // String 66 67 // Manual scrolling (hotspot and/or mousewheel scrolling) 68 manualContinuousScrolling: false, // Boolean 69 70 // Autoscrolling 71 autoScrollingMode: "", // always, onStart or empty (no auto scrolling) String 72 autoScrollingDirection: "endlessLoopRight", // right, left, backAndForth, endlessLoopRight, endlessLoopLeft String 73 autoScrollingStep: 1, // Pixels 74 autoScrollingInterval: 10, // Milliseconds 75 76 // Touch scrolling 77 touchScrolling: false, 78 79 // Easing for when the scrollToElement method is used 80 scrollToAnimationDuration: 1000, // Milliseconds 81 scrollToEasingFunction: "easeOutQuart" // String 82 }, 83 _create: function() { 84 var self = this, 85 o = this.options, 86 el = this.element; 87 88 // Create variables for any existing or not existing 89 // scroller elements on the page. 90 el.data("scrollWrapper", el.find("." + o.scrollWrapperClass)); 91 el.data("scrollingHotSpotRight", el.find("." + o.scrollingHotSpotRightClass)); 92 el.data("scrollingHotSpotLeft", el.find("." + o.scrollingHotSpotLeftClass)); 93 el.data("scrollableArea", el.find("." + o.scrollableAreaClass)); 94 95 // Check which elements are already present on the page. 96 // Create any elements needed by the plugin if 97 // the user hasn't already created them. 98 99 // First detach any present hot spots 100 if (el.data("scrollingHotSpotRight").length > 0) { 101 102 el.data("scrollingHotSpotRight").detach(); 103 } 104 if (el.data("scrollingHotSpotLeft").length > 0) { 105 106 el.data("scrollingHotSpotLeft").detach(); 107 } 108 109 // Both the scrollable area and the wrapper are missing 110 if (el.data("scrollableArea").length === 0 && el.data("scrollWrapper").length === 0) { 111 el.wrapInner("<div class='" + o.scrollableAreaClass + "'>").wrapInner("<div class='" + o.scrollWrapperClass + "'>"); 112 113 el.data("scrollWrapper", el.find("." + o.scrollWrapperClass)); 114 el.data("scrollableArea", el.find("." + o.scrollableAreaClass)); 115 } 116 // Only the wrapper is missing 117 else if (el.data("scrollWrapper").length === 0) { 118 el.wrapInner("<div class='" + o.scrollWrapperClass + "'>"); 119 el.data("scrollWrapper", el.find("." + o.scrollWrapperClass)); 120 } 121 // Only the scrollable area is missing 122 else if (el.data("scrollableArea").length === 0) { 123 el.data("scrollWrapper").wrapInner("<div class='" + o.scrollableAreaClass + "'>"); 124 el.data("scrollableArea", el.find("." + o.scrollableAreaClass)); 125 } 126 127 // Put the right and left hot spot back into the scroller again 128 // or create them if they where not present from the beginning. 129 if (el.data("scrollingHotSpotRight").length === 0) { 130 el.prepend("<div class='" + o.scrollingHotSpotRightClass + "'></div>"); 131 el.data("scrollingHotSpotRight", el.find("." + o.scrollingHotSpotRightClass)); 132 } else { 133 el.prepend(el.data("scrollingHotSpotRight")); 134 } 135 136 if (el.data("scrollingHotSpotLeft").length === 0) { 137 el.prepend("<div class='" + o.scrollingHotSpotLeftClass + "'></div>"); 138 el.data("scrollingHotSpotLeft", el.find("." + o.scrollingHotSpotLeftClass)); 139 } else { 140 el.prepend(el.data("scrollingHotSpotLeft")); 141 } 142 143 // Create variables in the element data storage 144 el.data("speedBooster", 1); 145 el.data("scrollXPos", 0); 146 el.data("hotSpotWidth", '300'); 147 el.data("scrollableAreaWidth", 0); 148 el.data("startingPosition", 0); 149 el.data("rightScrollingInterval", null); 150 el.data("leftScrollingInterval", null); 151 el.data("autoScrollingInterval", null);
152 el.data("hideHotSpotBackgroundsInterval", null); 153 el.data("previousScrollLeft", 0); 154 el.data("pingPongDirection", "right"); 155 el.data("getNextElementWidth", true); 156 el.data("swapAt", null); 157 el.data("startAtElementHasNotPassed", true); 158 el.data("swappedElement", null); 159 el.data("originalElements", el.data("scrollableArea").children(o.countOnlyClass)); 160 el.data("visible", true); 161 el.data("enabled", true); 162 el.data("scrollableAreaHeight", el.data("scrollableArea").height()); 163 el.data("scrollerOffset", el.offset()); 164 165 /***************************************** 166 SET UP EVENTS FOR TOUCH SCROLLING 167 *****************************************/ 168 if (o.touchScrolling && el.data("enabled")) { 169 // Use jquery.kinetic.js for touch scrolling 170 // Vertical scrolling disabled 171 el.data("scrollWrapper").kinetic({ 172 y: false, 173 moved: function(settings) { 174 if (o.manualContinuousScrolling) { 175 if (el.data("scrollWrapper").scrollLeft() <= 0) { 176 self._checkContinuousSwapLeft(); 177 } else { 178 self._checkContinuousSwapRight(); 179 } 180 } 181 182 // Callback 183 self._trigger("touchMoved"); 184 }, 185 stopped: function(settings) { 186 // Stop any ongoing animations 187 el.data("scrollWrapper").stop(true, false); 188 189 // Stop any ongoing auto scrolling 190 self.stopAutoScrolling(); 191 192 // Callback 193 self._trigger("touchStopped"); 194 } 195 }); 196 } 197 198 /***************************************** 199 SET UP EVENTS FOR SCROLLING RIGHT 200 *****************************************/ 201 // Check the mouse X position and calculate 202 // the relative X position inside the right hotspot 203 el.data("scrollingHotSpotRight").bind("mousemove", function(e) { 204 if (o.hotSpotScrolling) { 205 //var x = e.pageX - $(this).offset().left; 206 var x = 1; 207 el.data("scrollXPos", Math.round((x / el.data("hotSpotWidth")) * o.hotSpotScrollingStep)); 208 209 // If the position is less then 1, it's set to 1 210 if (el.data("scrollXPos") === Infinity || el.data("scrollXPos") < 1) { 211 el.data("scrollXPos", 1); 212 } 213 } 214 }); 215 216 // Mouseover right hotspot - scrolling 217 el.data("scrollingHotSpotRight").bind("mouseover", function() { 218 if (o.hotSpotScrolling) { 219 // Stop any ongoing animations 220 el.data("scrollWrapper").stop(true, false); 221 222 // Stop any ongoing auto scrolling 223 self.stopAutoScrolling(); 224 225 // Start the scrolling interval 226 el.data("rightScrollingInterval", setInterval(function() { 227 if (el.data("scrollXPos") > 0 && el.data("enabled")) { 228 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + (el.data("scrollXPos") * el.data("speedBooster"))); 229 230 if (o.manualContinuousScrolling) { 231 self._checkContinuousSwapRight(); 232 } 233 234 self._showHideHotSpots(); 235 } 236 }, o.hotSpotScrollingInterval)); 237 238 // Callback 239 self._trigger("mouseOverRightHotSpot"); 240 } 241 }); 242 243 // Mouseout right hotspot - stop scrolling 244 el.data("scrollingHotSpotRight").bind("mouseout", function() { 245 if (o.hotSpotScrolling) { 246 clearInterval(el.data("rightScrollingInterval")); 247 el.data("scrollXPos", 0); 248 249 // Easing out after scrolling 250 if (o.easingAfterHotSpotScrolling && el.data("enabled")) { 251 el.data("scrollWrapper").animate({ 252 scrollLeft: el.data("scrollWrapper").scrollLeft() + o.easingAfterHotSpotScrollingDistance 253 }, { 254 duration: o.easingAfterHotSpotScrollingDuration, 255 easing: o.easingAfterHotSpotScrollingFunction 256 }); 257 } 258 } 259 }); 260
261 // mousedown right hotspot (add scrolling speed booster) 262 el.data("scrollingHotSpotRight").bind("mousedown", function() { 263 el.data("speedBooster", o.hotSpotMouseDownSpeedBooster); 264 }); 265 266 // mouseup anywhere (stop boosting the scrolling speed) 267 $("body").bind("mouseup", function() { 268 el.data("speedBooster", 1); 269 }); 270 271 /***************************************** 272 SET UP EVENTS FOR SCROLLING LEFT 273 *****************************************/ 274 // Check the mouse X position and calculate 275 // the relative X position inside the left hotspot 276 el.data("scrollingHotSpotLeft").bind("mousemove", function(e) { 277 if (o.hotSpotScrolling) { 278 //var x = el.data("hotSpotWidth") - (e.pageX - $(this).offset().left); 279 var x = 1; 280 281 el.data("scrollXPos", Math.round((x / el.data("hotSpotWidth")) * o.hotSpotScrollingStep)); 282 // If the position is less then 1, it's set to 1 283 if (el.data("scrollXPos") === Infinity || el.data("scrollXPos") < 1) { 284 el.data("scrollXPos", 1); 285 } 286 } 287 }); 288 289 // Mouseover left hotspot 290 el.data("scrollingHotSpotLeft").bind("mouseover", function() { 291 if (o.hotSpotScrolling) { 292 // Stop any ongoing animations 293 el.data("scrollWrapper").stop(true, false); 294 295 // Stop any ongoing auto scrolling 296 self.stopAutoScrolling(); 297 298 el.data("leftScrollingInterval", setInterval(function() { 299 if (el.data("scrollXPos") > 0 && el.data("enabled")) { 300 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - (el.data("scrollXPos") * el.data("speedBooster"))); 301 302 if (o.manualContinuousScrolling) { 303 self._checkContinuousSwapLeft(); 304 } 305 306 self._showHideHotSpots(); 307 } 308 }, o.hotSpotScrollingInterval)); 309 310 // Callback 311 self._trigger("mouseOverLeftHotSpot"); 312 } 313 }); 314 315 // mouseout left hotspot 316 el.data("scrollingHotSpotLeft").bind("mouseout", function() { 317 if (o.hotSpotScrolling) { 318 clearInterval(el.data("leftScrollingInterval")); 319 el.data("scrollXPos", 0); 320 321 // Easing out after scrolling 322 if (o.easingAfterHotSpotScrolling && el.data("enabled")) { 323 el.data("scrollWrapper").animate({ 324 scrollLeft: el.data("scrollWrapper").scrollLeft() - o.easingAfterHotSpotScrollingDistance 325 }, { 326 duration: o.easingAfterHotSpotScrollingDuration, 327 easing: o.easingAfterHotSpotScrollingFunction 328 }); 329 } 330 } 331 }); 332 333 // mousedown left hotspot (add scrolling speed booster) 334 el.data("scrollingHotSpotLeft").bind("mousedown", function() { 335 el.data("speedBooster", o.hotSpotMouseDownSpeedBooster); 336 }); 337 338 /***************************************** 339 SET UP EVENT FOR MOUSEWHEEL SCROLLING 340 *****************************************/ 341 el.data("scrollableArea").mousewheel(function(event, delta, deltaX, deltaY) { 342 343 if (el.data("enabled") && o.mousewheelScrolling.length > 0) { 344 var pixels; 345 346 // Can be either positive or negative 347 // Is multiplied/inverted by minus one since you want it to scroll 348 // left when moving the wheel down/right and right when moving the wheel up/left 349 if (o.mousewheelScrolling === "vertical" && deltaY !== 0) { 350 // Stop any ongoing auto scrolling if it's running 351 self.stopAutoScrolling(); 352 event.preventDefault(); 353 pixels = Math.round((o.mousewheelScrollingStep * deltaY) * -1); 354 self.move(pixels); 355 } else if (o.mousewheelScrolling === "horizontal" && deltaX !== 0) { 356 // Stop any ongoing auto scrolling if it's running 357 self.stopAutoScrolling(); 358 event.preventDefault(); 359 pixels = Math.round((o.mousewheelScrollingStep * deltaX) * -1); 360 self.move(pixels); 361 } else if (o.mousewheelScrolling === "allDirections") { 362 // Stop any ongoing auto scrolling if it's running 363 self.stopAutoScrolling(); 364 event.preventDefault(); 365 pixels = Math.round((o.mousewheelScrollingStep * delta) * -1); 366 self.move(pixels); 367 } 368 369 } 370 }); 371 372 // Capture and disable mousewheel events when the pointer 373 // is over any of the hotspots 374 if (o.mousewheelScrolling) { 375 el.data("scrollingHotSpotLeft").add(el.data("scrollingHotSpotRight")).mousewheel(function(event) { 376 event.preventDefault(); 377 }); 378 } 379 380 /*****************************************
381 SET UP EVENT FOR RESIZING THE BROWSER WINDOW 382 *****************************************/ 383 $(window).bind("resize", function() { 384 self._showHideHotSpots(); 385 self._trigger("windowResized"); 386 }); 387 388 /***************************************** 389 FETCHING CONTENT ON INITIALIZATION 390 *****************************************/ 391 // If getContentOnLoad is present in the options, 392 // sort out the method and parameters and get the content 393 394 if (!(jQuery.isEmptyObject(o.getContentOnLoad))) { 395 self[o.getContentOnLoad.method](o.getContentOnLoad.content, o.getContentOnLoad.manipulationMethod, o.getContentOnLoad.addWhere, o.getContentOnLoad.filterTag); 396 } 397 398 // Should it be hidden on start? 399 if (o.hiddenOnStart) { 400 self.hide(); 401 } 402 403 /***************************************** 404 AUTOSCROLLING 405 *****************************************/ 406 // The $(window).load event handler is used because the width of the elements are not calculated 407 // properly until then, at least not in Google Chrome. The start of the auto scrolling and the 408 // setting of the hotspot backgrounds is started here as well for the same reason. 409 // If the auto scrolling is not started in $(window).load, it won't start because it 410 // will interpret the scrollable areas as too short. 411 $(window).load(function() { 412 413 // If scroller is not hidden, recalculate the scrollable area 414 if (!(o.hiddenOnStart)) { 415 self.recalculateScrollableArea(); 416 } 417 418 // Autoscrolling is active 419 if ((o.autoScrollingMode.length > 0) && !(o.hiddenOnStart)) { 420 self.startAutoScrolling(); 421 } 422 423 // If the user wants to have visible hotspot backgrounds, 424 // here is where it's taken care of 425 if (o.autoScrollingMode !== "always") { 426 427 switch (o.visibleHotSpotBackgrounds) { 428 case "always": 429 self.showHotSpotBackgrounds(); 430 break; 431 case "onStart": 432 self.showHotSpotBackgrounds(); 433 el.data("hideHotSpotBackgroundsInterval", setTimeout(function() { 434 self.hideHotSpotBackgrounds(250); 435 }, o.hotSpotsVisibleTime)); 436 break; 437 case "hover": 438 el.mouseenter(function(event) { 439 if (o.hotSpotScrolling) { 440 event.stopPropagation(); 441 self.showHotSpotBackgrounds(250); 442 } 443 }).mouseleave(function(event) { 444 if (o.hotSpotScrolling) { 445 event.stopPropagation(); 446 self.hideHotSpotBackgrounds(250); 447 } 448 }); 449 break; 450 default: 451 break; 452 } 453 } 454 455 self._showHideHotSpots(); 456 457 self._trigger("setupComplete"); 458 459 }); 460 461 }, 462 /********************************************************** 463 _init 464 **********************************************************/ 465 // When the contents of the scrollable area is changed outside the widget, 466 // the widget must be reinitilaized. 467 // This code is run every time the widget is called without arguments 468 _init: function() { 469 var self = this, 470 el = this.element; 471 472 // Recalculate the total width of the elements inside the scrollable area 473 self.recalculateScrollableArea(); 474 475 // Determine which hotspots to show 476 self._showHideHotSpots(); 477 478 // Trigger callback 479 self._trigger("initializationComplete"); 480 }, 481 /********************************************************** 482 Override _setOption and handle altered options 483 **********************************************************/ 484 _setOption: function(key, value) { 485 var self = this, 486 o = this.options, 487 el = this.element; 488 489 // Update option 490 o[key] = value; 491 492 if (key === "hotSpotScrolling") { 493 // Handler if the option hotSpotScrolling is altered 494 if (value === true) { 495 self._showHideHotSpots(); 496 } else { 497 el.data("scrollingHotSpotLeft").hide(); 498 el.data("scrollingHotSpotRight").hide(); 499 } 500 } else if (key === "autoScrollingStep" || 501 // Make sure that certain values are integers, otherwise 502 // they will summon bad spirits in the plugin 503 key === "easingAfterHotSpotScrollingDistance" || 504 key === "easingAfterHotSpotScrollingDuration" || 505 key === "easingAfterMouseWheelScrollingDuration") { 506 o[key] = parseInt(value, 10); 507 } else if (key === "autoScrollingInterval") { 508 // Handler if the autoScrollingInterval is altered 509 o[key] = parseInt(value, 10); 510 self.startAutoScrolling(); 511 } 512 513 }, 514 /********************************************************** 515 Hotspot functions 516 **********************************************************/
517 showHotSpotBackgrounds: function(fadeSpeed) { 518 519 // Alter the CSS (SmoothDivScroll.css) if you want to customize 520 // the look'n'feel of the visible hotspots 521 var self = this, 522 el = this.element, 523 o = this.options; 524 525 // Fade in the hotspot backgrounds 526 if (fadeSpeed !== undefined) { 527 // Before the fade-in starts, we need to make sure the opacity is zero 528 //el.data("scrollingHotSpotLeft").add(el.data("scrollingHotSpotRight")).css("opacity", "0.0"); 529 530 el.data("scrollingHotSpotLeft").addClass(o.scrollingHotSpotLeftVisibleClass); 531 el.data("scrollingHotSpotRight").addClass(o.scrollingHotSpotRightVisibleClass); 532 533 // Fade in the hotspots 534 el.data("scrollingHotSpotLeft").add(el.data("scrollingHotSpotRight")).fadeTo(fadeSpeed, 0.35); 535 } 536 // Don't fade, just show them 537 else { 538 539 // The left hotspot 540 el.data("scrollingHotSpotLeft").addClass(o.scrollingHotSpotLeftVisibleClass); 541 el.data("scrollingHotSpotLeft").removeAttr("style"); 542 543 // The right hotspot 544 el.data("scrollingHotSpotRight").addClass(o.scrollingHotSpotRightVisibleClass); 545 el.data("scrollingHotSpotRight").removeAttr("style"); 546 } 547 548 self._showHideHotSpots(); 549 550 }, 551 hideHotSpotBackgrounds: function(fadeSpeed) { 552 var el = this.element, 553 o = this.options; 554 555 // Fade out the hotspot backgrounds 556 if (fadeSpeed !== undefined) { 557 558 // Fade out the left hotspot 559 el.data("scrollingHotSpotLeft").fadeTo(fadeSpeed, 0.0, function() { 560 el.data("scrollingHotSpotLeft").removeClass(o.scrollingHotSpotLeftVisibleClass); 561 }); 562 563 // Fade out the right hotspot 564 el.data("scrollingHotSpotRight").fadeTo(fadeSpeed, 0.0, function() { 565 el.data("scrollingHotSpotRight").removeClass(o.scrollingHotSpotRightVisibleClass); 566 }); 567 568 } 569 // Don't fade, just hide them 570 else { 571 el.data("scrollingHotSpotLeft").removeClass(o.scrollingHotSpotLeftVisibleClass).removeAttr("style"); 572 el.data("scrollingHotSpotRight").removeClass(o.scrollingHotSpotRightVisibleClass).removeAttr("style"); 573 } 574 575 }, 576 // Function for showing and hiding hotspots depending on the 577 // offset of the scrolling 578 _showHideHotSpots: function() { 579 var self = this, 580 el = this.element, 581 o = this.options; 582 583 // Hot spot scrolling is not enabled so show no hot spots 584 if (!(o.hotSpotScrolling)) { 585 el.data("scrollingHotSpotLeft").hide(); 586 el.data("scrollingHotSpotRight").hide(); 587 } else { 588 589 // If the manual continuous scrolling option is set show both 590 if (o.hotSpotScrolling && o.autoScrollingMode !== "always" && el.data("autoScrollingInterval") !== null) { 591 el.data("scrollingHotSpotLeft").show(); 592 el.data("scrollingHotSpotRight").show(); 593 } 594 // Autoscrolling not set to always and hotspot scrolling enabled. 595 // Regular hot spot scrolling. 596 else if (o.autoScrollingMode !== "always" && o.hotSpotScrolling) { 597 // If the scrollable area is shorter than the scroll wrapper, both hotspots 598 // should be hidden 599 if (el.data("scrollableAreaWidth") <= (el.data("scrollWrapper").innerWidth())) { 600 el.data("scrollingHotSpotLeft").hide(); 601 el.data("scrollingHotSpotRight").hide(); 602 } 603 // When you can't scroll further left the left scroll hotspot should be hidden 604 // and the right hotspot visible. 605 else if (el.data("scrollWrapper").scrollLeft() === 0) { 606 el.data("scrollingHotSpotLeft").hide(); 607 el.data("scrollingHotSpotRight").show(); 608 // Callback 609 self._trigger("scrollerLeftLimitReached"); 610 // Clear interval 611 clearInterval(el.data("leftScrollingInterval")); 612 el.data("leftScrollingInterval", null); 613 } 614 // When you can't scroll further right 615 // the right scroll hotspot should be hidden 616 // and the left hotspot visible 617 else if (el.data("scrollableAreaWidth") <= (el.data("scrollWrapper").innerWidth() + el.data("scrollWrapper").scrollLeft())) { 618 el.data("scrollingHotSpotLeft").show(); 619 el.data("scrollingHotSpotRight").hide(); 620 // Callback 621 self._trigger("scrollerRightLimitReached"); 622 // Clear interval 623 clearInterval(el.data("rightScrollingInterval")); 624 el.data("rightScrollingInterval", null); 625 } 626 // If you are somewhere in the middle of your 627 // scrolling, both hotspots should be visible 628 else { 629 el.data("scrollingHotSpotLeft").show(); 630 el.data("scrollingHotSpotRight").show(); 631 } 632 } 633 // If auto scrolling is set to always, there should be no hotspots 634 else { 635 el.data("scrollingHotSpotLeft").hide(); 636 el.data("scrollingHotSpotRight").hide(); 637 } 638 } 639 640 }, 641 // Function for calculating the scroll position of a certain element 642 _setElementScrollPosition: function(method, element) { 643 var el = this.element, 644 o = this.options, 645 tempScrollPosition = 0; 646 647 switch (method) { 648 case "first": 649 el.data("scrollXPos", 0); 650 return true; 651 case "start": 652 // Check to see if there is a specified start element in the options 653 // and that the element exists in the DOM 654 if (o.startAtElementId !== "") { 655 if (el.data("scrollableArea").has("#" + o.startAtElementId)) { 656 tempScrollPosition = $("#" + o.startAtElementId).position().left; 657 el.data("scrollXPos", tempScrollPosition); 658 return true; 659 } 660 } 661 return false;
662 case "last": 663 el.data("scrollXPos", (el.data("scrollableAreaWidth") - el.data("scrollWrapper").innerWidth())); 664 return true; 665 case "number": 666 // Check to see that an element number is passed 667 if (!(isNaN(element))) { 668 tempScrollPosition = el.data("scrollableArea").children(o.countOnlyClass).eq(element - 1).position().left; 669 el.data("scrollXPos", tempScrollPosition); 670 return true; 671 } 672 return false; 673 case "id": 674 // Check that an element id is passed and that the element exists in the DOM 675 if (element.length > 0) { 676 if (el.data("scrollableArea").has("#" + element)) { 677 tempScrollPosition = $("#" + element).position().left; 678 el.data("scrollXPos", tempScrollPosition); 679 return true; 680 } 681 } 682 return false; 683 default: 684 return false; 685 } 686 687 }, 688 /********************************************************** 689 Jumping to a certain element 690 **********************************************************/ 691 jumpToElement: function(jumpTo, element) { 692 var self = this, 693 el = this.element; 694 695 // Check to see that the scroller is enabled 696 if (el.data("enabled")) { 697 // Get the position of the element to scroll to 698 if (self._setElementScrollPosition(jumpTo, element)) { 699 // Jump to the element 700 el.data("scrollWrapper").scrollLeft(el.data("scrollXPos")); 701 // Check the hotspots 702 self._showHideHotSpots(); 703 // Trigger the right callback 704 switch (jumpTo) { 705 case "first": 706 self._trigger("jumpedToFirstElement"); 707 break; 708 case "start": 709 self._trigger("jumpedToStartElement"); 710 break; 711 case "last": 712 self._trigger("jumpedToLastElement"); 713 break; 714 case "number": 715 self._trigger("jumpedToElementNumber", null, { 716 "elementNumber": element 717 }); 718 break; 719 case "id": 720 self._trigger("jumpedToElementId", null, { 721 "elementId": element 722 }); 723 break; 724 default: 725 break; 726 } 727 728 } 729 } 730 }, 731 /********************************************************** 732 Scrolling to a certain element 733 **********************************************************/ 734 scrollToElement: function(scrollTo, element) { 735 var self = this, 736 el = this.element, 737 o = this.options, 738 autoscrollingWasRunning = false; 739 740 if (el.data("enabled")) { 741 // Get the position of the element to scroll to 742 if (self._setElementScrollPosition(scrollTo, element)) { 743 // Stop any ongoing auto scrolling 744 if (el.data("autoScrollingInterval") !== null) { 745 self.stopAutoScrolling(); 746 autoscrollingWasRunning = true; 747 } 748 749 // Stop any other running animations 750 // (clear queue but don't jump to the end) 751 el.data("scrollWrapper").stop(true, false); 752 753 // Do the scolling animation 754 el.data("scrollWrapper").animate({ 755 scrollLeft: el.data("scrollXPos") 756 }, { 757 duration: o.scrollToAnimationDuration, 758 easing: o.scrollToEasingFunction, 759 complete: function() { 760 // If auto scrolling was running before, start it again 761 if (autoscrollingWasRunning) { 762 self.startAutoScrolling(); 763 } 764 765 self._showHideHotSpots(); 766 767 // Trigger the right callback 768 switch (scrollTo) { 769 case "first": 770 self._trigger("scrolledToFirstElement"); 771 break; 772 case "start": 773 self._trigger("scrolledToStartElement"); 774 break; 775 case "last": 776 self._trigger("scrolledToLastElement"); 777 break; 778 case "number": 779 self._trigger("scrolledToElementNumber", null, { 780 "elementNumber": element 781 }); 782 break; 783 case "id": 784 self._trigger("scrolledToElementId", null, { 785 "elementId": element 786 }); 787 break; 788 default: 789 break; 790 } 791 } 792 }); 793 } 794 } 795 796 }, 797 move: function(pixels) { 798 var self = this, 799 el = this.element, 800 o = this.options; 801 // clear queue, move to end 802 el.data("scrollWrapper").stop(true, true); 803 804 // Only run this code if it's possible to scroll left or right, 805 if ((pixels < 0 && el.data("scrollWrapper").scrollLeft() > 0) || (pixels > 0 && el.data("scrollableAreaWidth") > (el.data("scrollWrapper").innerWidth() + el.data("scrollWrapper").scrollLeft())) || o.manualContinuousScrolling) { 806 807 var scrollLength = el.data("scrollableArea").width() - el.data("scrollWrapper").width(); 808 var sOffset = el.data("scrollWrapper").scrollLeft() + pixels; 809 810 if (sOffset < 0) { // Swap last element to be the first one if scroll out of the left edge of view 811 812 var forceSwapElementLeft = function() { 813 el.data("swappedElement", el.data("scrollableArea").children(":last").detach()); 814 el.data("scrollableArea").prepend(el.data("swappedElement")); 815 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + el.data("swappedElement").outerWidth(true)); 816 }; 817 818 while (sOffset < 0) { // keep swap elements left until it has enough length for scrolling left 819 forceSwapElementLeft(); 820 sOffset = el.data("scrollableArea").children(":first").outerWidth(true) + sOffset; 821 } 822 823 } else if (sOffset - scrollLength > 0) { // Swap the first element to be the last one if scroll out of the right edge of view 824 825 var forceSwapElementRight = function() { 826 el.data("swappedElement", el.data("scrollableArea").children(":first").detach()); 827 el.data("scrollableArea").append(el.data("swappedElement")); 828 var wrapperLeft = el.data("scrollWrapper").scrollLeft(); 829 el.data("scrollWrapper").scrollLeft(wrapperLeft - el.data("swappedElement").outerWidth(true)); 830 }; 831 832 while (sOffset - scrollLength > 0) { // keep swap elements right until it has enough length for scrolling right 833 forceSwapElementRight(); 834 sOffset = sOffset - el.data("scrollableArea").children(":last").outerWidth(true); 835 } 836 837 } 838 839 if (o.easingAfterMouseWheelScrolling) { 840 841 el.data("scrollWrapper").animate({ 842 scrollLeft: el.data("scrollWrapper").scrollLeft() + pixels 843 }, { 844 duration: o.easingAfterMouseWheelScrollingDuration, 845 easing: o.easingAfterMouseWheelFunction, 846 complete: function() { 847 self._showHideHotSpots(); 848 if (o.manualContinuousScrolling) { 849 if (pixels > 0) { 850 self._checkContinuousSwapRight(); 851 } else { 852 self._checkContinuousSwapLeft(); 853 } 854 } 855 } 856 }); 857 858 } else { 859 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + pixels); 860 self._showHideHotSpots(); 861 862 if (o.manualContinuousScrolling) { 863 if (pixels > 0) { 864 self._checkContinuousSwapRight(); 865 } else { 866 self._checkContinuousSwapLeft(); 867 } 868 } 869 } 870 871 } 872 873 }, 874 /********************************************************** 875 Adding or replacing content 876 **********************************************************/ 877 /* Arguments are: 878 content - a valid URL to a Flickr feed - string 879 manipulationMethod - addFirst, addLast or replace (default) - string 880 */ 881 getFlickrContent: function(content, manipulationMethod) { 882 var self = this, 883 el = this.element; 884 885 $.getJSON(content, function(data) { 886 // small square - size is 75x75 887 // thumbnail -> large - size is the longest side 888 var flickrImageSizes = [{ 889 size: "small square", 890 pixels: 75, 891 letter: "_s" 892 }, { 893 size: "thumbnail", 894 pixels: 100, 895 letter: "_t" 896 }, { 897 size: "small", 898 pixels: 240, 899 letter: "_m" 900 }, { 901 size: "medium", 902 pixels: 500, 903 letter: "" 904 }, { 905 size: "medium 640", 906 pixels: 640, 907 letter: "_z" 908 }, { 909 size: "large", 910 pixels: 1024, 911 letter: "_b" 912 }]; 913 var loadedFlickrImages = []; 914 var imageIdStringBuffer = []; 915 var startingIndex;
916 var numberOfFlickrItems = data.items.length; 917 var loadedFlickrImagesCounter = 0; 918 919 // Determine a plausible starting value for the 920 // image height 921 if (el.data("scrollableAreaHeight") <= 75) { 922 startingIndex = 0; 923 } else if (el.data("scrollableAreaHeight") <= 100) { 924 startingIndex = 1; 925 } else if (el.data("scrollableAreaHeight") <= 240) { 926 startingIndex = 2; 927 } else if (el.data("scrollableAreaHeight") <= 500) { 928 startingIndex = 3; 929 } else if (el.data("scrollableAreaHeight") <= 640) { 930 startingIndex = 4; 931 } else { 932 startingIndex = 5; 933 } 934 935 // Put all items from the feed in an array. 936 // This is necessary 937 $.each(data.items, function(index, item) { 938 loadFlickrImage(item, startingIndex); 939 }); 940 941 function loadFlickrImage(item, sizeIndex) { 942 var path = item.media.m; 943 var imgSrc = path.replace("_m", flickrImageSizes[sizeIndex].letter); 944 var tempImg = $("<img />").attr("src", imgSrc); 945 946 tempImg.load(function() { 947 // Is it still smaller? Load next size 948 if (this.height < el.data("scrollableAreaHeight")) { 949 // Load a bigger image, if possible 950 if ((sizeIndex + 1) < flickrImageSizes.length) { 951 loadFlickrImage(item, sizeIndex + 1); 952 } else { 953 addImageToLoadedImages(this); 954 } 955 } else { 956 addImageToLoadedImages(this); 957 } 958 959 // Finishing stuff to do when all images have been loaded 960 if (loadedFlickrImagesCounter === numberOfFlickrItems) { 961 switch (manipulationMethod) { 962 case "addFirst": 963 // Add the loaded content first in the scrollable area 964 el.data("scrollableArea").children(":first").before(loadedFlickrImages); 965 break; 966 case "addLast": 967 // Add the loaded content last in the scrollable area 968 el.data("scrollableArea").children(":last").after(loadedFlickrImages); 969 break; 970 default: 971 // Replace the content in the scrollable area 972 el.data("scrollableArea").html(loadedFlickrImages); 973 break; 974 } 975 976 // Recalculate the total width of the elements inside the scrollable area 977 self.recalculateScrollableArea(); 978 979 // Determine which hotspots to show 980 self._showHideHotSpots(); 981 982 // Trigger callback 983 self._trigger("addedFlickrContent", null, { 984 "addedElementIds": imageIdStringBuffer 985 }); 986 } 987 988 }); 989 } 990 991 // Add the loaded content first or last in the scrollable area 992 function addImageToLoadedImages(imageObj) { 993 // Calculate the scaled width 994 var widthScalingFactor = el.data("scrollableAreaHeight") / imageObj.height; 995 var tempWidth = Math.round(imageObj.width * widthScalingFactor); 996 // Set an id for the image - the filename is used as an id 997 var tempIdArr = $(imageObj).attr("src").split("/"); 998 var lastElemIndex = (tempIdArr.length - 1); 999 tempIdArr = tempIdArr[lastElemIndex].split("."); 1000 $(imageObj).attr("id", tempIdArr[0]); 1001 // Set the height of the image to the height of the scrollable area and add the width 1002 $(imageObj).css({ 1003 "height": el.data("scrollableAreaHeight"), 1004 "width": tempWidth 1005 }); 1006 // Add the id of the image to the array of id's - this 1007 // is used as a parameter when the callback is triggered 1008 imageIdStringBuffer.push(tempIdArr[0]); 1009 // Add the image to the array of loaded images 1010 loadedFlickrImages.push(imageObj); 1011 1012 // Increment counter for loaded images 1013 loadedFlickrImagesCounter++; 1014 } 1015 1016 }); 1017 }, 1018 /* Arguments are: 1019 content - a valid URL to an AJAX content source - string 1020 manipulationMethod - addFirst, addLast or replace (default) - string 1021 filterTag - a jQuery selector that matches the elements from the AJAX content 1022 source that you want, for example ".myClass" or "#thisDiv" or "div" - string 1023 */ 1024 getAjaxContent: function(content, manipulationMethod, filterTag) { 1025 var self = this, 1026 el = this.element; 1027 $.ajaxSetup({ 1028 cache: false 1029 }); 1030 1031 $.get(content, function(data) { 1032 var filteredContent; 1033 1034 if (filterTag !== undefined) { 1035 if (filterTag.length > 0) { 1036 // A bit of a hack since I can't know if the element 1037 // that the user wants is a direct child of body (= use filter) 1038 // or other types of elements (= use find) 1039 filteredContent = $("<div>").html(data).find(filterTag); 1040 } else { 1041 filteredContent = content; 1042 } 1043 } else { 1044 filteredContent = data; 1045 } 1046 1047 switch (manipulationMethod) { 1048 case "addFirst": 1049 // Add the loaded content first in the scrollable area 1050 el.data("scrollableArea").children(":first").before(filteredContent); 1051 break; 1052 case "addLast": 1053 // Add the loaded content last in the scrollable area 1054 el.data("scrollableArea").children(":last").after(filteredContent); 1055 break; 1056 default: 1057 // Replace the content in the scrollable area 1058 el.data("scrollableArea").html(filteredContent); 1059 break; 1060 } 1061 1062 // Recalculate the total width of the elements inside the scrollable area 1063 self.recalculateScrollableArea(); 1064 1065 // Determine which hotspots to show 1066 self._showHideHotSpots(); 1067 1068 // Trigger callback 1069 self._trigger("addedAjaxContent"); 1070 1071 }); 1072 }, 1073 getHtmlContent: function(content, manipulationMethod, filterTag) { 1074 var self = this, 1075 el = this.element; 1076 1077 // No AJAX involved at all - just add raw HTML-content 1078 /* Arguments are: 1079 content - any raw HTML that you want - string 1080 manipulationMethod - addFirst, addLast or replace (default) - string 1081 filterTag - a jQuery selector that matches the elements from the AJAX content 1082 source that you want, for example ".myClass" or "#thisDiv" or "div" - string 1083 */ 1084 var filteredContent; 1085 if (filterTag !== undefined) { 1086 if (filterTag.length > 0) { 1087 // A bit of a hack since I can't know if the element 1088 // that the user wants is a direct child of body (= use filter) 1089 // or other types of elements (= use find) 1090 filteredContent = $("<div>").html(content).find(filterTag); 1091 } else { 1092 filteredContent = content; 1093 } 1094 } else { 1095 filteredContent = content; 1096 } 1097 1098 switch (manipulationMethod) { 1099 case "addFirst": 1100 // Add the loaded content first in the scrollable area 1101 el.data("scrollableArea").children(":first").before(filteredContent); 1102 break; 1103 case "addLast": 1104 // Add the loaded content last in the scrollable area 1105 el.data("scrollableArea").children(":last").after(filteredContent); 1106 break; 1107 default: 1108 // Replace the content in the scrollable area 1109 el.data("scrollableArea").html(filteredContent); 1110 break; 1111 } 1112 1113 // Recalculate the total width of the elements inside the scrollable area 1114 self.recalculateScrollableArea(); 1115 1116 // Determine which hotspots to show 1117 self._showHideHotSpots(); 1118 1119 // Trigger callback 1120 self._trigger("addedHtmlContent"); 1121 1122 }, 1123 /********************************************************** 1124 Recalculate the scrollable area 1125 **********************************************************/ 1126 recalculateScrollableArea: function() { 1127 1128 var tempScrollableAreaWidth = 0, 1129 foundStartAtElement = false, 1130 o = this.options, 1131 el = this.element; 1132 1133 // Add up the total width of all the items inside the scrollable area 1134 el.data("scrollableArea").children(o.countOnlyClass).each(function() { 1135 // Check to see if the current element in the loop is the one where the scrolling should start 1136 if ((o.startAtElementId.length > 0) && (($(this).attr("id")) === o.startAtElementId)) { 1137 el.data("startingPosition", tempScrollableAreaWidth); 1138 foundStartAtElement = true; 1139 } 1140 tempScrollableAreaWidth = tempScrollableAreaWidth + $(this).outerWidth(true); 1141 1142 }); 1143 1144 // If the element with the ID specified by startAtElementId 1145 // is not found, reset it 1146 if (!(foundStartAtElement)) { 1147 el.data("startAtElementId", ""); 1148 } 1149 1150 // Set the width of the scrollable area 1151 el.data("scrollableAreaWidth", tempScrollableAreaWidth); 1152 el.data("scrollableArea").width(el.data("scrollableAreaWidth")); 1153 1154 // Move to the starting position 1155 el.data("scrollWrapper").scrollLeft(el.data("startingPosition")); 1156 el.data("scrollXPos", el.data("startingPosition")); 1157 }, 1158 /********************************************************** 1159 Get current scrolling left offset 1160 **********************************************************/ 1161 getScrollerOffset: function() { 1162 var el = this.element; 1163 1164 // Returns the current left offset 1165 // Please remember that if the scroller is in continuous 1166 // mode, the offset is not that relevant anymore since 1167 // the plugin will swap the elements inside the scroller 1168 // around and manipulate the offset in this process. 1169 return el.data("scrollWrapper").scrollLeft(); 1170 }, 1171 /********************************************************** 1172 Stopping, starting and doing the auto scrolling 1173 **********************************************************/ 1174 stopAutoScrolling: function() { 1175 var self = this, 1176 el = this.element; 1177 1178 if (el.data("autoScrollingInterval") !== null) { 1179 clearInterval(el.data("autoScrollingInterval")); 1180 el.data("autoScrollingInterval", null); 1181 1182 // Check to see which hotspots should be active 1183 // in the position where the scroller has stopped 1184 self._showHideHotSpots(); 1185 1186 self._trigger("autoScrollingStopped"); 1187 } 1188 }, 1189 /********************************************************** 1190 Start Autoscrolling 1191 **********************************************************/ 1192 startAutoScrolling: function() { 1193 var self = this, 1194 el = this.element, 1195 o = this.options; 1196 1197 if (el.data("enabled")) { 1198 self._showHideHotSpots(); 1199 1200 // Stop any running interval 1201 clearInterval(el.data("autoScrollingInterval")); 1202 el.data("autoScrollingInterval", null); 1203 1204 // Callback 1205 self._trigger("autoScrollingStarted"); 1206 1207 // Start interval 1208 el.data("autoScrollingInterval", setInterval(function() { 1209 1210 // If the scroller is not visible or 1211 // if the scrollable area is shorter than the scroll wrapper 1212 // any running auto scroll interval should stop. 1213 if (!(el.data("visible")) || (el.data("scrollableAreaWidth") <= (el.data("scrollWrapper").innerWidth()))) { 1214 // Stop any running interval 1215 clearInterval(el.data("autoScrollingInterval")); 1216 el.data("autoScrollingInterval", null); 1217 1218 } else { 1219 1220 // Store the old scrollLeft value to see if the scrolling has reached the end 1221 el.data("previousScrollLeft", el.data("scrollWrapper").scrollLeft()); 1222 1223 switch (o.autoScrollingDirection) { 1224 case "right": 1225 1226 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + o.autoScrollingStep); 1227 if (el.data("previousScrollLeft") === el.data("scrollWrapper").scrollLeft()) { 1228 self._trigger("autoScrollingRightLimitReached"); 1229 self.stopAutoScrolling(); 1230 } 1231 break; 1232
1233 case "left": 1234 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - o.autoScrollingStep); 1235 if (el.data("previousScrollLeft") === el.data("scrollWrapper").scrollLeft()) { 1236 self._trigger("autoScrollingLeftLimitReached"); 1237 self.stopAutoScrolling(); 1238 } 1239 break; 1240 1241 case "backAndForth": 1242 if (el.data("pingPongDirection") === "right") { 1243 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + (o.autoScrollingStep)); 1244 } else { 1245 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - (o.autoScrollingStep)); 1246 } 1247 1248 // If the scrollLeft hasnt't changed it means that the scrolling has reached 1249 // the end and the direction should be switched 1250 if (el.data("previousScrollLeft") === el.data("scrollWrapper").scrollLeft()) { 1251 if (el.data("pingPongDirection") === "right") { 1252 el.data("pingPongDirection", "left"); 1253 self._trigger("autoScrollingRightLimitReached"); 1254 } else { 1255 el.data("pingPongDirection", "right"); 1256 self._trigger("autoScrollingLeftLimitReached"); 1257 } 1258 } 1259 break; 1260 1261 case "endlessLoopRight": 1262 1263 // Do the auto scrolling 1264 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + o.autoScrollingStep); 1265 1266 self._checkContinuousSwapRight(); 1267 break; 1268 case "endlessLoopLeft": 1269 1270 // Do the auto scrolling 1271 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - o.autoScrollingStep); 1272 1273 self._checkContinuousSwapLeft(); 1274 break; 1275 default: 1276 break; 1277 1278 } 1279 } 1280 }, o.autoScrollingInterval)); 1281 } 1282 }, 1283 /********************************************************** 1284 Check Continuos Swap Right 1285 **********************************************************/ 1286 _checkContinuousSwapRight: function() { 1287 var el = this.element, 1288 o = this.options; 1289 1290 // Get the width of the first element. When it has scrolled out of view, 1291 // the element swapping should be executed. A true/false variable is used 1292 // as a flag variable so the swapAt value doesn't have to be recalculated 1293 // in each loop. 1294 if (el.data("getNextElementWidth")) { 1295 1296 if ((o.startAtElementId.length > 0) && (el.data("startAtElementHasNotPassed"))) { 1297 // If the user has set a certain element to start at, set swapAt 1298 // to that element width. This happens once. 1299 el.data("swapAt", $("#" + o.startAtElementId).outerWidth(true)); 1300 el.data("startAtElementHasNotPassed", false); 1301 } else { 1302 // Set swapAt to the first element in the scroller 1303 el.data("swapAt", el.data("scrollableArea").children(":first").outerWidth(true)); 1304 } 1305 el.data("getNextElementWidth", false); 1306 } 1307 1308 // Check to see if the swap should be done 1309 if (el.data("swapAt") <= el.data("scrollWrapper").scrollLeft()) { 1310 el.data("swappedElement", el.data("scrollableArea").children(":first").detach()); 1311 el.data("scrollableArea").append(el.data("swappedElement")); 1312 var wrapperLeft = el.data("scrollWrapper").scrollLeft(); 1313 el.data("scrollWrapper").scrollLeft(wrapperLeft - el.data("swappedElement").outerWidth(true)); 1314 el.data("getNextElementWidth", true); 1315 } 1316 }, 1317 /********************************************************** 1318 Check Continuos Swap Left 1319 **********************************************************/ 1320 _checkContinuousSwapLeft: function() { 1321 var el = this.element, 1322 o = this.options; 1323 1324 // Get the width of the first element. When it has scrolled out of view, 1325 // the element swapping should be executed. A true/false variable is used 1326 // as a flag variable so the swapAt value doesn't have to be recalculated 1327 // in each loop. 1328 1329 if (el.data("getNextElementWidth")) { 1330 if ((o.startAtElementId.length > 0) && (el.data("startAtElementHasNotPassed"))) { 1331 el.data("swapAt", $("#" + o.startAtElementId).outerWidth(true)); 1332 el.data("startAtElementHasNotPassed", false); 1333 } else { 1334 el.data("swapAt", el.data("scrollableArea").children(":first").outerWidth(true)); 1335 } 1336 1337 el.data("getNextElementWidth", false); 1338 } 1339 1340 // Check to see if the swap should be done 1341 if (el.data("scrollWrapper").scrollLeft() === 0) { 1342 1343 el.data("swappedElement", el.data("scrollableArea").children(":last").detach()); 1344 el.data("scrollableArea").prepend(el.data("swappedElement")); 1345 el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + el.data("swappedElement").outerWidth(true)); 1346 el.data("getNextElementWidth", true); 1347 1348 } 1349 1350 }, 1351 restoreOriginalElements: function() { 1352 var self = this, 1353 el = this.element; 1354 1355 // Restore the original content of the scrollable area 1356 el.data("scrollableArea").html(el.data("originalElements")); 1357 self.recalculateScrollableArea(); 1358 self.jumpToElement("first"); 1359 }, 1360 show: function() { 1361 var el = this.element; 1362 el.data("visible", true); 1363 el.show(); 1364 }, 1365 hide: function() { 1366 var el = this.element; 1367 el.data("visible", false); 1368 el.hide(); 1369 }, 1370 enable: function() { 1371 var el = this.element; 1372 1373 // Enable touch scrolling 1374 if (this.options.touchScrolling) { 1375 el.data("scrollWrapper").kinetic('attach'); 1376 } 1377 1378 // Set enabled to true 1379 el.data("enabled", true); 1380 }, 1381 disable: function() { 1382 var self = this, 1383 el = this.element; 1384 1385 // Clear all running intervals 1386 self.stopAutoScrolling(); 1387 clearInterval(el.data("rightScrollingInterval")); 1388 clearInterval(el.data("leftScrollingInterval"));
1389 clearInterval(el.data("hideHotSpotBackgroundsInterval")); 1390 1391 // Disable touch scrolling 1392 if (this.options.touchScrolling) { 1393 el.data("scrollWrapper").kinetic('detach'); 1394 } 1395 1396 // Set enabled to false 1397 el.data("enabled", false); 1398 }, 1399 destroy: function() { 1400 var self = this, 1401 el = this.element; 1402 1403 // Clear all running intervals 1404 self.stopAutoScrolling(); 1405 clearInterval(el.data("rightScrollingInterval")); 1406 clearInterval(el.data("leftScrollingInterval")); 1407 clearInterval(el.data("hideHotSpotBackgroundsInterval")); 1408 1409 // Remove all element specific events 1410 el.data("scrollingHotSpotRight").unbind("mouseover"); 1411 el.data("scrollingHotSpotRight").unbind("mouseout"); 1412 el.data("scrollingHotSpotRight").unbind("mousedown"); 1413 1414 el.data("scrollingHotSpotLeft").unbind("mouseover"); 1415 el.data("scrollingHotSpotLeft").unbind("mouseout"); 1416 el.data("scrollingHotSpotLeft").unbind("mousedown"); 1417 1418 el.unbind("mousenter"); 1419 el.unbind("mouseleave"); 1420 1421 // Remove all elements created by the plugin 1422 el.data("scrollingHotSpotRight").remove(); 1423 el.data("scrollingHotSpotLeft").remove(); 1424 el.data("scrollableArea").remove(); 1425 el.data("scrollWrapper").remove(); 1426 1427 // Restore the original content of the scrollable area 1428 el.html(el.data("originalElements")); 1429 1430 // Call the base destroy function 1431 $.Widget.prototype.destroy.apply(this, arguments); 1432 1433 } 1434 1435 }); 1436})(jQuery);
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.