1/** 2 * carouselTicker v1.0.0 3 * More information visit http://likeclever1.github.io/carouselTicker/ 4 * Copyright 2015, Yuriy Berezovskiy 5 * 6 * Released under the MIT license - http://opensource.org/licenses/MIT 7 * 8 * Usages: $(...).carouselTicker(); 9 * 10 * Options: 11 * - speed: integer 12 * - delay: integer 13 * - direction: string - "prev", "next" 14 */ 15 16"use strict"; 17 18(function ($) { 19 var defaults = { 20 // GENERAL 21 direction: "prev", 22 mode: "horizontal", 23 speed: 1, 24 delay: 30, 25 pauseOnHover: 30, 26 27 // CALLBACKS 28 onCarouselTickerLoad: function () {}, 29 }; 30 31 $.fn.carouselTicker = function (options) { 32 if (this.length == 0) return this; 33 34 // support multiple elements 35 if (this.length > 1) { 36 this.each(function () { 37 $(this).carouselTicker(options); 38 }); 39 return this; 40 } 41 42 // create a namespace to be throughout the plugin 43 var ticker = {}; 44 // set a reference to our slider element 45 var el = this, 46 $el = $(this); 47 48 /** 49 * =================================================================================== 50 * = PRIVATE FUNCTIONS 51 * =================================================================================== 52 */ 53 54 /** 55 * Initializes namespace settings to be used throughout plugin 56 */ 57 58 var _init = function () { 59 // merge user-supplied options with defaults 60 ticker.settings = $.extend({}, defaults, options); 61 // initialize pointer timeout 62 ticker.intervalPointer = null; 63 // determine direction ticker 64 ticker.directionSwitcher = ticker.settings.direction === "prev" ? -1 : 1; 65 // set default value items inside ticker 66 ticker.itemsWidth = 0; 67 // set default value childs (items + clone) 68 ticker.childsWidth = 0; 69 // set default value items inside ticker 70 ticker.itemsHeight = 0; 71 // set default value childs (items + clone) 72 ticker.childsHeight = 0; 73 // determine list 74 ticker.$list = $el.children("div"); 75 // determine items 76 ticker.$items = ticker.$list.children(".carouselTicker__item"); 77 // initialize initialize flag 78 ticker.isInitialize = false; 79 // initialize mousemove flag 80 ticker.isMousemove = false; 81 // determine ticker parent 82 ticker.$parent = $el.parent(); 83 // set wrapper class 84 ticker.wrapCls = "carouselTicker__wrap"; 85 // set list class 86 ticker.listCls = "carouselTicker__list"; 87 ticker.itemCls = "carouselTicker__item"; 88 // set loader class 89 ticker.loaderCls = "carouselTicker__loader"; 90 // set clone class 91 ticker.cloneCls = "carouselTicker__clone"; 92 // determine touch events 93 ticker.touch = "ontouchstart" in document.documentElement ? true : false; 94 // determine event types 95 ticker.eventTypes = { 96 mousedown: ticker.touch ? "touchstart" : "mousedown", 97 mousemove: ticker.touch ? "touchmove" : "mousemove", 98 mouseup: ticker.touch ? "touchend" : "mouseup", 99 }; 100 101 _setup(); 102 }; 103 104 /** 105 * Performs all DOM and CSS modifications 106 */ 107 108 var _setup = function () { 109 110 function setupFunc() { 111 if ($el.children().hasClass(ticker.wrapCls)) return; 112 $("<div class='" + ticker.loaderCls + "'></div>").appendTo($el); 113 $el.find("." + ticker.wrapCls).css({ position: "relative" }); 114 ticker.$list.wrap( 115 "<div class='carouselTicker__wrap' style='position: relative; overflow: hidden; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none;'></div>" 116 ); 117 ticker.$items.clone().addClass(ticker.cloneCls).appendTo(ticker.$list); 118 ticker.$list.css({ 119 position: "relative", 120 }); 121 // set true to initialize value 122 ticker.isInitialize = true; 123 ticker.settings.onCarouselTickerLoad(); 124 _start(); 125 } 126 127 // if horizontal mode 128 if (ticker.settings.mode === "horizontal") { 129 // determine summ items width 130 _calcItemsWidth(); 131 // if summ items width > width parent el 132 if (ticker.itemsWidth > ticker.$parent.width()) { 133 // set new width 134 $el 135 .find("." + ticker.wrapCls) 136 .css({ width: ticker.$parent.width() + "px" }); 137 ticker.$list.css({ width: ticker.itemsWidth * 2, left: 0 }); 138 // set common parameters 139 setupFunc(); 140 } 141 // if vertical mode 142 } else if (ticker.settings.mode === "vertical") { 143 144 // determine summ items height 145 _calcItemsHeight(); 146 147 // if summ items height > height parent el 148 if (ticker.itemsHeight > ticker.$parent.height()) { 149 // set new height 150 $el 151 .find("." + ticker.wrapCls) 152 .css({ height: ticker.$parent.height() + "px" }); 153 ticker.$list.css({ height: ticker.itemsHeight * 2, top: 0 }); 154 // set common parameters 155 setupFunc(); 156 } 157 } 158 159 if (ticker.isInitialize) { 160 // delete event dragstart from link and image 161 $el.on("dragstart", function (e) { 162 if ( 163 e.target.nodeName.toUpperCase() == "IMG" || 164 e.target.nodeName.toUpperCase() == "A" 165 ) { 166 return false;
167 } 168 }); 169 } 170 171 }; 172 173 /** 174 * Start the ticker 175 */ 176 177 var _start = function () { 178 // remove the loading DOM element 179 if ($el.find("." + ticker.loaderCls).length) 180 $el.find("." + ticker.loaderCls).remove(); 181 // start ticker-carousel 182 ticker.intervalPointer = setInterval(function () { 183 _moveTicker(); 184 }, ticker.settings.delay); 185 // initialize eventOver event 186 if(ticker.settings.pauseOnHover){ 187 $el.find("." + ticker.itemCls).on("mouseover", _eventOver); 188 $el.find("." + ticker.itemCls).on("mouseleave", _eventOut); 189 } 190 // initialize drag and drop event 191 if(ticker.settings.carouselDrag){ 192 _eventDragAndDrop(); 193 } 194 }; 195 196 /** 197 * Move carouselTicker 198 */ 199 var _moveTicker = function () { 200 var mode = ticker.settings.mode === "horizontal" ? "left" : "top", 201 itemsSize = 202 ticker.settings.mode === "horizontal" 203 ? ticker.itemsWidth 204 : ticker.itemsHeight; 205 // step ticker moving 206 ticker.$list.css( 207 mode, 208 "+=" + ticker.directionSwitcher * ticker.settings.speed + "px" 209 ); 210 // depending of direction change offset list for effect Infinity rotate 211 if (ticker.settings.direction === "prev") { 212 if (Math.abs(parseInt(ticker.$list.css(mode))) >= itemsSize) { 213 ticker.$list.css(mode, 0); 214 } 215 } 216 217 if (ticker.settings.direction === "next") { 218 if (parseInt(ticker.$list.css(mode)) >= 0) { 219 ticker.$list.css(mode, -itemsSize + "px"); 220 } 221 } 222 }; 223 224 /** 225 * Method calc summ items width 226 */ 227 function _calcItemsWidth() { 228 // set value 0 to default 229 ticker.itemsWidth = 0; 230 // calc sum 231 ticker.$items.each(function () { 232 var $this = $(this), 233 style = this.currentStyle || window.getComputedStyle(this), 234 margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight); 235 // if item clone - calc summ without it 236 if ($this.hasClass(ticker.cloneCls)) return; 237 ticker.itemsWidth += this.getBoundingClientRect().width + margin; 238 }); 239 } 240 241 /** 242 * Method calc summ items height 243 */ 244 function _calcItemsHeight() { 245 // set value 0 to default 246 ticker.itemsHeight = 0; 247 // calc sum 248 ticker.$items.each(function () { 249 var $this = $(this); 250 251 // if item clone - calc summ without it 252 if ($this.hasClass(ticker.cloneCls)) return; 253 ticker.itemsHeight += $this.outerHeight(true); 254 }); 255 } 256 257 /** 258 * Event Methods _eventOver, _eventOut, _eventDragAndDrop 259 */ 260 function _eventOver() { 261 // depending from mode choose condition 262 var condition = 263 ticker.settings.mode === "horizontal" 264 ? ticker.itemsWidth > ticker.$parent.width() 265 : ticker.itemsHeight > ticker.$parent.height(); 266 // if ticker width/height > outer width/height block 267 if (condition) { 268 // make clearInterval 269 clearInterval(ticker.intervalPointer); 270 // make clearInterval 271 ticker.intervalPointer = false; 272 } 273 } 274 275 function _eventOut() { 276 // depending from mode choose condition 277 var condition = 278 ticker.settings.mode === "horizontal" 279 ? ticker.itemsWidth > ticker.$parent.width() 280 : ticker.itemsHeight > ticker.$parent.height(); 281 // if mouse move 282 if (ticker.isMousemove) { 283 // off event behaviour mousemove 284 ticker.$list.off(ticker.eventTypes.mousemove); 285 // call event mouseup 286 ticker.$list.trigger(ticker.eventTypes.mouseup); 287 } 288 // if ticker width > outer width block 289 if (condition) { 290 // protection from double setInterval 291 if (ticker.intervalPointer) return; 292 // call _moveTicker 293 ticker.intervalPointer = setInterval(function () { 294 _moveTicker(); 295 }, ticker.settings.delay); 296 } 297 } 298 299 function _eventDragAndDrop() { 300 var flag = false; 301 302 ticker.$list.on(ticker.eventTypes.mousedown, function (e) { 303 var start = e.clientX || event.touches[0].pageX, 304 startY = e.clientY || event.touches[0].pageY, 305 $this = $(this), 306 posList = parseFloat($(this).css("left")), 307 posListY = parseFloat($(this).css("top")); 308 309 $(e.target).off("click"); 310 clearInterval(ticker.intervalPointer); 311 ticker.intervalPointer = false;
312 flag = true; 313 314 $this.on(ticker.eventTypes.mousemove, function (e) { 315 var x = e.clientX || event.touches[0].pageX, 316 y = e.clientY || event.touches[0].pageY, 317 // fix for touch device 318 diff = start - x, 319 diffY = startY - y; 320 321 if (ticker.touch) { 322 $(document).on("touchmove", function (e) { 323 e.preventDefault(); 324 }); 325 } 326 327 if (ticker.settings.mode === "horizontal") { 328 ticker.directionSwitcher = diff >= 0 ? -1 : 1; 329 } else if (ticker.settings.mode === "vertical") { 330 ticker.directionSwitcher = diffY >= 0 ? -1 : 1; 331 } 332 333 ticker.isMousemove = true; 334 335 if (flag) { 336 if (ticker.settings.mode === "horizontal") { 337 // if drag more left side 338 if (posList - diff >= 0 && ticker.directionSwitcher === 1) { 339 $this.css("left", "-=" + ticker.itemsWidth); 340 posList = -ticker.itemsWidth; 341 start = e.clientX || event.touches[0].pageX; 342 diff = 0; 343 } 344 // if drag more right side 345 if ( 346 posList - diff <= -ticker.itemsWidth && 347 ticker.directionSwitcher === -1 348 ) { 349 $this.css("left", 0); 350 posList = 0; 351 diff = 0; 352 start = e.clientX || event.touches[0].pageX; 353 } 354 355 $this.css("left", posList - diff + "px"); 356 } else if (ticker.settings.mode === "vertical") { 357 // if drag more top side 358 if (posListY - diffY >= 0 && ticker.directionSwitcher === 1) { 359 $this.css("top", "-=" + ticker.itemsHeight); 360 posListY = -ticker.itemsHeight; 361 startY = e.clientY || event.touches[0].pageY; 362 diffY = 0; 363 } 364 // if drag more right side 365 if ( 366 posListY - diffY <= -ticker.itemsHeight && 367 ticker.directionSwitcher === -1 368 ) { 369 $this.css("top", 0); 370 posListY = 0; 371 diffY = 0; 372 startY = e.clientY || event.touches[0].pageY; 373 } 374 375 $this.css("top", posListY - diffY + "px"); 376 } 377 } 378 }); 379 }); 380 381 ticker.$list.on(ticker.eventTypes.mouseup, function (e) { 382 var $target = $(e.target); 383 384 if ( 385 $target.attr("href") || 386 ($target.parents().attr("href") && ticker.isMousemove) 387 ) { 388 e.preventDefault(); 389 $target.on("click", function (e) { 390 e.preventDefault(); 391 }); 392 } 393 394 flag = false; 395 ticker.isMousemove = false; 396 ticker.settings.direction = 397 ticker.directionSwitcher === 1 ? "next" : "prev"; 398 $(this).off(ticker.eventTypes.mousemove); 399 400 if (ticker.touch) { 401 $(document).off("touchmove"); 402 } 403 404 if (ticker.intervalPointer) clearInterval(ticker.intervalPointer); 405 406 if (ticker.touch) 407 ticker.intervalPointer = setInterval(function () { 408 _moveTicker(); 409 }, ticker.settings.delay); 410 }); 411 } 412 413 /** 414 * Public Methods 415 */ 416 417 /** 418 * resize carouselTicker 419 * 420 **/ 421 422 el.resizeTicker = function () { 423 _calcItemsWidth(); 424 425 if (ticker.itemsWidth > ticker.$parent.width()) { 426 if (!ticker.isInitialize) { 427 _init(); 428 } 429 } else { 430 if (ticker.isInitialize) el.destructor(); 431 } 432 }; 433 434 /** 435 * Stop rotate carouselTicker 436 */ 437 438 el.stop = function () { 439 $el.off("mouseover", _eventOver); 440 $el.off("mouseleave", _eventOut); 441 442 clearInterval(ticker.intervalPointer); 443 ticker.intervalPointer = false; 444 }; 445 446 /** 447 * Run carouselTicker 448 */ 449 450 el.run = function () { 451 _start(); 452 }; 453 454 /** 455 * Destroy the current instance of the ticker (revert everything back to original state) 456 */ 457 458 el.destructor = function () { 459 var $clones = $el.find("." + ticker.cloneCls); 460 // remove all clone items from dom 461 $clones.remove(); 462 463 var $tickerWrapper = $el.find("." + ticker.wrapCls); 464 465 if ($tickerWrapper.length) { 466 var $list = $el.find("." + ticker.listCls); 467 $list.unwrap(); 468 $list.css({ left: "auto", position: "static", width: "auto" }); 469 $el.css({ width: "auto", position: "static" }); 470 } 471 472 el.stop(); 473 ticker.isInitialize = false;
474 }; 475 476 /** 477 * Reload the ticker (revert all DOM changes, and re-initialize) 478 */ 479 el.reloadCarouselTicker = function (settings) { 480 if (settings != undefined) options = settings; 481 el.destructor(); 482 _init(); 483 }; 484 485 /** 486 * Start rotate to next direction 487 */ 488 el.next = function () { 489 el.stop(); 490 ticker.settings.direction = "next"; 491 ticker.directionSwitcher = ticker.settings.direction === "prev" ? -1 : 1; 492 el.run(); 493 }; 494 495 /** 496 * Start rotate to prev direction 497 */ 498 el.prev = function () { 499 el.stop(); 500 ticker.settings.direction = "prev"; 501 ticker.directionSwitcher = ticker.settings.direction === "prev" ? -1 : 1; 502 el.run(); 503 }; 504 505 if (document.readyState === "loading") { 506 $(window).on("load", function () { 507 _init(); 508 }); 509 } else { 510 _init(); 511 } 512 513 // returns the current jQuery object 514 return this; 515 }; 516})(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.