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