1 2/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 3(function(g, q, f) { 4 function p(a, b) { 5 this.wrapper = "string" == typeof a ? q.querySelector(a) : a; 6 this.scroller = this.wrapper.children[0]; 7 this.scrollerStyle = this.scroller.style; 8 this.options = { 9 resizeScrollbars: !0, 10 mouseWheelSpeed: 20, 11 snapThreshold: .334, 12 disablePointer: !d.hasPointer, 13 disableTouch: d.hasPointer || !d.hasTouch, 14 disableMouse: d.hasPointer || d.hasTouch, 15 startX: 0, 16 startY: 0, 17 scrollY: !0, 18 directionLockThreshold: 5, 19 momentum: !0, 20 bounce: !0, 21 bounceTime: 600, 22 bounceEasing: "", 23 preventDefault: !0, 24 preventDefaultException: { 25 tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ 26 }, 27 HWCompositing: !0, 28 useTransition: !0, 29 useTransform: !0, 30 bindToWrapper: "undefined" === typeof g.onmousedown 31 }; 32 for (var c in b) this.options[c] = b[c]; 33 this.translateZ = this.options.HWCompositing && d.hasPerspective ? " translateZ(0)" : ""; 34 this.options.useTransition = d.hasTransition && this.options.useTransition; 35 this.options.useTransform = d.hasTransform && this.options.useTransform; 36 this.options.eventPassthrough = !0 === this.options.eventPassthrough ? "vertical" : this.options.eventPassthrough; 37 this.options.preventDefault = !this.options.eventPassthrough && 38 this.options.preventDefault; 39 this.options.scrollY = "vertical" == this.options.eventPassthrough ? !1 : this.options.scrollY; 40 this.options.scrollX = "horizontal" == this.options.eventPassthrough ? !1 : this.options.scrollX; 41 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 42 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 43 this.options.bounceEasing = "string" == typeof this.options.bounceEasing ? d.ease[this.options.bounceEasing] || d.ease.circular : 44 this.options.bounceEasing; 45 this.options.resizePolling = void 0 === this.options.resizePolling ? 60 : this.options.resizePolling; 46 !0 === this.options.tap && (this.options.tap = "tap"); 47 this.options.useTransition || this.options.useTransform || /relative|absolute/i.test(this.scrollerStyle.position) || (this.scrollerStyle.position = "relative"); 48 "scale" == this.options.shrinkScrollbars && (this.options.useTransition = !1); 49 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 50 this.directionY = this.directionX = this.y = 51 this.x = 0; 52 this._events = {}; 53 this._init(); 54 this.refresh(); 55 this.scrollTo(this.options.startX, this.options.startY); 56 this.enable() 57 } 58 59 function u(a, b, c) { 60 var e = q.createElement("div"), 61 d = q.createElement("div"); 62 !0 === c && (e.style.cssText = "position:absolute;z-index:9999", d.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px"); 63 d.className = "iScrollIndicator"; 64 "h" == a ? (!0 === c && (e.style.cssText += 65 ";height:7px;left:2px;right:2px;bottom:0", d.style.height = "100%"), e.className = "iScrollHorizontalScrollbar") : (!0 === c && (e.style.cssText += ";width:7px;bottom:2px;top:2px;right:1px", d.style.width = "100%"), e.className = "iScrollVerticalScrollbar"); 66 e.style.cssText += ";overflow:hidden"; 67 b || (e.style.pointerEvents = "none"); 68 e.appendChild(d); 69 return e 70 } 71 72 function v(a, b) { 73 this.wrapper = "string" == typeof b.el ? q.querySelector(b.el) : b.el; 74 this.wrapperStyle = this.wrapper.style; 75 this.indicator = this.wrapper.children[0]; 76 this.indicatorStyle = 77 this.indicator.style; 78 this.scroller = a; 79 this.options = { 80 listenX: !0, 81 listenY: !0, 82 interactive: !1, 83 resize: !0, 84 defaultScrollbars: !1, 85 shrink: !1, 86 fade: !1, 87 speedRatioX: 0, 88 speedRatioY: 0 89 }; 90 for (var c in b) this.options[c] = b[c]; 91 this.sizeRatioY = this.sizeRatioX = 1; 92 this.maxPosY = this.maxPosX = 0; 93 this.options.interactive && (this.options.disableTouch || (d.addEvent(this.indicator, "touchstart", this), d.addEvent(g, "touchend", this)), this.options.disablePointer || (d.addEvent(this.indicator, d.prefixPointerEvent("pointerdown"), this), d.addEvent(g, 94 d.prefixPointerEvent("pointerup"), this)), this.options.disableMouse || (d.addEvent(this.indicator, "mousedown", this), d.addEvent(g, "mouseup", this))); 95 if (this.options.fade) { 96 this.wrapperStyle[d.style.transform] = this.scroller.translateZ; 97 var e = d.style.transitionDuration; 98 if (e) { 99 this.wrapperStyle[e] = d.isBadAndroid ? "0.0001ms" : "0ms"; 100 var f = this; 101 d.isBadAndroid && t(function() { 102 "0.0001ms" === f.wrapperStyle[e] && (f.wrapperStyle[e] = "0s") 103 }); 104 this.wrapperStyle.opacity = "0" 105 } 106 } 107 } 108 var t = g.requestAnimationFrame || g.webkitRequestAnimationFrame || 109 g.mozRequestAnimationFrame || g.oRequestAnimationFrame || g.msRequestAnimationFrame || function(a) { 110 g.setTimeout(a, 1E3 / 60) 111 }, 112 d = function() { 113 function a(a) { 114 return !1 === e ? !1 : "" === e ? a : e + a.charAt(0).toUpperCase() + a.substr(1) 115 } 116 var b = {}, 117 c = q.createElement("div").style, 118 e = function() { 119 for (var a = ["t", "webkitT", "MozT", "msT", "OT"], b, e = 0, d = a.length; e < d; e++) 120 if (b = a[e] + "ransform", b in c) return a[e].substr(0, a[e].length - 1); 121 return !1 122 }(); 123 b.getTime = Date.now || function() { 124 return (new Date).getTime() 125 }; 126 b.extend = function(a, b) { 127 for (var c in b) a[c] = 128 b[c] 129 }; 130 b.addEvent = function(a, b, c, e) { 131 a.addEventListener(b, c, !!e) 132 }; 133 b.removeEvent = function(a, b, c, e) { 134 a.removeEventListener(b, c, !!e) 135 }; 136 b.prefixPointerEvent = function(a) { 137 return g.MSPointerEvent ? "MSPointer" + a.charAt(7).toUpperCase() + a.substr(8) : a 138 }; 139 b.momentum = function(a, b, c, e, d, k) { 140 b = a - b; 141 c = f.abs(b) / c; 142 var g; 143 k = void 0 === k ? 6E-4 : k; 144 g = a + c * c / (2 * k) * (0 > b ? -1 : 1); 145 k = c / k; 146 g < e ? (g = d ? e - d / 2.5 * (c / 8) : e, b = f.abs(g - a), k = b / c) : 0 < g && (g = d ? d / 2.5 * (c / 8) : 0, b = f.abs(a) + g, k = b / c); 147 return { 148 destination: f.round(g), 149 duration: k 150 } 151 }; 152 var d = a("transform"); 153 b.extend(b, { 154 hasTransform: !1 !== d, 155 hasPerspective: a("perspective") in c, 156 hasTouch: "ontouchstart" in g, 157 hasPointer: !(!g.PointerEvent && !g.MSPointerEvent), 158 hasTransition: a("transition") in c 159 }); 160 b.isBadAndroid = function() { 161 var a = g.navigator.appVersion; 162 return /Android/.test(a) && !/Chrome\/\d/.test(a) ? (a = a.match(/Safari\/(\d+.\d)/)) && "object" === typeof a && 2 <= a.length ? 535.19 > parseFloat(a[1]) : !0 : !1 163 }(); 164 b.extend(b.style = {}, { 165 transform: d, 166 transitionTimingFunction: a("transitionTimingFunction"), 167 transitionDuration: a("transitionDuration"), 168 transitionDelay: a("transitionDelay"), 169 transformOrigin: a("transformOrigin") 170 }); 171 b.hasClass = function(a, b) { 172 return (new RegExp("(^|\\s)" + b + "(\\s|$)")).test(a.className) 173 }; 174 b.addClass = function(a, c) { 175 if (!b.hasClass(a, c)) { 176 var e = a.className.split(" "); 177 e.push(c); 178 a.className = e.join(" ") 179 } 180 }; 181 b.removeClass = function(a, c) { 182 b.hasClass(a, c) && (a.className = a.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)", "g"), " ")) 183 }; 184 b.offset = function(a) { 185 for (var b = -a.offsetLeft, c = -a.offsetTop; a = a.offsetParent;) b -= a.offsetLeft, c -= a.offsetTop; 186 return { 187 left: b, 188 top: c 189 } 190 }; 191 b.preventDefaultException = function(a, b) { 192 for (var c in b) 193 if (b[c].test(a[c])) return !0; 194 return !1 195 }; 196 b.extend(b.eventType = {}, { 197 touchstart: 1, 198 touchmove: 1, 199 touchend: 1, 200 mousedown: 2, 201 mousemove: 2, 202 mouseup: 2, 203 pointerdown: 3, 204 pointermove: 3, 205 pointerup: 3, 206 MSPointerDown: 3, 207 MSPointerMove: 3, 208 MSPointerUp: 3 209 }); 210 b.extend(b.ease = {}, { 211 quadratic: { 212 style: "cubic-bezier(0.25, 0.46, 0.45, 0.94)", 213 fn: function(a) { 214 return a * (2 - a) 215 } 216 }, 217 circular: { 218 style: "cubic-bezier(0.1, 0.57, 0.1, 1)", 219 fn: function(a) {
220 return f.sqrt(1 - --a * a) 221 } 222 }, 223 back: { 224 style: "cubic-bezier(0.175, 0.885, 0.32, 1.275)", 225 fn: function(a) { 226 return --a * a * (5 * a + 4) + 1 227 } 228 }, 229 bounce: { 230 style: "", 231 fn: function(a) { 232 return (a /= 1) < 1 / 2.75 ? 7.5625 * a * a : a < 2 / 2.75 ? 7.5625 * (a -= 1.5 / 2.75) * a + .75 : a < 2.5 / 2.75 ? 7.5625 * (a -= 2.25 / 2.75) * a + .9375 : 7.5625 * (a -= 2.625 / 2.75) * a + .984375 233 } 234 }, 235 elastic: { 236 style: "", 237 fn: function(a) { 238 return 0 === a ? 0 : 1 == a ? 1 : .4 * f.pow(2, -10 * a) * f.sin(2 * (a - .055) * f.PI / .22) + 1 239 } 240 } 241 }); 242 b.tap = function(a, b) { 243 var c = q.createEvent("Event"); 244 c.initEvent(b, !0, !0); 245 c.pageX = a.pageX; 246 c.pageY = a.pageY; 247 a.target.dispatchEvent(c) 248 }; 249 b.click = function(a) { 250 var b = a.target, 251 c; 252 253 // nectar addition. 254 var activateEvent = false; 255 if( (/(INPUT)/i).test(b.tagName) ) { 256 257 if( b.getAttribute("type") == 'submit' || b.getAttribute("type") == 'button' ) { 258 activateEvent = true; 259 } 260 261 } 262 263 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(b.tagName) || activateEvent ) { 264 (c = q.createEvent(g.MouseEvent ? "MouseEvents" : "Event"), 265 c.initEvent("click", !0, !0), c.view = a.view || g, c.detail = 1, c.screenX = b.screenX || 0, c.screenY = b.screenY || 0, c.clientX = b.clientX || 0, c.clientY = b.clientY || 0, c.ctrlKey = !!a.ctrlKey, c.altKey = !!a.altKey, c.shiftKey = !!a.shiftKey, c.metaKey = !!a.metaKey, c.button = 0, c.relatedTarget = null, c._constructed = !0, b.dispatchEvent(c)) 266 } 267 268 }; 269 return b 270 }(); 271 p.prototype = { 272 version: "5.2.0", 273 _init: function() { 274 this._initEvents(); 275 (this.options.scrollbars || this.options.indicators) && this._initIndicators(); 276 this.options.mouseWheel && this._initWheel(); 277 this.options.snap && this._initSnap(); 278 this.options.keyBindings && this._initKeys() 279 }, 280 destroy: function() { 281 this._initEvents(!0); 282 clearTimeout(this.resizeTimeout); 283 this.resizeTimeout = null; 284 this._execEvent("destroy") 285 }, 286 _transitionEnd: function(a) { 287 a.target == this.scroller && this.isInTransition && (this._transitionTime(), this.resetPosition(this.options.bounceTime) || (this.isInTransition = !1, this._execEvent("scrollEnd"))) 288 }, 289 _start: function(a) { 290 if (!(1 != d.eventType[a.type] && 0 !== (a.which ? 291 a.button : 2 > a.button ? 0 : 4 == a.button ? 1 : 2) || !this.enabled || this.initiated && d.eventType[a.type] !== this.initiated)) { 292 !this.options.preventDefault || d.isBadAndroid || d.preventDefaultException(a.target, this.options.preventDefaultException) || a.preventDefault(); 293 var b = a.touches ? a.touches[0] : a; 294 this.initiated = d.eventType[a.type]; 295 this.moved = !1; 296 this.directionLocked = this.directionY = this.directionX = this.distY = this.distX = 0; 297 this.startTime = d.getTime(); 298 this.options.useTransition && this.isInTransition ? (this._transitionTime(), 299 this.isInTransition = !1, a = this.getComputedPosition(), this._translate(f.round(a.x), f.round(a.y)), this._execEvent("scrollEnd")) : !this.options.useTransition && this.isAnimating && (this.isAnimating = !1, this._execEvent("scrollEnd")); 300 this.startX = this.x; 301 this.startY = this.y; 302 this.absStartX = this.x; 303 this.absStartY = this.y; 304 this.pointX = b.pageX; 305 this.pointY = b.pageY; 306 this._execEvent("beforeScrollStart") 307 } 308 }, 309 _move: function(a) { 310 if (this.enabled && d.eventType[a.type] === this.initiated) { 311 this.options.preventDefault && a.preventDefault(); 312 var b = a.touches ? a.touches[0] : a, 313 c = b.pageX - this.pointX, 314 e = b.pageY - this.pointY, 315 k = d.getTime(), 316 h; 317 this.pointX = b.pageX; 318 this.pointY = b.pageY; 319 this.distX += c; 320 this.distY += e; 321 b = f.abs(this.distX); 322 h = f.abs(this.distY); 323 if (!(300 < k - this.endTime && 10 > b && 10 > h)) { 324 this.directionLocked || this.options.freeScroll || (this.directionLocked
324= b > h + this.options.directionLockThreshold ? "h" : h >= b + this.options.directionLockThreshold ? "v" : "n"); 325 if ("h" == this.directionLocked) { 326 if ("vertical" == this.options.eventPassthrough) a.preventDefault(); 327 else if ("horizontal" == 328 this.options.eventPassthrough) { 329 this.initiated = !1; 330 return 331 } 332 e = 0 333 } else if ("v" == this.directionLocked) { 334 if ("horizontal" == this.options.eventPassthrough) a.preventDefault(); 335 else if ("vertical" == this.options.eventPassthrough) { 336 this.initiated = !1; 337 return 338 } 339 c = 0 340 } 341 c = this.hasHorizontalScroll ? c : 0; 342 e = this.hasVerticalScroll ? e : 0; 343 a = this.x + c; 344 b = this.y + e; 345 if (0 < a || a < this.maxScrollX) a = this.options.bounce ? this.x + c / 3 : 0 < a ? 0 : this.maxScrollX; 346 if (0 < b || b < this.maxScrollY) b = this.options.bounce ? this.y + e / 3 : 0 < b ? 0 : this.maxScrollY; 347 this.directionX = 348 0 < c ? -1 : 0 > c ? 1 : 0; 349 this.directionY = 0 < e ? -1 : 0 > e ? 1 : 0; 350 this.moved || this._execEvent("scrollStart"); 351 this.moved = !0; 352 this._translate(a, b); 353 300 < k - this.startTime && (this.startTime = k, this.startX = this.x, this.startY = this.y) 354 } 355 } 356 }, 357 _end: function(a) { 358 if (this.enabled && d.eventType[a.type] === this.initiated) { 359 this.options.preventDefault && !d.preventDefaultException(a.target, this.options.preventDefaultException) && a.preventDefault(); 360 var b, c; 361 c = d.getTime() - this.startTime; 362 var e = f.round(this.x), 363 k = f.round(this.y), 364 h = f.abs(e - this.startX), 365 g = f.abs(k - this.startY); 366 b = 0; 367 var l = ""; 368 this.initiated = this.isInTransition = 0; 369 this.endTime = d.getTime(); 370 if (!this.resetPosition(this.options.bounceTime)) 371 if (this.scrollTo(e, k), this.moved) 372 if (this._events.flick && 200 > c && 100 > h && 100 > g) this._execEvent("flick"); 373 else if (this.options.momentum && 300 > c && (b = this.hasHorizontalScroll ? d.momentum(this.x, this.startX, c, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { 374 destination: e, 375 duration: 0 376 }, c = this.hasVerticalScroll ? d.momentum(this.y, this.startY, 377 c, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { 378 destination: k, 379 duration: 0 380 }, e = b.destination, k = c.destination, b = f.max(b.duration, c.duration), this.isInTransition = 1), this.options.snap && (this.currentPage = l = this._nearestSnap(e, k), b = this.options.snapSpeed || f.max(f.max(f.min(f.abs(e - l.x), 1E3), f.min(f.abs(k - l.y), 1E3)), 300), e = l.x, k = l.y, this.directionY = this.directionX = 0, l = this.options.bounceEasing), e != this.x || k != this.y) { 381 if (0 < e || e < this.maxScrollX || 0 < k || k < this.maxScrollY) l = 382 d.ease.quadratic; 383 this.scrollTo(e, k, b, l) 384 } else this._execEvent("scrollEnd"); 385 else this.options.tap && d.tap(a, this.options.tap), this.options.click && d.click(a), this._execEvent("scrollCancel") 386 } 387 }, 388 _resize: function() { 389 var a = this; 390 clearTimeout(this.resizeTimeout); 391 this.resizeTimeout = setTimeout(function() { 392 a.refresh() 393 }, this.options.resizePolling) 394 }, 395 resetPosition: function(a) { 396 var b = this.x, 397 c = this.y; 398 !this.hasHorizontalScroll || 0 < this.x ? b = 0 : this.x < this.maxScrollX && (b = this.maxScrollX); 399 !this.hasVerticalScroll || 0 < this.y ? c = 400 0 : this.y < this.maxScrollY && (c = this.maxScrollY); 401 if (b == this.x && c == this.y) return !1; 402 this.scrollTo(b, c, a || 0, this.options.bounceEasing); 403 return !0 404 }, 405 disable: function() { 406 this.enabled = !1 407 }, 408 enable: function() { 409 this.enabled = !0 410 }, 411 refresh: function() {
412 this.wrapperWidth = this.wrapper.clientWidth; 413 this.wrapperHeight = this.wrapper.clientHeight; 414 this.scrollerWidth = this.scroller.offsetWidth; 415 this.scrollerHeight = this.scroller.offsetHeight; 416 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 417 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 418 this.hasHorizontalScroll = this.options.scrollX && 0 > this.maxScrollX; 419 this.hasVerticalScroll = this.options.scrollY && 0 > this.maxScrollY; 420 this.hasHorizontalScroll || (this.maxScrollX = 0, this.scrollerWidth = this.wrapperWidth); 421 this.hasVerticalScroll || (this.maxScrollY = 0, this.scrollerHeight = this.wrapperHeight); 422 this.directionY = this.directionX = this.endTime = 0; 423 this.wrapperOffset = d.offset(this.wrapper); 424 this._execEvent("refresh"); 425 this.resetPosition() 426 }, 427 on: function(a, b) { 428 this._events[a] || (this._events[a] = []); 429 this._events[a].push(b) 430 }, 431 off: function(a, b) { 432 if (this._events[a]) { 433 var c = this._events[a].indexOf(b); - 1 < c && this._events[a].splice(c, 1) 434 } 435 }, 436 _execEvent: function(a) { 437 if (this._events[a]) { 438 var b = 0, 439 c = this._events[a].length; 440 if (c) 441 for (; b < c; b++) this._events[a][b].apply(this, [].slice.call(arguments, 1)) 442 } 443 }, 444 scrollBy: function(a, b, c, e) { 445 a = this.x + a; 446 b = this.y + b; 447 this.scrollTo(a, b, c || 0, e) 448 }, 449 scrollTo: function(a, b, c, e) { 450 e = e || d.ease.circular; 451 this.isInTransition = this.options.useTransition && 0 < c; 452 var f = this.options.useTransition && e.style; 453 !c || f ? (f && (this._transitionTimingFunction(e.style), 454 this._transitionTime(c)), this._translate(a, b)) : this._animate(a, b, c, e.fn) 455 }, 456 scrollToElement: function(a, b, c, e, k) { 457 if (a = a.nodeType ? a : this.scroller.querySelector(a)) { 458 var h = d.offset(a); 459 h.left -= this.wrapperOffset.left; 460 h.top -= this.wrapperOffset.top; 461 !0 === c && (c = f.round(a.offsetWidth / 2 - this.wrapper.offsetWidth / 2)); 462 !0 === e && (e = f.round(a.offsetHeight / 2 - this.wrapper.offsetHeight / 2)); 463 h.left -= c || 0; 464 h.top -= e || 0; 465 h.left = 0 < h.left ? 0 : h.left < this.maxScrollX ? this.maxScrollX : h.left; 466 h.top = 0 < h.top ? 0 : h.top < this.maxScrollY ? this.maxScrollY : 467 h.top; 468 b = void 0 === b || null === b || "auto" === b ? f.max(f.abs(this.x - h.left), f.abs(this.y - h.top)) : b; 469 this.scrollTo(h.left, h.top, b, k) 470 } 471 }, 472 _transitionTime: function(a) { 473 if (this.options.useTransition) { 474 a = a || 0; 475 var b = d.style.transitionDuration; 476 if (b) { 477 this.scrollerStyle[b] = a + "ms"; 478 if (!a && d.isBadAndroid) { 479 this.scrollerStyle[b] = "0.0001ms"; 480 var c = this; 481 t(function() { 482 "0.0001ms" === c.scrollerStyle[b] && (c.scrollerStyle[b] = "0s") 483 }) 484 } 485 if (this.indicators) 486 for (var e = this.indicators.length; e--;) this.indicators[e].transitionTime(a) 487 } 488 } 489 }, 490 _transitionTimingFunction: function(a) { 491 this.scrollerStyle[d.style.transitionTimingFunction] = 492 a; 493 if (this.indicators) 494 for (var b = this.indicators.length; b--;) this.indicators[b].transitionTimingFunction(a) 495 }, 496 _translate: function(a, b) { 497 this.options.useTransform ? this.scrollerStyle[d.style.transform] = "translate(" + a + "px," + b + "px)" + this.translateZ : (a = f.round(a), b = f.round(b), this.scrollerStyle.left = a + "px", this.scrollerStyle.top = b + "px"); 498 this.x = a; 499 this.y = b; 500 if (this.indicators) 501 for (var c = this.indicators.length; c--;) this.indicators[c].updatePosition() 502 }, 503 _initEvents: function(a) { 504 a = a ? d.removeEvent : d.addEvent; 505 var b = 506 this.options.bindToWrapper ? this.wrapper : g; 507 a(g, "orientationchange", this); 508 a(g, "resize", this); 509 this.options.click && a(this.wrapper, "click", this, !0); 510 this.options.disableMouse || (a(this.wrapper, "mousedown", this), a(b, "mousemove", this), a(b, "mousecancel", this), a(b, "mouseup", this)); 511 d.hasPointer && !this.options.disablePointer && (a(this.wrapper, d.prefixPointerEvent("pointerdown"), this), a(b, d.prefixPointerEvent("pointermove"), this), a(b, d.prefixPointerEvent("pointercancel"), this), a(b, d.prefixPointerEvent("pointerup"), 512 this)); 513 d.hasTouch && !this.options.disableTouch && (a(this.wrapper, "touchstart", this), a(b, "touchmove", this), a(b, "touchcancel", this), a(b, "touchend", this)); 514 a(this.scroller, "transitionend", this); 515 a(this.scroller, "webkitTransitionEnd", this); 516 a(this.scroller, "oTransitionEnd", this); 517 a(this.scroller, "MSTransitionEnd", this) 518 }, 519 getComputedPosition: function() { 520 var a = g.getComputedStyle(this.scroller, null), 521 b; 522 this.options.useTransform ? (a = a[d.style.transform].split(")")[0].split(", "), b = +(a[12] || a[4]), a = +(a[13] || a[5])) : 523 (b = +a.left.replace(/[^-\d.]/g, ""), a = +a.top.replace(/[^-\d.]/g, "")); 524 return { 525 x: b, 526 y: a 527 } 528 }, 529 _initIndicators: function() { 530 function a(a) { 531 if (f.indicators) 532 for (var b = f.indicators.length; b--;) a.call(f.indicators[b]) 533 } 534 var b = this.options.interactiveScrollbars, 535 c = "string" != typeof this.options.scrollbars, 536 e = [], 537 d, f = this; 538 this.indicators = []; 539 this.options.scrollbars && (this.options.scrollY && (d = { 540 el: u("v", b, this.options.scrollbars), 541 interactive: b, 542 defaultScrollbars: !0, 543 customStyle: c, 544 resize: this.options.resizeScrollbars, 545 shrink: this.options.shrinkScrollbars, 546 fade: this.options.fadeScrollbars, 547 listenX: !1 548 }, this.wrapper.appendChild(d.el), e.push(d)), this.options.scrollX && (d = { 549 el: u("h", b, this.options.scrollbars), 550 interactive: b, 551 defaultScrollbars: !0, 552 customStyle: c, 553 resize: this.options.resizeScrollbars, 554 shrink: this.options.shrinkScrollbars, 555 fade: this.options.fadeScrollbars, 556 listenY: !1 557 }, this.wrapper.appendChild(d.el), e.push(d))); 558 this.options.indicators && (e = e.concat(this.options.indicators)); 559 for (b = e.length; b--;) this.indicators.push(new v(this, e[b])); 560 this.options.fadeScrollbars && 561 (this.on("scrollEnd", function() { 562 a(function() { 563 this.fade() 564 }) 565 }), this.on("scrollCancel", function() { 566 a(function() { 567 this.fade() 568 }) 569 }), this.on("scrollStart", function() { 570 a(function() { 571 this.fade(1) 572 }) 573 }), this.on("beforeScrollStart", function() { 574 a(function() { 575 this.fade(1, !0) 576 }) 577 })); 578 this.on("refresh", function() { 579 a(function() { 580 this.refresh() 581 }) 582 }); 583 this.on("destroy", function() { 584 a(function() { 585 this.destroy() 586 }); 587 delete this.indicators 588 }) 589 }, 590 _initWheel: function() { 591 d.addEvent(this.wrapper, "wheel", this); 592 d.addEvent(this.wrapper, "mousewheel", 593 this); 594 d.addEvent(this.wrapper, "DOMMouseScroll", this); 595 this.on("destroy", function() { 596 clearTimeout(this.wheelTimeout); 597 this.wheelTimeout = null; 598 d.removeEvent(this.wrapper, "wheel", this); 599 d.removeEvent(this.wrapper, "mousewheel", this); 600 d.removeEvent(this.wrapper, "DOMMouseScroll", this) 601 }) 602 }, 603 _wheel: function(a) { 604 if (this.enabled) { 605 var b, c, e, d = this; 606 void 0 === this.wheelTimeout && d._execEvent("scrollStart"); 607 clearTimeout(this.wheelTimeout); 608 this.wheelTimeout = setTimeout(function() { 609 d.options.snap || d._execEvent("scrollEnd"); 610 d.wheelTimeout = 611 void 0 612 }, 400); 613 if ("deltaX" in a) 1 === a.deltaMode ? (b = -a.deltaX * this.options.mouseWheelSpeed, a = -a.deltaY * this.options.mouseWheelSpeed) : (b = -a.deltaX, a = -a.deltaY); 614 else if ("wheelDeltaX" in a) b = a.wheelDeltaX / 120 * this.options.mouseWheelSpeed, a = a.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 615 else if ("wheelDelta" in a) b = a = a.wheelDelta / 120 * this.options.mouseWheelSpeed; 616 else if ("detail" in a) b = a = -a.detail / 3 * this.options.mouseWheelSpeed; 617 else return; 618 b *= this.options.invertWheelDirection; 619 a *= this.options.invertWheelDirection; 620 this.hasVerticalScroll || (b = a, a = 0); 621 this.options.snap ? (c = this.currentPage.pageX, e = this.currentPage.pageY, 0 < b ? c-- : 0 > b && c++, 0 < a ? e-- : 0 > a && e++, this.goToPage(c, e)) : (c = this.x + f.round(this.hasHorizontalScroll ? b : 0), e = this.y + f.round(this.hasVerticalScroll ? a : 0), this.directionX = 0 < b ? -1 : 0 > b ? 1 : 0, this.directionY = 0 < a ? -1 : 0 > a ? 1 : 0, 0 < c ? c = 0 : c < this.maxScrollX && (c = this.maxScrollX), 0 < e ? e = 0 : e < this.maxScrollY && (e = this.maxScrollY), this.scrollTo(c, e, 0)) 622 } 623 }, 624 _initSnap: function() { 625 this.currentPage = {}; 626 "string" == typeof this.options.snap && 627 (this.options.snap = this.scroller.querySelectorAll(this.options.snap)); 628 this.on("refresh", function() { 629 var a = 0, 630 b, c = 0, 631 e, d, g, n = 0, 632 l;
633 e = this.options.snapStepX || this.wrapperWidth; 634 var m = this.options.snapStepY || this.wrapperHeight; 635 this.pages = []; 636 if (this.wrapperWidth && this.wrapperHeight && this.scrollerWidth && this.scrollerHeight) { 637 if (!0 === this.options.snap) 638 for (d = f.round(e / 2), g = f.round(m / 2); n > -this.scrollerWidth;) { 639 this.pages[a] = []; 640 for (l = b = 0; l > -this.scrollerHeight;) this.pages[a][b] = { 641 x: f.max(n, this.maxScrollX), 642 y: f.max(l, 643 this.maxScrollY), 644 width: e, 645 height: m, 646 cx: n - d, 647 cy: l - g 648 }, l -= m, b++; 649 n -= e; 650 a++ 651 } else 652 for (m = this.options.snap, b = m.length, e = -1; a < b; a++) { 653 if (0 === a || m[a].offsetLeft <= m[a - 1].offsetLeft) c = 0, e++; 654 this.pages[c] || (this.pages[c] = []); 655 n = f.max(-m[a].offsetLeft, this.maxScrollX); 656 l = f.max(-m[a].offsetTop, this.maxScrollY); 657 d = n - f.round(m[a].offsetWidth / 2); 658 g = l - f.round(m[a].offsetHeight / 2); 659 this.pages[c][e] = { 660 x: n, 661 y: l, 662 width: m[a].offsetWidth, 663 height: m[a].offsetHeight, 664 cx: d, 665 cy: g 666 }; 667 n > this.maxScrollX && c++ 668 } 669 this.goToPage(this.currentPage.pageX || 670 0, this.currentPage.pageY || 0, 0); 671 0 === this.options.snapThreshold % 1 ? this.snapThresholdY = this.snapThresholdX = this.options.snapThreshold : (this.snapThresholdX = f.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold), this.snapThresholdY = f.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold)) 672 } 673 }); 674 this.on("flick", function() { 675 var a = this.options.snapSpeed || f.max(f.max(f.min(f.abs(this.x - this.startX), 1E3), f.min(f.abs(this.y - 676 this.startY), 1E3)), 300); 677 this.goToPage(this.currentPage.pageX + this.directionX, this.currentPage.pageY + this.directionY, a) 678 }) 679 }, 680 _nearestSnap: function(a, b) { 681 if (!this.pages.length) return { 682 x: 0, 683 y: 0, 684 pageX: 0, 685 pageY: 0 686 }; 687 var c = 0, 688 e = this.pages.length, 689 d = 0; 690 if (f.abs(a - this.absStartX) < this.snapThresholdX && f.abs(b - this.absStartY) < this.snapThresholdY) return this.currentPage; 691 0 < a ? a = 0 : a < this.maxScrollX && (a = this.maxScrollX); 692 0 < b ? b = 0 : b < this.maxScrollY && (b = this.maxScrollY); 693 for (; c < e; c++) 694 if (a >= this.pages[c][0].cx) { 695 a = this.pages[c][0].x; 696 break 697 } for (e = this.pages[c].length; d < e; d++) 698 if (b >= this.pages[0][d].cy) { 699 b = this.pages[0][d].y; 700 break 701 } c == this.currentPage.pageX && (c += this.directionX, 0 > c ? c = 0 : c >= this.pages.length && (c = this.pages.length - 1), a = this.pages[c][0].x); 702 d == this.currentPage.pageY && (d += this.directionY, 0 > d ? d = 0 : d >= this.pages[0].length && (d = this.pages[0].length - 1), b = this.pages[0][d].y); 703 return { 704 x: a, 705 y: b, 706 pageX: c, 707 pageY: d 708 } 709 }, 710 goToPage: function(a, b, c, d) { 711 d = d || this.options.bounceEasing; 712 a >= this.pages.length ? a = this.pages.length - 1 : 0 > a && (a = 0); 713 b >= this.pages[a].length ? 714 b = this.pages[a].length - 1 : 0 > b && (b = 0); 715 var g = this.pages[a][b].x, 716 h = this.pages[a][b].y; 717 c = void 0 === c ? this.options.snapSpeed || f.max(f.max(f.min(f.abs(g - this.x), 1E3), f.min(f.abs(h - this.y), 1E3)), 300) : c; 718 this.currentPage = { 719 x: g, 720 y: h, 721 pageX: a, 722 pageY: b 723 }; 724 this.scrollTo(g, h, c, d) 725 }, 726 next: function(a, b) { 727 var c = this.currentPage.pageX, 728 d = this.currentPage.pageY; 729 c++; 730 c >= this.pages.length && this.hasVerticalScroll && (c = 0, d++); 731 this.goToPage(c, d, a, b) 732 }, 733 prev: function(a, b) { 734 var c = this.currentPage.pageX, 735 d = this.currentPage.pageY; 736 c--; 737 0 > c && this.hasVerticalScroll && 738 (c = 0, d--); 739 this.goToPage(c, d, a, b) 740 }, 741 _initKeys: function(a) { 742 a = { 743 pageUp: 33, 744 pageDown: 34, 745 end: 35, 746 home: 36, 747 left: 37, 748 up: 38, 749 right: 39, 750 down: 40 751 }; 752 var b; 753 if ("object" == typeof this.options.keyBindings) 754 for (b in this.options.keyBindings) "string" == typeof this.options.keyBindings[b] && (this.options.keyBindings[b] = this.options.keyBindings[b].toUpperCase().charCo
754deAt(0)); 755 else this.options.keyBindings = {}; 756 for (b in a) this.options.keyBindings[b] = this.options.keyBindings[b] || a[b]; 757 d.addEvent(g, "keydown", this); 758 this.on("destroy", function() { 759 d.removeEvent(g, 760 "keydown", this) 761 }) 762 }, 763 _key: function(a) { 764 if (this.enabled) { 765 var b = this.options.snap, 766 c = b ? this.currentPage.pageX : this.x, 767 e = b ? this.currentPage.pageY : this.y, 768 g = d.getTime(), 769 h = this.keyTime || 0, 770 n; 771 this.options.useTransition && this.isInTransition && (n = this.getComputedPosition(), this._translate(f.round(n.x), f.round(n.y)), this.isInTransition = !1); 772 this.keyAcceleration = 200 > g - h ? f.min(this.keyAcceleration + .25, 50) : 0; 773 switch (a.keyCode) { 774 case this.options.keyBindings.pageUp: 775 this.hasHorizontalScroll && !this.hasVerticalScroll ? c += b ? 776 1 : this.wrapperWidth : e += b ? 1 : this.wrapperHeight; 777 break; 778 case this.options.keyBindings.pageDown: 779 this.hasHorizontalScroll && !this.hasVerticalScroll ? c -= b ? 1 : this.wrapperWidth : e -= b ? 1 : this.wrapperHeight; 780 break; 781 case this.options.keyBindings.end: 782 c = b ? this.pages.length - 1 : this.maxScrollX; 783 e = b ? this.pages[0].length - 1 : this.maxScrollY; 784 break; 785 case this.options.keyBindings.home: 786 e = c = 0; 787 break; 788 case this.options.keyBindings.left: 789 c += b ? -1 : 5 + this.keyAcceleration >> 0; 790 break; 791 case this.options.keyBindings.up: 792 e += b ? 1 : 5 + this.keyAcceleration >> 793 0; 794 break; 795 case this.options.keyBindings.right: 796 c -= b ? -1 : 5 + this.keyAcceleration >> 0; 797 break; 798 case this.options.keyBindings.down: 799 e -= b ? 1 : 5 + this.keyAcceleration >> 0; 800 break; 801 default: 802 return 803 } 804 b ? this.goToPage(c, e) : (0 < c ? this.keyAcceleration = c = 0 : c < this.maxScrollX && (c = this.maxScrollX, this.keyAcceleration = 0), 0 < e ? this.keyAcceleration = e = 0 : e < this.maxScrollY && (e = this.maxScrollY, this.keyAcceleration = 0), this.scrollTo(c, e, 0), this.keyTime = g) 805 } 806 }, 807 _animate: function(a, b, c, e) { 808 function f() { 809 var r = d.getTime(), 810 p; 811 r >= q ? (g.isAnimating = !1, g._translate(a, 812 b), g.resetPosition(g.options.bounceTime) || g._execEvent("scrollEnd")) : (r = (r - m) / c, p = e(r), r = (a - n) * p + n, p = (b - l) * p + l, g._translate(r, p), g.isAnimating && t(f)) 813 } 814 var g = this, 815 n = this.x, 816 l = this.y, 817 m = d.getTime(), 818 q = m + c; 819 this.isAnimating = !0; 820 f() 821 }, 822 handleEvent: function(a) { 823 switch (a.type) { 824 case "touchstart": 825 case "pointerdown": 826 case "MSPointerDown": 827 case "mousedown": 828 this._start(a); 829 break; 830 case "touchmove": 831 case "pointermove": 832 case "MSPointerMove": 833 case "mousemove": 834 this._move(a); 835 break; 836 case "touchend": 837 case "pointerup": 838 case "MSPointerUp": 839 case "mouseup": 840 case "touchcancel": 841 case "pointercancel": 842 case "MSPointerCancel": 843 case "mousecancel": 844 this._end(a); 845 break; 846 case "orientationchange": 847 case "resize": 848 this._resize(); 849 break; 850 case "transitionend": 851 case "webkitTransitionEnd": 852 case "oTransitionEnd": 853 case "MSTransitionEnd": 854 this._transitionEnd(a); 855 break; 856 case "wheel": 857 case "DOMMouseScroll": 858 case "mousewheel": 859 this._wheel(a); 860 break; 861 case "keydown": 862 this._key(a); 863 break; 864 case "click": 865 this.enabled && !a._constructed && (a.preventDefault(), a.stopPropagation()) 866 } 867 } 868 }; 869 v.prototype = { 870 handleEvent: function(a) { 871 switch (a.type) { 872 case "touchstart": 873 case "pointerdown": 874 case "MSPointerDown": 875 case "mousedown": 876 this._start(a); 877 break; 878 case "touchmove": 879 case "pointermove": 880 case "MSPointerMove": 881 case "mousemove": 882 this._move(a); 883 break; 884 case "touchend": 885 case "pointerup": 886 case "MSPointerUp": 887 case "mouseup": 888 case "touchcancel": 889 case "pointercancel": 890 case "MSPointerCancel": 891 case "mousecancel": 892 this._end(a) 893 } 894 }, 895 destroy: function() { 896 this.options.fadeScrollbars && (clearTimeout(this.fadeTimeout), this.fadeTimeout = null); 897 this.options.interactive && (d.removeEvent(this.indicator, "touchstart", this), d.removeEvent(this.indicator, d.prefixPointerEvent("pointerdown"), 898 this), d.removeEvent(this.indicator, "mousedown", this), d.removeEvent(g, "touchmove", this), d.removeEvent(g, d.prefixPointerEvent("pointermove"), this), d.removeEvent(g, "mousemove", this), d.removeEvent(g, "touchend", this), d.removeEvent(g, d.prefixPointerEvent("pointerup"), this), d.removeEvent(g, "mouseup", this)); 899 this.options.defaultScrollbars && this.wrapper.parentNode.removeChild(this.wrapper) 900 }, 901 _start: function(a) { 902 var b = a.touches ? a.touches[0] : a; 903 a.preventDefault(); 904 a.stopPropagation(); 905 this.transitionTime(); 906 this.initiated = !0; 907 this.moved = !1; 908 this.lastPointX = b.pageX; 909 this.lastPointY = b.pageY; 910 this.startTime = d.getTime(); 911 this.options.disableTouch || d.addEvent(g, "touchmove", this); 912 this.options.disablePointer || d.addEvent(g, d.prefixPointerEvent("pointermove"), this); 913 this.options.disableMouse || d.addEvent(g, "mousemove", this); 914 this.scroller._execEvent("beforeScrollStart") 915 }, 916 _move: function(a) { 917 var b = a.touches ? a.touches[0] : a, 918 c, e; 919 d.getTime(); 920 this.moved || this.scroller._execEvent("scrollStart"); 921 this.moved = !0; 922 c = b.pageX - this.lastPointX; 923 this.lastPointX = 924 b.pageX; 925 e = b.pageY - this.lastPointY; 926 this.lastPointY = b.pageY; 927 this._pos(this.x + c, this.y + e); 928 a.preventDefault(); 929 a.stopPropagation() 930 }, 931 _end: function(a) { 932 if (this.initiated) { 933 this.initiated = !1; 934 a.preventDefault(); 935 a.stopPropagation(); 936 d.removeEvent(g, "touchmove", this); 937 d.removeEvent(g, d.prefixPointerEvent("pointermove"), this); 938 d.removeEvent(g, "mousemove", this); 939 if (this.scroller.options.snap) { 940 a = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 941 var b = this.options.snapSpeed || f.max(f.max(f.min(f.abs(this.scroller.x - 942 a.x), 1E3), f.min(f.abs(this.scroller.y - a.y), 1E3)), 300); 943 if (this.scroller.x != a.x || this.scroller.y != a.y) this.scroller.directionX = 0, this.scroller.directionY = 0, this.scroller.currentPage = a, this.scroller.scrollTo(a.x, a.y, b, this.scroller.options.bounceEasing) 944 } 945 this.moved && this.scroller._execEvent("scrollEnd") 946 } 947 }, 948 transitionTime: function(a) { 949 a = a || 0; 950 var b = d.style.transitionDuration; 951 if (b && (this.indicatorStyle[b] = a + "ms", !a && d.isBadAndroid)) { 952 this.indicatorStyle[b] = "0.0001ms"; 953 var c = this; 954 t(function() { 955 "0.0001ms" === c.indicatorStyle[b] && 956 (c.indicatorStyle[b] = "0s") 957 }) 958 } 959 }, 960 transitionTimingFunction: function(a) { 961 this.indicatorStyle[d.style.transitionTimingFunction] = a 962 }, 963 refresh: function() { 964 this.transitionTime(); 965 this.indicatorStyle.display = this.options.listenX && !this.options.listenY ? this.scroller.hasHorizontalScroll ? "block" : "none" : this.options.listenY && !this.options.listenX ? this.scroller.hasVerticalScroll ? "block" : "none" : this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? "block" : "none"; 966 this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ? 967 (d.addClass(this.wrapper, "iScrollBothScrollbars"), d.removeClass(this.wrapper, "iScrollLoneScrollbar"), this.options.defaultScrollbars && this.options.customStyle && (this.options.listenX ? this.wrapper.style.right = "8px" : this.wrapper.style.bottom = "8px")) : (d.removeClass(this.wrapper, "iScrollBothScrollbars"), d.addClass(this.wrapper, "iScrollLoneScrollbar"), this.options.defaultScrollbars && this.options.customStyle && (this.options.listenX ? this.wrapper.style.right = "2px" : this.wrapper.style.bottom = "2px")); 968 this.options.listenX &&
969 (this.wrapperWidth = this.wrapper.clientWidth, this.options.resize ? (this.indicatorWidth = f.max(f.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8), this.indicatorStyle.width = this.indicatorWidth + "px") : this.indicatorWidth = this.indicator.clientWidth, this.maxPosX = this.wrapperWidth - this.indicatorWidth, "clip" == this.options.shrink ? (this.minBoundaryX = -this.indicatorWidth + 8, this.maxBoundaryX = this.wrapperWidth - 8) : (this.minBoundaryX = 0, this.maxBoundaryX = this.maxPosX), 970 this.sizeRatioX = this.options.speedRatioX || this.scroller.maxScrollX && this.maxPosX / this.scroller.maxScrollX); 971 this.options.listenY && (this.wrapperHeight = this.wrapper.clientHeight, this.options.resize ? (this.indicatorHeight = f.max(f.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8), this.indicatorStyle.height = this.indicatorHeight + "px") : this.indicatorHeight = this.indicator.clientHeight, this.maxPosY = this.wrapperHeight - this.indicatorHeight, "clip" == this.options.shrink ? 972 (this.minBoundaryY = -this.indicatorHeight + 8, this.maxBoundaryY = this.wrapperHeight - 8) : (this.minBoundaryY = 0, this.maxBoundaryY = this.maxPosY), this.maxPosY = this.wrapperHeight - this.indicatorHeight, this.sizeRatioY = this.options.speedRatioY || this.scroller.maxScrollY && this.maxPosY / this.scroller.maxScrollY); 973 this.updatePosition() 974 }, 975 updatePosition: function() { 976 var a = this.options.listenX && f.round(this.sizeRatioX * this.scroller.x) || 0, 977 b = this.options.listenY && f.round(this.sizeRatioY * this.scroller.y) || 0; 978 this.options.ignoreBoundaries || 979 (a < this.minBoundaryX ? ("scale" == this.options.shrink && (this.width = f.max(this.indicatorWidth + a, 8), this.indicatorStyle.width = this.width + "px"), a = this.minBoundaryX) : a > this.maxBoundaryX ? "scale" == this.options.shrink ? (this.width = f.max(this.indicatorWidth - (a - this.maxPosX), 8), this.indicatorStyle.width = this.width + "px", a = this.maxPosX + this.indicatorWidth - this.width) : a = this.maxBoundaryX : "scale" == this.options.shrink && this.width != this.indicatorWidth && (this.width = this.indicatorWidth, this.indicatorStyle.width = this.width + 980 "px"), b < this.minBoundaryY ? ("scale" == this.options.shrink && (this.height = f.max(this.indicatorHeight + 3 * b, 8), this.indicatorStyle.height = this.height + "px"), b = this.minBoundaryY) : b > this.maxBoundaryY ? "scale" == this.options.shrink ? (this.height = f.max(this.indicatorHeight - 3 * (b - this.maxPosY), 8), this.indicatorStyle.height = this.height + "px", b = this.maxPosY + this.indicatorHeight - this.height) : b = this.maxBoundaryY : "scale" == this.options.shrink && this.height != this.indicatorHeight && (this.height = this.indicatorHeight, this.indicatorStyle.height = 981 this.height + "px")); 982 this.x = a; 983 this.y = b; 984 this.scroller.options.useTransform ? this.indicatorStyle[d.style.transform] = "translate(" + a + "px," + b + "px)" + this.scroller.translateZ : (this.indicatorStyle.left = a + "px", this.indicatorStyle.top = b + "px") 985 }, 986 _pos: function(a, b) { 987 0 > a ? a = 0 : a > this.maxPosX && (a = this.maxPosX); 988 0 > b ? b = 0 : b > this.maxPosY && (b = this.maxPosY); 989 a = this.options.listenX ? f.round(a / this.sizeRatioX) : this.scroller.x; 990 b = this.options.listenY ? f.round(b / this.sizeRatioY) : this.scroller.y; 991 this.scroller.scrollTo(a, b) 992 }, 993 fade: function(a, 994 b) { 995 if (!b || this.visible) { 996 clearTimeout(this.fadeTimeout); 997 this.fadeTimeout = null; 998 var c = a ? 0 : 300; 999 this.wrapperStyle[d.style.transitionDuration] = (a ? 250 : 500) + "ms"; 1000 this.fadeTimeout = setTimeout(function(a) { 1001 this.wrapperStyle.opacity = a; 1002 this.visible = +a 1003 }.bind(this, a ? "1" : "0"), c) 1004 } 1005 } 1006 }; 1007 p.utils = d; 1008 "undefined" != typeof module && module.exports ? module.exports = p : "function" == typeof define && define.amd ? define(function() { 1009 return p 1010 }) : g.IScroll = p 1011})(window, document, Math); 1012 1013 1014 1015 1016 1017 1018/*! 1019 * fullPage 2.8.1 1020 * https://github.com/alvarotrigo/fullPage.js 1021 * @license MIT licensed 1022 * 1023 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 1024 */ 1025(function(global, factory) { 1026 'use strict'; 1027 if (typeof define === 'function' && define.amd) { 1028 define(['jquery'], function($) { 1029 return factory($, global, global.document, global.Math); 1030 }); 1031 } else if (typeof exports !== 'undefined') { 1032 module.exports = factory(require('jquery'), global, global.document, global.Math); 1033 } else { 1034 factory(jQuery, global, global.document, global.Math); 1035 } 1036})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 1037 'use strict'; 1038 1039 // keeping central set of classnames and selectors 1040 var WRAPPER = 'fullpage-wrapper'; 1041 var WRAPPER_SEL = '.' + WRAPPER; 1042 1043 // slimscroll 1044 var SCROLLABLE = 'fp-scrollable'; 1045 var SCROLLABLE_SEL = '.' + SCROLLABLE; 1046 1047 // util 1048 var RESPONSIVE = 'fp-responsive'; 1049 var NO_TRANSITION = 'fp-notransition'; 1050 var DESTROYED = 'fp-destroyed'; 1051 var ENABLED = 'fp-enabled'; 1052 var VIEWING_PREFIX = 'fp-viewing'; 1053 var ACTIVE = 'active'; 1054 var ACTIVE_SEL = '.' + ACTIVE; 1055 var COMPLETELY = 'fp-completely'; 1056 var COMPLETELY_SEL = '.' + COMPLETELY; 1057 1058 // section 1059 var SECTION_DEFAULT_SEL = '.section'; 1060 var SECTION = 'fp-section'; 1061 var SECTION_SEL = '.' + SECTION; 1062 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 1063 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 1064 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 1065 var TABLE_CELL = 'fp-tableCell'; 1066 var TABLE_CELL_SEL = '.' + TABLE_CELL; 1067 var AUTO_HEIGHT = 'fp-auto-height'; 1068 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 1069 var NORMAL_SCROLL = 'fp-normal-scroll'; 1070 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 1071 1072 // section nav 1073 var SECTION_NAV = 'fp-nav'; 1074 var SECTION_NAV_SEL = '#' + SECTION_NAV; 1075 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 1076 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 1077 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 1078 1079 // slide 1080 var SLIDE_DEFAULT_SEL = '.slide';
1081 var SLIDE = 'fp-slide'; 1082 var SLIDE_SEL = '.' + SLIDE; 1083 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 1084 var SLIDES_WRAPPER = 'fp-slides'; 1085 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 1086 var SLIDES_CONTAINER = 'fp-slidesContainer'; 1087 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 1088 var TABLE = 'fp-table'; 1089 1090 // slide nav 1091 var SLIDES_NAV = 'fp-slidesNav'; 1092 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 1093 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 1094 var SLIDES_ARROW = 'fp-controlArrow'; 1095 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 1096 var SLIDES_PREV = 'fp-prev'; 1097 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 1098 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 1099 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 1100 var SLIDES_NEXT = 'fp-next'; 1101 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 1102 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 1103 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 1104 1105 /* nectar addition */ 1106 var HASHCHANGE = false; 1107 var HASHCHANGETIMEOUT; 1108 /* nectar addition end */ 1109 1110 var $window = $(window); 1111 var $document = $(document); 1112 1113 // Default options for iScroll.js used when using scrollOverflow 1114 1115 /* nectar addition */ 1116 //changing click param depending on mobile device 1117 if('ontouchstart' in document.documentElement) { 1118 var iscrollOptions = { 1119 scrollbars: true, 1120 mouseWheel: true, 1121 hideScrollbars: false, 1122 disableMouse: true, 1123 useTransition: true, 1124 interactiveScrollbars: true, 1125 click: true 1126 }; 1127 } else { 1128 var iscrollOptions = { 1129 scrollbars: true, 1130 mouseWheel: true, 1131 hideScrollbars: false, 1132 disableMouse: true, 1133 useTransition: true, 1134 interactiveScrollbars: true, 1135 click: false 1136 }; 1137 } 1138 1139 if($('.nectar_using_pfsr.nectar_pfsr_compose_mode:not(.using-mobile-browser)').length > 0) { 1140 1141 var iscrollOptions = { 1142 scrollbars: true, 1143 mouseWheel: false, 1144 hideScrollbars: false, 1145 useTransition: true, 1146 interactiveScrollbars: true, 1147 disableMouse: true, 1148 disableTouch: true, 1149 disablePointer: false, 1150 click: false 1151 }; 1152 } 1153 1154 // allow text selection. 1155 if ( $('body').find('.allow-text-selection').length > 0 ) { 1156 iscrollOptions.preventDefault = false;
1157 } 1158 1159 1160 1161 $.fn.fullpage = function(options) { 1162 //only once my friend! 1163 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 1164 1165 1166 1167 // common jQuery objects 1168 var $htmlBody = $('html, body'); 1169 var $body = $('body'); 1170 1171 var FP = $.fn.fullpage; 1172 1173 // Create some defaults, extending them with any options that were provided 1174 options = $.extend({ 1175 //navigation 1176 menu: false, 1177 anchors:[], 1178 lockAnchors: false, 1179 navigation: false, 1180 navigationPosition: 'right', 1181 navigationTooltips: [], 1182 showActiveTooltip: false, 1183 slidesNavigation: false, 1184 slidesNavPosition: 'bottom', 1185 scrollBar: false, 1186 hybrid: false, 1187 1188 //scrolling 1189 css3: true, 1190 scrollingSpeed: 700, 1191 autoScrolling: true, 1192 fitToSection: true, 1193 fitToSectionDelay: 1000, 1194 easing: 'easeInOutCubic', 1195 easingcss3: 'ease', 1196 loopBottom: false, 1197 loopTop: false, 1198 loopHorizontal: true, 1199 continuousVertical: false, 1200 normalScrollElements: null, 1201 scrollOverflow: false, 1202 scrollOverflowHandler: iscrollHandler, 1203 scrollOverflowOptions: null, 1204 touchSensitivity: 5, 1205 normalScrollElementTouchThreshold: 5, 1206 1207 //Accessibility 1208 keyboardScrolling: true, 1209 animateAnchor: true, 1210 recordHistory: true, 1211 1212 //design 1213 controlArrows: true, 1214 controlArrowColor: '#fff', 1215 verticalCentered: true, 1216 sectionsColor : [], 1217 paddingTop: 0, 1218 paddingBottom: 0, 1219 fixedElements: null, 1220 responsive: 0, //backwards compabitility with responsiveWiddth 1221 responsiveWidth: 0, 1222 responsiveHeight: 0, 1223 1224 //Custom selectors 1225 sectionSelector: SECTION_DEFAULT_SEL, 1226 slideSelector: SLIDE_DEFAULT_SEL, 1227 1228 1229 //events 1230 afterLoad: null, 1231 onLeave: null, 1232 afterRender: null, 1233 afterResize: null, 1234 afterReBuild: null, 1235 afterSlideLoad: null, 1236 onSlideLeave: null 1237 }, options); 1238 1239 displayWarnings(); 1240 1241 //extending iScroll options with the user custom ones 1242 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 1243 1244 //easeInOutCubic animation included in the plugin 1245 $.extend($.easing,{ easeInOutCubic: function (x, t, b, c, d) {if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;}}); 1246 1247 /** 1248 * Sets the autoScroll option. 1249 * It changes the scroll bar visibility and the history of the site as a result. 1250 */ 1251 FP.setAutoScrolling = function(value, type){ 1252 setVariableState('autoScrolling', value, type); 1253 1254 var element = $(SECTION_ACTIVE_SEL); 1255 1256 if(options.autoScrolling && !options.scrollBar){ 1257 $htmlBody.css({ 1258 'overflow' : 'hidden', 1259 'height' : '100%' 1260 }); 1261 1262 FP.setRecordHistory(originals.recordHistory, 'internal'); 1263 1264 //for IE touch devices 1265 container.css({ 1266 '-ms-touch-action': 'none', 1267 'touch-action': 'none' 1268 }); 1269 1270 if(element.length){ 1271 //moving the container up 1272 silentScroll(element.position().top); 1273 } 1274 1275 }else{ 1276 $htmlBody.css({ 1277 'overflow' : 'visible', 1278 'height' : 'initial' 1279 }); 1280 1281 FP.setRecordHistory(false, 'internal'); 1282 1283 //for IE touch devices 1284 container.css({ 1285 '-ms-touch-action': '', 1286 'touch-action': '' 1287 }); 1288 1289 silentScroll(0); 1290 1291 //scrolling the page to the section with no animation 1292 if (element.length) { 1293 1294 $htmlBody.scrollTop(element.position().top); 1295 } 1296 } 1297 }; 1298 1299 /** 1300 * Defines wheter to record the history for each hash change in the URL. 1301 */ 1302 FP.setRecordHistory = function(value, type){ 1303 setVariableState('recordHistory', value, type); 1304 }; 1305 1306 /** 1307 * Defines the scrolling speed 1308 */ 1309 FP.setScrollingSpeed = function(value, type){ 1310 setVariableState('scrollingSpeed', value, type); 1311 }; 1312 1313 /** 1314 * Sets fitToSection 1315 */ 1316 FP.setFitToSection = function(value, type){ 1317 setVariableState('fitToSection', value, type); 1318 }; 1319 1320 /** 1321 * Sets lockAnchors 1322 */ 1323 FP.setLockAnchors = function(value){ 1324 options.lockAnchors = value; 1325 }; 1326 1327 /** 1328 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 1329 */ 1330 FP.setMouseWheelScrolling = function (value){ 1331 if(value){ 1332 addMouseWheelHandler(); 1333 addMiddleWheelHandler(); 1334 }else{ 1335 removeMouseWheelHandler(); 1336 removeMiddleWheelHandler(); 1337 } 1338 }; 1339 1340 /** 1341 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 1342 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 1343 * 1344 * @param directions string containing the direction or directions separated by comma. 1345 */ 1346 FP.setAllowScrolling = function (value, directions){ 1347 if(typeof directions !== 'undefined'){ 1348 directions = directions.replace(/ /g,'').split(','); 1349 1350 $.each(directions, function (index, direction){ 1351 setIsScrollAllowed(value, direction, 'm'); 1352 }); 1353 } 1354 else if(value){ 1355 FP.setMouseWheelScrolling(true); 1356 addTouchHandler(); 1357 }else{ 1358 FP.setMouseWheelScrolling(false); 1359 removeTouchHandler(); 1360 } 1361 }; 1362 1363 /** 1364 * Adds or remove the possiblity of scrolling through sections by using the keyboard arrow keys 1365 */ 1366 FP.setKeyboardScrolling = function (value, directions){ 1367 if(typeof directions !== 'undefined'){ 1368 directions = directions.replace(/ /g,'').split(','); 1369 1370 $.each(directions, function (index, direction){ 1371 setIsScrollAllowed(value, direction, 'k'); 1372 }); 1373 }else{ 1374 options.keyboardScrolling = value; 1375 } 1376 }; 1377 1378 /** 1379 * Moves the page up one section. 1380 */ 1381 FP.moveSectionUp = function(){ 1382 1383 /* nectar addition */ 1384 if(canScroll == false) return false;
1385 1386 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 1387 1388 //looping to the bottom if there's no more sections above 1389 if (!prev.length && (options.loopTop || options.continuousVertical)) { 1390 prev = $(SECTION_SEL).last(); 1391 } 1392 1393 if (prev.length) { 1394 scrollPage(prev, null, true); 1395 } 1396 }; 1397 1398 /** 1399 * Moves the page down one section. 1400 */ 1401 FP.moveSectionDown = function (){ 1402 1403 /* nectar addition */ 1404 if(canScroll == false) return false; 1405 1406 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 1407 1408 //looping to the top if there's no more sections below 1409 if(!next.length && 1410 (options.loopBottom || options.continuousVertical)){ 1411 next = $(SECTION_SEL).first(); 1412 } 1413 1414 if(next.length){ 1415 scrollPage(next, null, false); 1416 } 1417 }; 1418 1419 /** 1420 * Moves the page to the given section and slide with no animation. 1421 * Anchors or index positions can be used as params. 1422 */ 1423 FP.silentMoveTo = function(sectionAnchor, slideAnchor){ 1424 FP.setScrollingSpeed (0, 'internal'); 1425 FP.moveTo(sectionAnchor, slideAnchor); 1426 FP.setScrollingSpeed (originals.scrollingSpeed, 'internal'); 1427 }; 1428 1429 /** 1430 * Moves the page to the given section and slide. 1431 * Anchors or index positions can be used as params. 1432 */ 1433 FP.moveTo = function (sectionAnchor, slideAnchor){ 1434 var destiny = getSectionByAnchor(sectionAnchor); 1435 1436 if (typeof slideAnchor !== 'undefined'){ 1437 scrollPageAndSlide(sectionAnchor, slideAnchor); 1438 }else if(destiny.length > 0){ 1439 scrollPage(destiny); 1440 } 1441 }; 1442 1443 /** 1444 * Slides right the slider of the active section. 1445 * Optional `section` param. 1446 */ 1447 FP.moveSlideRight = function(section){ 1448 moveSlide('next', section); 1449 }; 1450 1451 /** 1452 * Slides left the slider of the active section. 1453 * Optional `section` param. 1454 */ 1455 FP.moveSlideLeft = function(section){ 1456 moveSlide('prev', section); 1457 }; 1458 1459 /** 1460 * When resizing is finished, we adjust the slides sizes and positions 1461 */ 1462 FP.reBuild = function(resizing){ 1463 1464 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 1465 1466 isResizing = true; 1467 1468 /* nectar addition */ 1469 var $headerNavSpace = ($('body[data-header-format="left-header"]').length > 0 && $(window).width() > 1000) ? 0 : $('#header-outer').outerHeight(); 1470 var $adminBar = ($('#wpadminbar').length > 0) ? $('#wpadminbar').height() : 0; //admin bar 1471 if(window.vc_iframe) { $adminBar = 0; } 1472 var $headerHeight = ($('#header-outer.transparent').length == 0 ) ? $headerNavSpace : 0 ; 1473 // Handle mobile secondary nav 1474 if( $('#header-outer.transparent').length > 0 && $('#header-secondary-outer[data-mobile="display_full"]').length > 0 && $(window).width() <= 1000 ) { 1475 $headerHeight += $('#header-secondary-outer').height(); 1476 } 1477 var $borderMultiplier = ($('.body-border-right').length > 0 && $('#header-outer').css('background-color') == $('.body-border-right').css('background-color')) ? 1 : 2; 1478 var $borderHeight = ($('.body-border-right').length > 0 && $(window).width()>1000) ? $('.body-border-right').width()*$borderMultiplier : 0; 1479 var windowsWidth = $window.outerWidth(); 1480 var $materialExtra = ($('body.material .ocm-effect-wrap').length > 0) ? 2 : 0; //fix for showing material ocm BG since overflow is hidden on effect wrap 1481 windowsHeight = $window.height() - $adminBar - $headerHeight - $borderHeight + $materialExtra; //updating global var 1482 1483 $(SECTION_SEL).each(function(){ 1484 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 1485 var slides = $(this).find(SLIDE_SEL); 1486 1487 //adjusting the height of the table-cell for IE and Firefox 1488 if(options.verticalCentered){ 1489 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 1490 } 1491 1492 $(this).css('height', windowsHeight + 'px'); 1493 1494 1495 //adjusting the position fo the FULL WIDTH slides... 1496 if (slides.length > 1) {
1497 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 1498 } 1499 }); 1500 1501 /* nectar addition */ 1502 if($('#nectar_fullscreen_rows[data-animation="none"]').length == 0 && 1503 $('#nectar_fullscreen_rows[data-animation="free-scroll"]').length == 0) { 1504 $('#nectar_fullscreen_rows').css('height', windowsHeight + 'px'); 1505 } 1506 1507 //middle alignment of rows when desktop scroll overflow is turned off 1508 if($('#nectar_fullscreen_rows[data-content-overflow="hidden"]').length > 0) { 1509 $('#nectar_fullscreen_rows>.vc_row.vc_row-flex:not(#footer-outer)>.fp-tableCell>.full-page-inner-wrap-outer>.full-page-inner-wrap[data-content-pos="middle"] > .full-page-inner>.container>.span_12').css('height', windowsHeight + 'px'); 1510 $('#nectar_fullscreen_rows>.vc_row.vc_row-flex:not(#footer-outer)>.fp-tableCell>.full-page-inner-wrap-outer>.full-page-inner-wrap[data-content-pos="middle"]').css('overflow', 'hidden'); 1511 } 1512 1513 var activeSection = $(SECTION_ACTIVE_SEL); 1514 var sectionIndex = activeSection.index(SECTION_SEL); 1515 1516 //isn't it the first section? 1517 if(sectionIndex){ 1518 //adjusting the position for the current section 1519 FP.silentMoveTo(sectionIndex + 1); 1520 1521 } 1522 1523 isResizing = false; 1524 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 1525 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 1526 }; 1527 1528 /** 1529 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 1530 * are smaller than the set limit values. 1531 */ 1532 FP.setResponsive = function (active){ 1533 var isResponsive = $body.hasClass(RESPONSIVE); 1534 1535 if(active){ 1536 if(!isResponsive){ 1537 FP.setAutoScrolling(false, 'internal'); 1538 FP.setFitToSection(false, 'internal'); 1539 $(SECTION_NAV_SEL).hide(); 1540 $body.addClass(RESPONSIVE); 1541 } 1542 } 1543 else if(isResponsive){ 1544 FP.setAutoScrolling(originals.autoScrolling, 'internal'); 1545 FP.setFitToSection(originals.autoScrolling, 'internal'); 1546 $(SECTION_NAV_SEL).show(); 1547 $body.removeClass(RESPONSIVE); 1548 } 1549 }; 1550 1551 //flag to avoid very fast sliding for landscape sliders 1552 var slideMoving = false; 1553 1554 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 1555 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 1556 var container = $(this); 1557 /* nectar addition */ 1558 var $headerNavSpace = ($('body[data-header-format="left-header"]').length > 0 && $(window).width() > 1000) ? 0 : $('#header-outer').outerHeight(); 1559 var $adminBar = ($('#wpadminbar').length > 0) ? $('#wpadminbar').height() : 0; //admin bar 1560 if(window.vc_iframe) { $adminBar = 0; } 1561 var $borderMultiplier = ($('.body-border-right').length > 0 && $('#header-outer').css('background-color') == $('.body-border-right').css('background-color')) ? 1 : 2; 1562 var $borderHeight = ($('.body-border-right').length > 0 && $(window).width()>1000) ? $('.body-border-right').width()*$borderMultiplier : 0; 1563 var $headerHeight = ($('#header-outer.transparent').length == 0) ? $headerNavSpace : 0 ; 1564 if( $('#header-outer.transparent').length > 0 && $('#header-secondary-outer[data-mobile="display_full"]').length > 0 && $(window).width() <= 1000 ) { 1565 $headerHeight += $('#header-secondary-outer').height(); 1566 } 1567 var $materialExtra = ($('body.material .ocm-effect-wrap').length > 0) ? 2 : 0; //fix for showing material ocm BG since overflow is hidden on effect wrap 1568 var windowsHeight = $window.height() - $adminBar - $headerHeight - $borderHeight + $materialExtra; 1569 var isResizing = false;
1570 var isWindowFocused = true; 1571 var lastScrolledDestiny; 1572 var lastScrolledSlide; 1573 var canScroll = true; 1574 var clickedNavigation = false; // Nectar addition. 1575 var scrollings = []; 1576 var nav; 1577 var controlPressed; 1578 var isScrollAllowed = {}; 1579 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 1580 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 1581 var originals = $.extend(true, {}, options); //deep copy 1582 1583 //timeouts 1584 var resizeId; 1585 var afterSectionLoadsId; 1586 var afterSlideLoadsId; 1587 var scrollId; 1588 var scrollId2; 1589 var keydownId; 1590 1591 if($(this).length){ 1592 init(); 1593 bindEvents(); 1594 } 1595 1596 function init(){ 1597 //if css3 is not supported, it will use jQuery animations 1598 if(options.css3){ 1599 options.css3 = support3d(); 1600 } 1601 1602 options.scrollBar = options.scrollBar || options.hybrid; 1603 1604 1605 setOptionsFromDOM(); 1606 1607 prepareDom(); 1608 FP.setAllowScrolling(true); 1609 1610 FP.setAutoScrolling(options.autoScrolling, 'internal'); 1611 1612 //the starting point is a slide? 1613 var activeSlide = $(SECTION_ACTIVE_SEL).find(SLIDE_ACTIVE_SEL); 1614 1615 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/slide by default. 1616 if( activeSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && activeSlide.index() !== 0))){ 1617 silentLandscapeScroll(activeSlide); 1618 } 1619 1620 responsive(); 1621 1622 //setting the class for the body element 1623 setBodyClass(); 1624 1625 if(document.readyState === 'complete'){ 1626 scrollToAnchor(); 1627 } 1628 $window.on('load', scrollToAnchor); 1629 } 1630 1631 function bindEvents(){ 1632 $window 1633 //when scrolling... 1634 .on('scroll', scrollHandler) 1635 1636 //detecting any change on the URL to scroll to the given anchor link 1637 //(a way to detect back history button as we play with the hashes on the URL) 1638 .on('hashchange', hashChangeHandler) 1639 1640 // window focus 1641 .on('focus', focusHandler) 1642 1643 //when opening a new tab (ctrl + t), `control` won't be pressed when comming back. 1644 .blur(blurHandler) 1645 1646 //when resizing the site, we adjust the heights of the sections, slimScroll... 1647 .resize(resizeHandler) 1648 /* nectar addition */ 1649 .on('smartresize', checkScrollOverflow); 1650 $(window).on( 'vc_reload',function(){ 1651 1652 var currentRowIndex = ($('.fp-table.active').length > 0) ? $('.fp-table.active').index() + 1 : 'default'; 1653 1654 $('#nectar_fullscreen_rows > div.vc_element').addClass('fp-section'); 1655 $('#nectar_fullscreen_rows > div.vc_element').each(function(){ 1656 if( $(this).find('> .wpb_row > .fp-tableCell').length == 0 ) { 1657 currentRowIndex = $(this).index() + 1; 1658 addTableClass( $(this) ); 1659 } 1660 }); 1661 1662 if(currentRowIndex != 'default') { 1663 FP.silentMoveTo(currentRowIndex); 1664 1665 //$('#fp-nav ul > li:nth-child(' + (currentRowIndex) + ')').find('> a').trigger('click'); 1666 //FP.reBuild(true); 1667 } 1668 1669 1670 }); 1671 $document 1672 //Sliding with arrow keys, both, vertical and horizontal 1673 .keydown(keydownHandler) 1674 1675 //to prevent scrolling while zooming 1676 .keyup(keyUpHandler) 1677 1678 //Scrolls to the section when clicking the navigation bullet 1679 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 1680 1681 //Scrolls the slider to the given slide destination for the given section 1682 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 1683 1684 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 1685 1686 //Scrolling horizontally when clicking on the slider controls. 1687 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 1688 1689 /** 1690 * Applying normalScroll elements. 1691 * Ignoring the scrolls over the specified selectors. 1692 */ 1693 if(options.normalScrollElements){ 1694 $document.on('mouseenter', options.normalScrollElements, function () { 1695 FP.setMouseWheelScrolling(false); 1696 }); 1697 1698 $document.on('mouseleave', options.normalScrollElements, function(){ 1699 FP.setMouseWheelScrolling(true); 1700 }); 1701 } 1702 } 1703 1704 /** 1705 * Setting options from DOM elements if they are not provided. 1706 */ 1707 function setOptionsFromDOM(){ 1708 var sections = container.find(options.sectionSelector); 1709 1710 //no anchors option? Checking for them in the DOM attributes 1711 if(!options.anchors.length){ 1712 options.anchors = sections.filter('[data-anchor]').map(function(){ 1713 return $(this).data('anchor').toString(); 1714 }).get(); 1715 } 1716 1717 //no tooltipos option? Checking for them in the DOM attributes 1718 if(!options.navigationTooltips.length){ 1719 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 1720 return $(this).data('tooltip').toString(); 1721 }).get(); 1722 } 1723 } 1724 1725 /** 1726 * Works over the DOM structure to set it up for the current fullpage optionss. 1727 */ 1728 function prepareDom(){ 1729 container.css({ 1730 'height': '100%', 1731 'position': 'relative' 1732 }); 1733 1734 //adding a class to recognize the container internally in the code 1735 container.addClass(WRAPPER); 1736 $('html').addClass(ENABLED); 1737 1738 //due to https://github.com/alvarotrigo/fullPage.js/issues/1502 1739 /* nectar addition */ 1740 var $headerNavSpace = ($('body[data-header-format="left-header"]').length > 0 && $(window).width() > 1000) ? 0 : $('#header-outer').outerHeight(); 1741 var $adminBar = ($('#wpadminbar').length > 0) ? $('#wpadminbar').height() : 0; //admin bar 1742 if(window.vc_iframe) { $adminBar = 0; } 1743 var $borderMultiplier = ($('.body-border-right').length > 0 && $('#header-outer').css('background-color') == $('.body-border-right').css('background-color')) ? 1 : 2; 1744 var $borderHeight = ($('.body-border-right').length > 0 && $(window).width()>1000) ? $('.body-border-right').width()*$borderMultiplier : 0; 1745 var $headerHeight = ($('#header-outer.transparent').length == 0 ) ? $headerNavSpace : 0 ; 1746 if( $('#header-outer.transparent').length > 0 && $('#header-secondary-outer[data-mobile="display_full"]').length > 0 && $(window).width() <= 1000 ) { 1747 $headerHeight += $('#header-secondary-outer').height(); 1748 } 1749 var $materialExtra = ($('body.material .ocm-effect-wrap').length > 0) ? 2 : 0; //fix for showing material ocm BG since overflow is hidden on effect wrap 1750 windowsHeight = $window.height() - $adminBar - $headerHeight - $borderHeight + $materialExtra; 1751 1752 container.removeClass(DESTROYED); //in case it was destroyed before initilizing it again 1753 1754 addInternalSelectors(); 1755 1756 //styling the sections / slides / menu 1757 $(SECTION_SEL).each(function(index){ 1758 var section = $(this); 1759 var slides = section.find(SLIDE_SEL); 1760 var numSlides = slides.length; 1761 1762 styleSection(section, index); 1763 styleMenu(section, index); 1764 1765 // if there's any slide 1766 if (numSlides > 0) { 1767 styleSlides(section, slides, numSlides); 1768 }else{ 1769 if(options.verticalCentered){ 1770 addTableClass(section); 1771 } 1772 } 1773 }); 1774 1775 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 1776 if(options.fixedElements && options.css3){ 1777 $(options.fixedElements).appendTo($body); 1778 } 1779 1780 //vertical centered of the navigation + active bullet 1781 if(options.navigation){ 1782 addVerticalNavigation(); 1783 } 1784 1785 enableYoutubeAPI(); 1786 enableVidemoAPI(); 1787 1788 if(options.scrollOverflow){ 1789 if(document.readyState === 'complete'){ 1790 createSlimScrollingHandler(); 1791 } 1792 //after DOM and images are loaded 1793 /* nectar addition */ 1794 afterRenderActions(); 1795 //$window.on('load', createSlimScrollingHandler); 1796 $window.on('load', function() { setTimeout(function(){ 1797 1798 $(SECTION_SEL).each(function(){ 1799 var slides = $(this).find(SLIDE_SEL); 1800 1801 if(slides.length){ 1802 slides.each(function(){ 1803 createSlimScrolling($(this)); 1804 }); 1805 }else{ 1806 createSlimScrolling($(this)); 1807 } 1808 1809 }); 1810 1811 },100); }); 1812 }else{ 1813 afterRenderActions(); 1814 } 1815 } 1816 1817 /** 1818 * Styles the horizontal slides for a section. 1819 */ 1820 function styleSlides(section, slides, numSlides){ 1821 var sliderWidth = numSlides * 100; 1822 var slideWidth = 100 / numSlides; 1823 1824 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 1825 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 1826 1827 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 1828 1829 if(numSlides > 1){ 1830 if(options.controlArrows){ 1831 createSlideArrows(section); 1832 } 1833 1834 if(options.slidesNavigation){ 1835 addSlidesNavigation(section, numSlides); 1836 } 1837 } 1838 1839 slides.each(function(index) { 1840 $(this).css('width', slideWidth + '%'); 1841 1842 if(options.verticalCentered){ 1843 addTableClass($(this)); 1844 } 1845 }); 1846 1847 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 1848 1849 //if the slide won't be an starting point, the default will be the first one 1850 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
1850ide by default. 1851 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 1852 silentLandscapeScroll(startingSlide); 1853 }else{ 1854 slides.eq(0).addClass(ACTIVE); 1855 } 1856 } 1857 1858 /** 1859 * Styling vertical sections 1860 */ 1861 function styleSection(section, index){ 1862 //if no active section is defined, the 1st one will be the default one 1863 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 1864 section.addClass(ACTIVE); 1865 } 1866 1867 section.css('height', windowsHeight + 'px'); 1868 1869 /* nectar addition */ 1870 if($('#nectar_fullscreen_rows[data-animation="none"]').length == 0 && 1871 $('#nectar_fullscreen_rows[data-animation="free-scroll"]').length == 0 ) { 1872 $('#nectar_fullscreen_rows').css('height', windowsHeight + 'px'); 1873 } 1874 if($('#nectar_fullscreen_rows[data-content-overflow="hidden"]').length > 0) $('#nectar_fullscreen_rows>.vc_row.vc_row-flex:not(#footer-outer)>.fp-tableCell>.full-page-inner-wrap-outer>.full-page-inner-wrap[data-content-pos="middle"] > .full-page-inner>.container>.span_12').css('height', windowsHeight + 'px'); 1875 1876 if(options.paddingTop){ 1877 section.css('padding-top', options.paddingTop); 1878 } 1879 1880 if(options.paddingBottom){ 1881 section.css('padding-bottom', options.paddingBottom); 1882 } 1883 1884 if (typeof options.sectionsColor[index] !== 'undefined') { 1885 section.css('background-color', options.sectionsColor[index]); 1886 } 1887 1888 if (typeof options.anchors[index] !== 'undefined') { 1889 section.attr('data-anchor', options.anchors[index]); 1890 } 1891 1892 /* nectar addition */ 1893 $(window).on('load', function(){ 1894 $(window).trigger('resize'); 1895 }); 1896 } 1897 1898 /** 1899 * Sets the data-anchor attributes to the menu elements and activates the current one. 1900 */ 1901 function styleMenu(section, index){ 1902 if (typeof options.anchors[index] !== 'undefined') { 1903 //activating the menu / nav element on load 1904 if(section.hasClass(ACTIVE)){ 1905 activateMenuAndNav(options.anchors[index], index); 1906 } 1907 } 1908 1909 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 1910 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 1911 $(options.menu).appendTo($body); 1912 } 1913 } 1914 1915 /** 1916 * Adds internal classes to be able to provide customizable selectors 1917 * keeping the link with the style sheet. 1918 */ 1919 function addInternalSelectors(){ 1920 //adding internal class names to void problem with common ones 1921 $(options.sectionSelector).each(function(){ 1922 $(this).addClass(SECTION); 1923 }); 1924 $(options.slideSelector).each(function(){ 1925 $(this).addClass(SLIDE); 1926 }); 1927 } 1928 1929 /** 1930 * Creates the control arrows for the given section 1931 */ 1932 function createSlideArrows(section){ 1933 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 1934 1935 if(options.controlArrowColor!='#fff'){ 1936 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 1937 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 1938 } 1939 1940 if(!options.loopHorizontal){ 1941 section.find(SLIDES_ARROW_PREV_SEL).hide(); 1942 } 1943 } 1944 1945 /** 1946 * Creates a vertical navigation bar. 1947 */ 1948 /* nectar addition */ 1949 function addVerticalNavigation(){ 1950 if($('#nectar_fullscreen_rows').attr('data-dot-navigation') == 'hidden') { return; } 1951 1952 if($('#boxed').length > 0) { 1953 $('#boxed').append('<div id="' + SECTION_NAV + '" class="'+$('#nectar_fullscreen_rows').attr('data-dot-navigation')+'"><ul></ul></div>'); 1954 } 1955 else { 1956 $body.append('<div id="' + SECTION_NAV + '" class="'+$('#nectar_fullscreen_rows').attr('data-dot-navigation')+'"><ul></ul></div>'); 1957 } 1958 1959 var nav = $(SECTION_NAV_SEL); 1960 1961 nav.addClass(function() { 1962 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 1963 }); 1964 1965 for (var i = 0; i < $(SECTION_SEL).length; i++) { 1966 1967 var link = ''; 1968 if (options.anchors.length) { 1969 link = options.anchors[i]; 1970 } 1971 1972 var li = '<li><a href="#' + link + '"><span></span></a>'; 1973 1974 // Only add tooltip if needed (defined by user) 1975 var tooltip = options.navigationTooltips[i]; 1976 1977 if (typeof tooltip !== 'undefined' && tooltip !== '') { 1978 1979 if(tooltip.length == 1) { 1980 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '"></div>'; 1981 } 1982 else { 1983 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '"><div class="tooltip-inner"><span>' + tooltip + '</span></div></div>'; 1984 } 1985 } 1986 1987 li += '</li>'; 1988 1989 nav.find('ul').append(li); 1990 } 1991 1992 /*nectar addition - front end editor create new section control */ 1993 if(window.vc_iframe) { 1994 var $addnewElClone = $('#nectar_fullscreen_rows > #vc_no-content-helper').clone(); 1995 setTimeout(function(){ 1996 if ( $addnewElClone.length > 0 ) { 1997 $('#fp-nav ul').append('<li class="vc_add_new_row"><a href="#">
1997' + $addnewElClone.find('#vc_not-empty-add-element').html() + '</a> <div class="fp-tooltip right"><div class="tooltip-inner"><span>Add New Section</span></div></div> </li>'); 1998 } 1999 },300); 2000 2001 $('body').off('click.vc_fp_new_section_rel'); 2002 $('body').on('click.vc_fp_new_section_rel','#fp-nav ul .vc-c-icon-add',function(e) { 2003 $('#nectar_fullscreen_rows > #vc_no-content-helper #vc_not-empty-add-element .vc-c-icon-add').trigger('click'); 2004 e.preventDefault(); 2005 return false; 2006 }); 2007 } 2008 /*nectar addition end */ 2009 2010 //centering it vertically 2011 $(SECTION_NAV_SEL).css('margin-top', '-' + (($(SECTION_NAV_SEL).height()/2) - $adminBar - $headerHeight/2) + 'px'); 2012 2013 //activating the current active section 2014 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 2015 2016 if($('#nectar_fullscreen_rows[data-footer="last_row"]').length > 0 || $('#nectar_fullscreen_rows[data-footer="default"]').length > 0) { 2017 nav.find('ul li:last-child').remove(); 2018 } 2019 } 2020 2021 /** 2022 * Creates the slim scroll scrollbar for the sections and slides inside them. 2023 */ 2024 function createSlimScrollingHandler(){ 2025 2026 $(SECTION_SEL).each(function(){ 2027 var slides = $(this).find(SLIDE_SEL); 2028 2029 if(slides.length){ 2030 slides.each(function(){ 2031 createSlimScrolling($(this)); 2032 }); 2033 }else{ 2034 createSlimScrolling($(this)); 2035 } 2036 2037 }); 2038 2039 afterRenderActions(); 2040 } 2041 2042 /* 2043 * Enables the Youtube videos API so we can control their flow if necessary. 2044 */ 2045 function enableYoutubeAPI(){ 2046 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 2047 var sign = getUrlParamSign($(this).attr('src')); 2048 $(this).attr('src', $(this).attr('src') + sign + 'enablejsapi=1'); 2049 }); 2050 } 2051 2052 /* 2053 * Enables the Vimeo videos API so we can control their flow if necessary. 2054 */ 2055 function enableVidemoAPI(){ 2056 container.find('iframe[src*="player.vimeo.com/"]').each(function(){ 2057 var sign = getUrlParamSign($(this).attr('src')); 2058 $(this).attr('src', $(this).attr('src') + sign + 'api=1'); 2059 }); 2060 } 2061 2062 /* 2063 * Returns the prefix sign to use for a new parameter in an existen URL. 2064 * 2065 * @return {String} ? | & 2066 */ 2067 function getUrlParamSign(url){ 2068 return ( !/\?/.test( url ) ) ? '?' : '&'; 2069 } 2070 2071 /** 2072 * Actions and callbacks to fire afterRender 2073 */ 2074 function afterRenderActions(){ 2075 var section = $(SECTION_ACTIVE_SEL); 2076 2077 section.addClass(COMPLETELY); 2078 2079 if(options.scrollOverflowHandler.afterRender){ 2080 options.scrollOverflowHandler.afterRender(section); 2081 } 2082 lazyLoad(section); 2083 playMedia(section); 2084 2085 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 2086 $.isFunction( options.afterRender ) && options.afterRender.call(container); 2087 } 2088 2089 2090 var isScrolling = false; 2091 var lastScroll = 0; 2092 2093 //when scrolling... 2094 function scrollHandler(){ 2095 var currentSection; 2096 2097 if(!options.autoScrolling || options.scrollBar){ 2098 var currentScroll = $window.scrollTop(); 2099 var scrollDirection = getScrollDirection(currentScroll); 2100 var visibleSectionIndex = 0; 2101 var screen_mid = currentScroll + ($window.height() / 2.0); 2102 2103 //taking the section which is showing more content in the viewport 2104 var sections = document.querySelectorAll(SECTION_SEL); 2105 for (var i = 0; i < sections.length; ++i) { 2106 var section = sections[i]; 2107 2108 // Pick the the last section which passes the middle line of the screen. 2109 if (section.offsetTop <= screen_mid) 2110 { 2111 visibleSectionIndex = i; 2112 } 2113 } 2114 2115 if(isCompletelyInViewPort(scrollDirection)){ 2116 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 2117 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 2118 } 2119 } 2120 2121 //geting the last one, the current one on the screen 2122 currentSection = $(sections).eq(visibleSectionIndex); 2123 2124 //setting the visible section as active when manually scrolling 2125 //executing only once the first time we reach the section 2126 if(!currentSection.hasClass(ACTIVE)){ 2127 isScrolling = true; 2128 var leavingSection = $(SECTION_ACTIVE_SEL); 2129 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 2130 var yMovement = getYmovement(currentSection); 2131 var anchorLink = currentSection.data('anchor'); 2132 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 2133 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 2134 2135 if(activeSlide.length){ 2136 var slideAnchorLink = activeSlide.data('anchor'); 2137 var slideIndex = activeSlide.index(); 2138 } 2139 2140 if(canScroll){ 2141 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 2142 2143 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 2144 2145 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 2146 lazyLoad(currentSection); 2147 2148 activateMenuAndNav(anchorLink, sectionIndex - 1); 2149 2150 if(options.anchors.length){ 2151 //needed to enter in hashChange event when using the menu with anchor links 2152 lastScrolledDestiny = anchorLink; 2153 2154 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 2155 } 2156 } 2157 2158 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 2159 clearTimeout(scrollId); 2160 scrollId = setTimeout(function(){ 2161 isScrolling = false;
2162 }, 100); 2163 } 2164 2165 if(options.fitToSection){ 2166 //for the auto adjust of the viewport to fit a whole section 2167 clearTimeout(scrollId2); 2168 2169 scrollId2 = setTimeout(function(){ 2170 //checking fitToSection again in case it was set to false before the timeout delay 2171 if(canScroll && options.fitToSection){ 2172 //allows to scroll to an active section and 2173 //if the section is already active, we prevent firing callbacks 2174 if($(SECTION_ACTIVE_SEL).is(currentSection)){ 2175 isResizing = true; 2176 } 2177 scrollPage($(SECTION_ACTIVE_SEL)); 2178 2179 isResizing = false; 2180 } 2181 }, options.fitToSectionDelay); 2182 } 2183 } 2184 } 2185 2186 /** 2187 * Determines whether the active section has seen in its whole or not. 2188 */ 2189 function isCompletelyInViewPort(movement){ 2190 var top = $(SECTION_ACTIVE_SEL).position().top; 2191 var bottom = top + $window.height(); 2192 2193 if(movement == 'up'){ 2194 return bottom >= ($window.scrollTop() + $window.height()); 2195 } 2196 return top <= $window.scrollTop(); 2197 } 2198 2199 /** 2200 * Gets the directon of the the scrolling fired by the scroll event. 2201 */ 2202 function getScrollDirection(currentScroll){ 2203 var direction = currentScroll > lastScroll ? 'down' : 'up'; 2204 2205 lastScroll = currentScroll; 2206 2207 return direction; 2208 } 2209 2210 /** 2211 * Determines the way of scrolling up or down: 2212 * by 'automatically' scrolling a section or by using the default and normal scrolling. 2213 */ 2214 function scrolling(type, scrollable){ 2215 /* nectar addition */ 2216 if (!isScrollAllowed.m[type] || $('#slide-out-widget-area.open[class*="fullscreen"]').length > 0){ 2217 return; 2218 } 2219 /* nectar addition end */ 2220 var check, scrollSection; 2221 2222 if(type == 'down'){ 2223 check = 'bottom'; 2224 scrollSection = FP.moveSectionDown; 2225 }else{ 2226 check = 'top'; 2227 scrollSection = FP.moveSectionUp; 2228 } 2229 2230 if(scrollable.length > 0 ){ 2231 //is the scrollbar at the start/end of the scroll? 2232 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 2233 2234 //* nectar addition */ 2235 if( $('#nectar_fullscreen_rows.nextSectionAllowed').length > 0) { 2236 scrollSection(); 2237 } 2238 $('#nectar_fullscreen_rows').addClass('nextSectionAllowed'); 2239 }else{ 2240 return true; 2241 } 2242 }else{ 2243 // moved up/down 2244 scrollSection(); 2245 } 2246 } 2247 2248 2249 var touchStartY = 0; 2250 var touchStartX = 0; 2251 var touchEndY = 0; 2252 var touchEndX = 0; 2253 2254 /* Detecting touch events 2255 2256 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 2257 * This way, the touchstart and the touch moves shows an small difference between them which is the 2258 * used one to determine the direction. 2259 */ 2260 function touchMoveHandler(event){ 2261 var e = event.originalEvent; 2262 2263 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 2264 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 2265 2266 if(options.autoScrolling){ 2267 //preventing the easing on iOS devices 2268 event.preventDefault(); 2269 } 2270 2271 var activeSection = $(SECTION_ACTIVE_SEL); 2272 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 2273 2274 if (canScroll && !slideMoving) { //if theres any # 2275 var touchEvents = getEventsPage(e); 2276 2277 touchEndY = touchEvents.y; 2278 touchEndX = touchEvents.x; 2279 2280 //if movement in the X axys is greater than in the Y and the currect section has slides... 2281 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 2282 2283 //is the movement greater than the minimum resistance to scroll? 2284 if (Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 2285 if (touchStartX > touchEndX) { 2286 if(isScrollAllowed.m.right){ 2287 FP.moveSlideRight(); //next 2288 } 2289 } else { 2290 if(isScrollAllowed.m.left){ 2291 FP.moveSlideLeft(); //prev 2292 } 2293 } 2294 } 2295 } 2296 2297 //vertical scrolling (only when autoScrolling is enabled) 2298 else if(options.autoScrolling){ 2299 2300 //is the movement greater than the minimum resistance to scroll? 2301 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 2302 if (touchStartY > touchEndY) { 2303 scrolling('down', scrollable); 2304 } else if (touchEndY > touchStartY) { 2305 scrolling('up', scrollable); 2306 } 2307 } 2308 } 2309 } 2310 } 2311 2312 } 2313 2314 /** 2315 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 2316 * Currently works well for iOS - Android might need some testing 2317 * @param {Element} el target element / jquery selector (in subsequent nodes) 2318 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 2319 * @return {boolean} true if there is a match to options.normalScrollElements 2320 */ 2321 function checkParentForNormalScrollElement (el, hop) { 2322 hop = hop || 0; 2323 var parent = $(el).parent(); 2324 2325 if (hop < options.normalScrollElementTouchThreshold && 2326 parent.is(options.normalScrollElements) ) { 2327 return true; 2328 } else if (hop == options.normalScrollElementTouchThreshold) { 2329 return false;
2330 } else { 2331 return checkParentForNormalScrollElement(parent, ++hop); 2332 } 2333 } 2334 2335 /** 2336 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 2337 * this way we make sure that is really a touch event what IE is detecting. 2338 */ 2339 function isReallyTouch(e){ 2340 //if is not IE || IE is detecting `touch` or `pen` 2341 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 2342 } 2343 2344 /** 2345 * Handler for the touch start event. 2346 */ 2347 function touchStartHandler(event){ 2348 var e = event.originalEvent; 2349 2350 //stopping the auto scroll to adjust to a section 2351 if(options.fitToSection){ 2352 $htmlBody.stop(); 2353 } 2354 2355 if(isReallyTouch(e)){ 2356 var touchEvents = getEventsPage(e); 2357 touchStartY = touchEvents.y; 2358 touchStartX = touchEvents.x; 2359 } 2360 } 2361 2362 /** 2363 * Gets the average of the last `number` elements of the given array. 2364 */ 2365 function getAverage(elements, number){ 2366 var sum = 0; 2367 2368 //taking `number` elements from the end to make the average, if there are not enought, 1 2369 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 2370 2371 for(var i = 0; i < lastElements.length; i++){ 2372 sum = sum + lastElements[i]; 2373 } 2374 2375 return Math.ceil(sum/number); 2376 } 2377 2378 /** 2379 * Detecting mousewheel scrolling 2380 * 2381 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 2382 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 2383 */ 2384 var prevTime = new Date().getTime(); 2385 2386 function MouseWheelHandler(e) { 2387 2388 2389 var curTime = new Date().getTime(); 2390 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 2391 2392 //autoscrolling and not zooming? 2393 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 2394 2395 /* Nectar addition - tracked whether clicked or scrolled to */ 2396 clickedNavigation = false; 2397 /* Nectar addition end */ 2398 2399 // cross-browser wheel delta 2400 e = e || window.event; 2401 var value = e.wheelDelta || -e.deltaY || -e.detail; 2402 var delta = Math.max(-1, Math.min(1, value)); 2403 2404 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 2405 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 2406 2407 //Limiting the array to 150 (lets not waste memory!) 2408 if(scrollings.length > 149){ 2409 scrollings.shift(); 2410 } 2411 2412 //keeping record of the previous scrollings 2413 scrollings.push(Math.abs(value)); 2414 2415 //preventing to scroll the site on mouse wheel when scrollbar is present 2416 if(options.scrollBar){ 2417 e.preventDefault ? e.preventDefault() : e.returnValue = false; 2418 } 2419 2420 var activeSection = $(SECTION_ACTIVE_SEL); 2421 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 2422 2423 //time difference between the last scroll and the current one 2424 var timeDiff = curTime-prevTime; 2425 prevTime = curTime; 2426 2427 //haven't they scrolled in a while? 2428 //(enough to be consider a different scrolling action to scroll another section) 2429 if(timeDiff > 200){ 2430 //emptying the array, we dont care about old scrollings for our averages 2431 scrollings = []; 2432 } 2433 2434 if(canScroll && $('#nectar_fullscreen_rows.trans-animation-active').length == 0){ 2435 var averageEnd = getAverage(scrollings, 10); 2436 var averageMiddle = getAverage(scrollings, 70); 2437 var isAccelerating = averageEnd >= averageMiddle; 2438 2439 //to avoid double swipes... 2440 if(isAccelerating && isScrollingVertically && $('.next-current').length == 0){ 2441 //scrolling down? 2442 if (delta < 0) { 2443 scrolling('down', scrollable); 2444 2445 //scrolling up? 2446 }else { 2447 scrolling('up', scrollable); 2448 } 2449 } 2450 } 2451 2452 return false;
2453 } 2454 2455 if(options.fitToSection){ 2456 //stopping the auto scroll to adjust to a section 2457 $htmlBody.stop(); 2458 } 2459 } 2460 2461 /** 2462 * Slides a slider to the given direction. 2463 * Optional `section` param. 2464 */ 2465 function moveSlide(direction, section){ 2466 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 2467 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 2468 var numSlides = slides.find(SLIDE_SEL).length; 2469 2470 // more than one slide needed and nothing should be sliding 2471 if (!slides.length || slideMoving || numSlides < 2) { 2472 return; 2473 } 2474 2475 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 2476 var destiny = null; 2477 2478 if(direction === 'prev'){ 2479 destiny = currentSlide.prev(SLIDE_SEL); 2480 }else{ 2481 destiny = currentSlide.next(SLIDE_SEL); 2482 } 2483 2484 //isn't there a next slide in the secuence? 2485 if(!destiny.length){ 2486 //respect loopHorizontal settin 2487 if (!options.loopHorizontal) return; 2488 2489 if(direction === 'prev'){ 2490 destiny = currentSlide.siblings(':last'); 2491 }else{ 2492 destiny = currentSlide.siblings(':first'); 2493 } 2494 } 2495 2496 slideMoving = true; 2497 2498 landscapeScroll(slides, destiny); 2499 } 2500 2501 /** 2502 * Maintains the active slides in the viewport 2503 * (Because he `scroll` animation might get lost with some actions, such as when using continuousVertical) 2504 */ 2505 function keepSlidesPosition(){ 2506 $(SLIDE_ACTIVE_SEL).each(function(){ 2507 silentLandscapeScroll($(this), 'internal'); 2508 }); 2509 } 2510 2511 var previousDestTop = 0; 2512 /** 2513 * Returns the destination Y position based on the scrolling direction and 2514 * the height of the section. 2515 */ 2516 function getDestinationPosition(element){ 2517 var elemPosition = element.position(); 2518 2519 //top of the desination will be at the top of the viewport 2520 var position = elemPosition.top; 2521 var isScrollingDown = elemPosition.top > previousDestTop; 2522 var sectionBottom = position - windowsHeight + element.outerHeight(); 2523 2524 //is the destination element bigger than the viewport? 2525 if(element.outerHeight() > windowsHeight){ 2526 //scrolling up? 2527 if(!isScrollingDown){ 2528 position = sectionBottom; 2529 } 2530 } 2531 2532 //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 2533 else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 2534 //The bottom of the destination will be at the bottom of the viewport 2535 position = sectionBottom; 2536 } 2537 2538 /* 2539 Keeping record of the last scrolled position to determine the scrolling direction. 2540 No conventional methods can be used as the scroll bar might not be present 2541 AND the section might not be active if it is auto-height and didnt reach the middle 2542 of the viewport. 2543 */ 2544 previousDestTop = position; 2545 return position; 2546 } 2547 2548 /** 2549 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 2550 */ 2551 function scrollPage(element, callback, isMovementUp){ 2552 /* nectar addition of ||canScroll and element.length == 0 */ 2553 if(typeof element === 'undefined' || 2554 element.length == 0 || 2555 ( $('#nectar_fullscreen_rows[data-animation="none"]').length == 0 && canScroll == false ) || 2556 $('.ocm-effect-wrap.material-ocm-open').length > 0 || 2557 $('.nectar_team_member_overlay.open').length > 0 ) { 2558 return; 2559 } //there's no element to scroll, leaving the function 2560 2561 var dtop = getDestinationPosition(element); 2562 2563 //local variables 2564 var v = { 2565 element: element, 2566 callback: callback, 2567 isMovementUp: isMovementUp, 2568 dtop: dtop, 2569 yMovement: getYmovement(element), 2570 anchorLink: element.data('anchor'), 2571 sectionIndex: element.index(SECTION_SEL), 2572 activeSlide: element.find(SLIDE_ACTIVE_SEL), 2573 activeSection: $(SECTION_ACTIVE_SEL), 2574 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 2575 2576 //caching the value of isResizing at the momment the function is called 2577 //because it will be checked later inside a setTimeout and the value might change 2578 localIsResizing: isResizing 2579 }; 2580 2581 //quiting when destination scroll is the same as the current one 2582 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 2583 2584 if(v.activeSlide.length){ 2585 var slideAnchorLink = v.activeSlide.data('anchor'); 2586 var slideIndex = v.activeSlide.index(); 2587 } 2588 2589 // If continuousVertical && we need to wrap around 2590 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 2591 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 2592 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 2593 2594 v = createInfiniteSections(v); 2595 } 2596 2597 //callback (onLeave) if the site is not just resizing and readjusting the slides 2598 if($.isFunction(options.onLeave) && !v.localIsResizing){ 2599 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 2600 return; 2601 } 2602 } 2603 2604 stopMedia(v.activeSection); 2605 /* nectar addition */ 2606 //element.addClass(ACTIVE).siblings().removeClass(ACTIVE); - moved to after section loads location 2607 if( $('#nectar_fullscreen_rows[data-animation="none"]').length > 0 && clickedNavigation == true ) { 2608 // Allow for instant changing between sections from clicking. 2609 clearTimeout(afterSectionLoadsId); 2610 element.removeClass(ACTIVE).siblings().removeClass(ACTIVE) 2611 } 2612 lazyLoad(element); 2613 options.scrollOverflowHandler.onLeave(); 2614 2615 2616 //preventing from activating the MouseWheelHandler event 2617 //more than once if the page is scrolling 2618 if( !window.vc_iframe) { 2619 canScroll = false;
2620 } 2621 2622 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 2623 2624 // Nectar addition - regular scrolling handling footer. 2625 setTimeout(function(){ 2626 if( $('#nectar_fullscreen_rows[data-animation="none"]').length > 0 && 2627 $('.last-before-footer').length > 0 && 2628 clickedNavigation == true && 2629 !$('#fp-nav ul > li:last-child a').hasClass('active') ) { 2630 setTimeout(function(){ 2631 var translate3d = 'translate3d(0px, -' + v.dtop + 'px, 0px)'; 2632 transformContainer(translate3d, true); 2633 },600); 2634 } 2635 },100); 2636 2637 performMovement(v); 2638 2639 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 2640 lastScrolledDestiny = v.anchorLink; 2641 2642 //avoid firing it twice (as it does also on scroll) 2643 activateMenuAndNav(v.anchorLink, v.sectionIndex); 2644 } 2645 2646 /** 2647 * Performs the movement (by CSS3 or by jQuery) 2648 */ 2649 function performMovement(v){ 2650 2651 /* nectar addition */ 2652 function switchedSection() { 2653 2654 var current = +new Date(), 2655 remaining = end - current; 2656 2657 if(remaining < 60) { 2658 afterSectionLoads(v); 2659 2660 } else { 2661 requestAnimationFrame(switchedSection); 2662 } 2663 2664 } 2665 2666 scrollings = []; 2667 2668 if($('#nectar_fullscreen_rows[data-animation-speed="medium"]').length > 0) { 2669 var $timeOutDur = ($('.last-before-footer').length == 0) ? 910 : 530; 2670 } 2671 else if($('#nectar_fullscreen_rows[data-animation-speed="slow"]').length > 0) { 2672 var $timeOutDur = ($('.last-before-footer').length == 0) ? 1200 : 530; 2673 } 2674 else { 2675 var $timeOutDur = ($('.last-before-footer').length == 0) ? 720 : 530; 2676 } 2677 2678 // using CSS3 translate functionality 2679 if (options.css3 && !options.scrollBar && $('#nectar_fullscreen_rows[data-animation="none"]').length == 0) { 2680 var translate3d = 'translate3d(0px, -' + v.dtop + 'px, 0px)'; 2681 /* nectar addition */ 2682 //transformContainer(translate3d, true); 2683 2684 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 2685 //scrollingSpeed to change in case of using silentMoveTo(); 2686 if(options.scrollingSpeed){ 2687 afterSectionLoadsId = setTimeout(function () { 2688 afterSectionLoads(v); 2689 HASHCHANGE = false; 2690 }, $timeOutDur); 2691 }else{ 2692 afterSectionLoads(v); 2693 } 2694 } 2695 2696 // using jQuery animate 2697 else{ 2698 2699 var scrollSettings = getScrollSettings(v); 2700 2701 if($('#nectar_fullscreen_rows[data-animation="none"]').length > 0) { 2702 2703 if($('.last-before-footer').length == 0) { 2704 2705 var translate3d = 'translate3d(0px, -' + v.dtop + 'px, 0px)'; 2706 transformContainer(translate3d, true); 2707 2708 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 2709 //scrollingSpeed to change in case of using silentMoveTo(); 2710 if(options.scrollingSpeed){ 2711 2712 if(window.vc_iframe) { 2713 2714 var duration = 950, 2715 end = +new Date() + duration; 2716 var $cur_section = $('#nectar_fullscreen_rows > .active'); 2717 requestAnimationFrame(switchedSection); 2718 2719 } else { 2720 afterSectionLoadsId = setTimeout(function () { 2721 afterSectionLoads(v); 2722 }, options.scrollingSpeed); 2723 } 2724 2725 }else{ 2726 afterSectionLoads(v); 2727 } 2728 2729 2730 } 2731 2732 else { 2733 2734 setTimeout(function(){ 2735 2736 if(options.scrollBar){ 2737 setTimeout(function(){ 2738 afterSectionLoads(v); 2739 },30); 2740 }else{ 2741 afterSectionLoads(v); 2742 } 2743 },$timeOutDur); 2744 } 2745 2746 } 2747 2748 else { 2749 setTimeout(function(){ 2750 2751 if(options.scrollBar){ 2752 setTimeout(function(){ 2753 afterSectionLoads(v); 2754 },30); 2755 }else{ 2756 afterSectionLoads(v); 2757 } 2758 HASHCHANGE = false;
2759 },$timeOutDur); 2760 } 2761 2762 2763 2764 } 2765 } 2766 2767 /** 2768 * Gets the scrolling settings depending on the plugin autoScrolling option 2769 */ 2770 function getScrollSettings(v){ 2771 var scroll = {}; 2772 2773 if(options.autoScrolling && !options.scrollBar){ 2774 scroll.options = { 'top': -v.dtop}; 2775 scroll.element = WRAPPER_SEL; 2776 }else{ 2777 scroll.options = { 'scrollTop': v.dtop}; 2778 scroll.element = 'html, body'; 2779 } 2780 2781 return scroll; 2782 } 2783 2784 /** 2785 * Adds sections before or after the current one to create the infinite effect. 2786 */ 2787 function createInfiniteSections(v){ 2788 // Scrolling down 2789 if (!v.isMovementUp) { 2790 // Move all previous sections to after the active section 2791 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 2792 } 2793 else { // Scrolling up 2794 // Move all next sections to before the active section 2795 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 2796 } 2797 2798 // Maintain the displayed position (now that we changed the element order) 2799 silentScroll($(SECTION_ACTIVE_SEL).position().top); 2800 2801 // Maintain the active slides visible in the viewport 2802 keepSlidesPosition(); 2803 2804 // save for later the elements that still need to be reordered 2805 v.wrapAroundElements = v.activeSection; 2806 2807 // Recalculate animation variables 2808 v.dtop = v.element.position().top; 2809 v.yMovement = getYmovement(v.element); 2810 2811 return v; 2812 } 2813 2814 /** 2815 * Fix section order after continuousVertical changes have been animated 2816 */ 2817 function continuousVerticalFixSectionOrder (v) { 2818 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 2819 // finish moving the elements around so the direct navigation will function more simply 2820 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 2821 return; 2822 } 2823 2824 if (v.isMovementUp) { 2825 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 2826 } 2827 else { 2828 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 2829 } 2830 2831 silentScroll($(SECTION_ACTIVE_SEL).position().top); 2832 2833 // Maintain the active slides visible in the viewport 2834 keepSlidesPosition(); 2835 } 2836 2837 2838 /** 2839 * Actions to do once the section is loaded. 2840 */ 2841 function afterSectionLoads (v){ 2842 2843 continuousVerticalFixSectionOrder(v); 2844 /* nectar addition */ 2845 //v.element.find('.fp-scrollable').mouseover(); 2846 2847 //resizing the scrolling divs 2848 //$(SECTION_SEL).each(function(){ 2849 // if(options.scrollOverflow){ 2850 // createSlimScrolling($(this)); 2851 // } 2852 //}); 2853 $('#nectar_fullscreen_rows').removeClass('trans-animation-active'); 2854 v.element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 2855 2856 //callback (afterLoad) if the site is not just resizing and readjusting the slides 2857 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 2858 options.scrollOverflowHandler.afterLoad(); 2859 2860 playMedia(v.element); 2861 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 2862 2863 $.isFunction(v.callback) && v.callback.call(this); 2864 2865 // Delay a little for mac smooth scroll 2866 if( clickedNavigation == true ) { 2867 canScroll = true; 2868 } 2869 2870 if( $('#nectar_fullscreen_rows[data-animation-speed="fast"]').length > 0 ) { 2871 setTimeout(function(){ 2872 canScroll = true; 2873 },425); 2874 } else { 2875 setTimeout(function(){ 2876 canScroll = true; 2877 },250); 2878 } 2879 2880 } 2881 2882 /** 2883 * Lazy loads image, video and audio elements. 2884 */ 2885 function lazyLoad(destiny){ 2886 var destiny = getSlideOrSection(destiny); 2887 2888 destiny.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 2889 $(this).attr('src', $(this).data('src')); 2890 $(this).removeAttr('data-src'); 2891 2892 if($(this).is('source')){ 2893 $(this).closest('video').get(0).load(); 2894 } 2895 }); 2896 } 2897 2898 /** 2899 * Plays video and audio elements. 2900 */ 2901 function playMedia(destiny){ 2902 2903 /* nectar addition */ 2904 2905 var destiny = getSlideOrSection(destiny); 2906 2907 //playing HTML5 media elements 2908 destiny.find('video.nectar-video-bg').each(function(){ 2909 var element = $(this).get(0); 2910 var videoBGStored = $(this); 2911 2912 if( typeof element.play === 'function' ) { 2913 2914 if( navigator.userAgent.match(/(Android|iPod|iPhone|iPad|BlackBerry|IEMobile|Opera Mini)/)) { 2915 element.onplay = function(){ 2916 videoBGStored.parents('.nectar-video-wrap').animate({'opacity':'1'},200); 2917 } 2918 } 2919 2920 element.play(); 2921 2922 } 2923 }); 2924 2925 //youtube videos 2926 destiny.find('.nectar-youtube-bg iframe[src*="youtube.com/embed/"]').each(function(){ 2927 var element = $(this).get(0); 2928 2929 if( /youtube\.com\/embed\//.test($(this).attr('src'))){ 2930 2931 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 2932 } 2933 }); 2934 2935 /* nectar addition end */ 2936 } 2937 2938 /** 2939 * Stops video and audio elements. 2940 */ 2941 function stopMedia(destiny){ 2942 var destiny = getSlideOrSection(destiny); 2943 2944 //stopping HTML5 media elements 2945 destiny.find('video, audio').each(function(){ 2946 var element = $(this).get(0); 2947 2948 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 2949 /* nectar addition */ 2950 if( $(this).parents('.nectar_video_player_self_hosted').length > 0 && $(this).is('[autoplay][muted]') ) { 2951 2952 } else { 2953 element.pause(); 2954 } 2955 /* nectar addition end */ 2956 } 2957 }); 2958 2959 //youtube videos 2960 destiny.find('.nectar-youtube-bg iframe[src*="youtube.com/embed/"]').each(function(){ 2961 var element = $(this).get(0); 2962 2963 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 2964 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 2965 } 2966 }); 2967 } 2968 2969 /** 2970 * Gets the active slide (or section) for the given section 2971 */ 2972 function getSlideOrSection(destiny){ 2973 var slide = destiny.find(SLIDE_ACTIVE_SEL); 2974 if( slide.length ) { 2975 destiny = $(slide); 2976 } 2977 2978 return destiny; 2979 } 2980 2981 /**
2982 * Scrolls to the anchor in the URL when loading the site 2983 */ 2984 function scrollToAnchor(){ 2985 2986 //getting the anchor link in the URL and deleting the `#` 2987 var value = window.location.hash.replace('#', '').split('/'); 2988 var section = decodeURIComponent(value[0]); 2989 var slide = decodeURIComponent(value[1]); 2990 /* nectar addition */ 2991 if(section && $('.vc_row[data-fullscreen-anchor-id="'+section+'"]').length > 0){ //if theres any # 2992 /* nectar addition end */ 2993 if(options.animateAnchor){ 2994 scrollPageAndSlide(section, slide); 2995 }else{ 2996 FP.silentMoveTo(section, slide); 2997 } 2998 } 2999 } 3000 3001 /** 3002 * Detecting any change on the URL to scroll to the given anchor link 3003 * (a way to detect back history button as we play with the hashes on the URL) 3004 */ 3005 function hashChangeHandler(){ 3006 3007 if(!isScrolling && !options.lockAnchors){ 3008 var value = window.location.hash.replace('#', '').split('/'); 3009 var section = decodeURIComponent(value[0]); 3010 var slide = decodeURIComponent(value[1]); 3011 3012 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 3013 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 3014 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slide === 'undefined' && !slideMoving); 3015 3016 3017 if(section.length){ 3018 /*in order to call scrollpage() only once for each destination at a time 3019 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 3020 event is fired on every scroll too.*/ 3021 if ((section && section !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slide )) { 3022 scrollPageAndSlide(section, slide); 3023 } 3024 } 3025 3026 3027 } 3028 3029 /* nectar addition */ 3030 3031 //make page history work when clicking faster than transition speed 3032 if($('#nectar_fullscreen_rows[data-animation-speed="medium"]').length > 0) 3033 var $timeOutDur = ($('.last-before-footer').length == 0) ? 900 : 530; 3034 else if($('#nectar_fullscreen_rows[data-animation-speed="slow"]').length > 0) 3035 var $timeOutDur = ($('.last-before-footer').length == 0) ? 1180 : 530; 3036 else 3037 var $timeOutDur = ($('.last-before-footer').length == 0) ? 710 : 530; 3038 3039 if(HASHCHANGE == true) { 3040 clearInterval(HASHCHANGETIMEOUT); 3041 3042 HASHCHANGETIMEOUT = setInterval(function(){ 3043 if(canScroll) { 3044 hashChangeHandler(); 3045 //reset 3046 clearInterval(HASHCHANGETIMEOUT); 3047 } 3048 },100); 3049 } 3050 3051 HASHCHANGE = true; 3052 /* nectar addition */ 3053 } 3054 3055 //Sliding with arrow keys, both, vertical and horizontal 3056 function keydownHandler(e) { 3057 3058 clearTimeout(keydownId); 3059 3060 var activeElement = $(':focus'); 3061 3062 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 3063 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 3064 options.keyboardScrolling && options.autoScrolling){ 3065 var keyCode = e.which; 3066 3067 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 3068 var keyControls = [40, 38, 32, 33, 34]; 3069 if($.inArray(keyCode, keyControls) > -1){ 3070 e.preventDefault(); 3071 } 3072 3073 controlPressed = e.ctrlKey; 3074 3075 keydownId = setTimeout(function(){ 3076 onkeydown(e); 3077 },150); 3078 } 3079 } 3080 3081 function tooltipTextHandler(){ 3082 $(this).prev().trigger('click'); 3083 } 3084 3085 //to prevent scrolling while zooming 3086 function keyUpHandler(e){ 3087 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 3088 controlPressed = e.ctrlKey; 3089 } 3090 } 3091 3092 //binding the mousemove when the mouse's middle button is released 3093 function mouseDownHandler(e){ 3094 //middle button 3095 if (e.which == 2){ 3096 oldPageY = e.pageY; 3097 container.on('mousemove', mouseMoveHandler); 3098 } 3099 } 3100 3101 //unbinding the mousemove when the mouse's middle button is released 3102 function mouseUpHandler(e){ 3103 //middle button 3104 if (e.which == 2){ 3105 container.off('mousemove'); 3106 } 3107 } 3108 3109 //Scrolling horizontally when clicking on the slider controls. 3110 function slideArrowHandler(){ 3111 var section = $(this).closest(SECTION_SEL); 3112 3113 if ($(this).hasClass(SLIDES_PREV)) { 3114 if(isScrollAllowed.m.left){ 3115 FP.moveSlideLeft(section); 3116 } 3117 } else { 3118 if(isScrollAllowed.m.right){ 3119 FP.moveSlideRight(section); 3120 } 3121 } 3122 } 3123 3124 function focusHandler() { 3125 isWindowFocused = true; 3126 } 3127 3128 //when opening a new tab (ctrl + t), `control` won't be pressed when comming back. 3129 function blurHandler(){ 3130 isWindowFocused = false;
3131 controlPressed = false; 3132 } 3133 3134 //Scrolls to the section when clicking the navigation bullet 3135 function sectionBulletHandler(e){ 3136 3137 e.preventDefault(); 3138 /* nectar addition */ 3139 clickedNavigation = true; 3140 if( $('#nectar_fullscreen_rows[data-animation="none"]').length > 0 ) { 3141 var index = $(this).parent().index(); 3142 scrollPage($(SECTION_SEL).eq(index)); 3143 } else { 3144 3145 if($('#nectar_fullscreen_rows .wpb_row.transition-out').length == 0 && $('#nectar_fullscreen_rows.trans-animation-active').length == 0) { 3146 var index = $(this).parent().index(); 3147 scrollPage($(SECTION_SEL).eq(index)); 3148 } 3149 } 3150 3151 } 3152 3153 //Scrolls the slider to the given slide destination for the given section 3154 function slideBulletHandler(e){ 3155 e.preventDefault(); 3156 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 3157 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 3158 3159 landscapeScroll(slides, destiny); 3160 } 3161 3162 /** 3163 * Keydown event 3164 */ 3165 function onkeydown(e){ 3166 var shiftPressed = e.shiftKey; 3167 3168 switch (e.which) { 3169 //up 3170 case 38: 3171 case 33: 3172 if(isScrollAllowed.k.up){ 3173 FP.moveSectionUp(); 3174 } 3175 break; 3176 3177 //down 3178 case 32: //spacebar 3179 if(shiftPressed && isScrollAllowed.k.up){ 3180 FP.moveSectionUp(); 3181 break; 3182 } 3183 case 40: 3184 case 34: 3185 if(isScrollAllowed.k.down){ 3186 FP.moveSectionDown(); 3187 } 3188 break; 3189 3190 //Home 3191 case 36: 3192 if(isScrollAllowed.k.up){ 3193 FP.moveTo(1); 3194 } 3195 break; 3196 3197 //End 3198 case 35: 3199 if(isScrollAllowed.k.down){ 3200 FP.moveTo( $(SECTION_SEL).length ); 3201 } 3202 break; 3203 3204 //left 3205 case 37: 3206 if(isScrollAllowed.k.left){ 3207 FP.moveSlideLeft(); 3208 } 3209 break; 3210 3211 //right 3212 case 39: 3213 if(isScrollAllowed.k.right){ 3214 FP.moveSlideRight(); 3215 } 3216 break; 3217 3218 default: 3219 return; // exit this handler for other keys 3220 } 3221 } 3222 3223 /** 3224 * Detecting the direction of the mouse movement. 3225 * Used only for the middle button of the mouse. 3226 */ 3227 var oldPageY = 0; 3228 function mouseMoveHandler(e){ 3229 if(canScroll){ 3230 // moving up 3231 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 3232 FP.moveSectionUp(); 3233 } 3234 3235 // moving down 3236 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 3237 FP.moveSectionDown(); 3238 } 3239 } 3240 oldPageY = e.pageY; 3241 } 3242 3243 /** 3244 * Scrolls horizontal sliders. 3245 */ 3246 function landscapeScroll(slides, destiny){ 3247 var destinyPos = destiny.position(); 3248 var slideIndex = destiny.index(); 3249 var section = slides.closest(SECTION_SEL); 3250 var sectionIndex = section.index(SECTION_SEL); 3251 var anchorLink = section.data('anchor'); 3252 var slidesNav = section.find(SLIDES_NAV_SEL); 3253 var slideAnchor = getAnchor(destiny); 3254 var prevSlide = section.find(SLIDE_ACTIVE_SEL); 3255 3256 //caching the value of isResizing at the momment the function is called 3257 //because it will be checked later inside a setTimeout and the value might change 3258 var localIsResizing = isResizing; 3259 3260 if(options.onSlideLeave){ 3261 var prevSlideIndex = prevSlide.index(); 3262 var xMovement = getXmovement(prevSlideIndex, slideIndex); 3263 3264 //if the site is not just resizing and readjusting the slides 3265 if(!localIsResizing && xMovement!=='none'){ 3266 if($.isFunction( options.onSlideLeave )){ 3267 if(options.onSlideLeave.call( prevSlide, anchorLink, (sectionIndex + 1), prevSlideIndex, xMovement, slideIndex ) === false){ 3268 slideMoving = false;
3269 return; 3270 } 3271 } 3272 } 3273 } 3274 stopMedia(prevSlide); 3275 3276 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 3277 if(!localIsResizing){ 3278 lazyLoad(destiny); 3279 } 3280 3281 if(!options.loopHorizontal && options.controlArrows){ 3282 //hidding it for the fist slide, showing for the rest 3283 section.find(SLIDES_ARROW_PREV_SEL).toggle(slideIndex!==0); 3284 3285 //hidding it for the last slide, showing for the rest 3286 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 3287 } 3288 3289 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 3290 if(section.hasClass(ACTIVE)){ 3291 setState(slideIndex, slideAnchor, anchorLink, sectionIndex); 3292 } 3293 3294 var afterSlideLoads = function(){ 3295 //if the site is not just resizing and readjusting the slides 3296 if(!localIsResizing){ 3297 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( destiny, anchorLink, (sectionIndex + 1), slideAnchor, slideIndex); 3298 } 3299 playMedia(destiny); 3300 3301 //letting them slide again 3302 slideMoving = false; 3303 }; 3304 3305 if(options.css3){ 3306 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 3307 3308 addAnimation(slides.find(SLIDES_CONTAINER_SEL), options.scrollingSpeed>0).css(getTransforms(translate3d)); 3309 3310 afterSlideLoadsId = setTimeout(function(){ 3311 afterSlideLoads(); 3312 }, options.scrollingSpeed, options.easing); 3313 }else{ 3314 slides.animate({ 3315 scrollLeft : Math.round(destinyPos.left) 3316 }, options.scrollingSpeed, options.easing, function() { 3317 3318 afterSlideLoads(); 3319 }); 3320 } 3321 3322 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 3323 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 3324 } 3325 3326 var previousHeight = windowsHeight; 3327 3328 //when resizing the site, we adjust the heights of the sections, slimScroll... 3329 function resizeHandler(){ 3330 if($('#nectar_fullscreen_rows.afterLoaded').length == 0) return false; 3331 //checking if it needs to get responsive 3332 responsive(); 3333 3334 // rebuild immediately on touch devices 3335 if (isTouchDevice) { 3336 var activeElement = $(document.activeElement); 3337 3338 //if the keyboard is NOT visible 3339 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 3340 var currentHeight = $window.height(); 3341 3342 //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars) 3343 /* nectar addition */ 3344 //if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 3345 FP.reBuild(true); 3346 previousHeight = currentHeight; 3347 //} 3348 /* nectar addition end */ 3349 } 3350 }else{ 3351 //in order to call the functions only when the resize is finished 3352 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 3353 clearTimeout(resizeId); 3354 3355 /* nectar addition */ 3356 // resizeId = setTimeout(function(){ 3357 FP.reBuild(true); 3358 // }, 230); 3359 } 3360 } 3361 /* nectar addition */ 3362 function checkScrollOverflow() { 3363 3364 if($('#nectar_fullscreen_rows.afterLoaded').length ==0) return false; 3365 $(SECTION_SEL).each(function(){ 3366 3367 //resizing the scrolling divs 3368 if(options.scrollOverflow){ 3369 3370 createSlimScrolling($(this)); 3371 3372 } 3373 3374 }); 3375 } 3376 /** 3377 * Checks if the site needs to get responsive and disables autoScrolling if so. 3378 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 3379 */ 3380 function responsive(){ 3381 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 3382 var heightLimit = options.responsiveHeight; 3383 3384 //only calculating what we need. Remember its called on the resize event. 3385 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 3386 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 3387 3388 if(widthLimit && heightLimit){ 3389 FP.setResponsive(isBreakingPointWidth || isBreakingPointHeight); 3390 } 3391 else if(widthLimit){ 3392 FP.setResponsive(isBreakingPointWidth); 3393 } 3394 else if(heightLimit){ 3395 FP.setResponsive(isBreakingPointHeight); 3396 } 3397 3398 /* nectar addition */ 3399 $(SECTION_NAV_SEL).css('margin-top', '-' + (($(SECTION_NAV_SEL).height()/2) - $adminBar - $headerHeight/2) + 'px'); 3400 } 3401 3402 /** 3403 * Adds transition animations for the given element 3404 */ 3405 function addAnimation(element){ 3406 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 3407 3408 element.removeClass(NO_TRANSITION); 3409 return element.css({
3410 '-webkit-transition': transition, 3411 'transition': transition 3412 }); 3413 } 3414 3415 /** 3416 * Remove transition animations for the given element 3417 */ 3418 function removeAnimation(element){ 3419 return element.addClass(NO_TRANSITION); 3420 } 3421 3422 /** 3423 * Activating the website navigation dots according to the given slide name. 3424 */ 3425 function activateNavDots(name, sectionIndex){ 3426 if(options.navigation){ 3427 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 3428 if(name){ 3429 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 3430 }else{ 3431 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 3432 } 3433 } 3434 } 3435 3436 /** 3437 * Activating the website main menu elements according to the given slide name. 3438 */ 3439 function activateMenuElement(name){ 3440 if(options.menu){ 3441 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 3442 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 3443 } 3444 } 3445 3446 /** 3447 * Sets to active the current menu and vertical nav items. 3448 */ 3449 function activateMenuAndNav(anchor, index){ 3450 activateMenuElement(anchor); 3451 activateNavDots(anchor, index); 3452 } 3453 3454 /** 3455 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 3456 * from the current section. 3457 */ 3458 function getYmovement(destiny){ 3459 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 3460 var toIndex = destiny.index(SECTION_SEL); 3461 if( fromIndex == toIndex){ 3462 return 'none'; 3463 } 3464 if(fromIndex > toIndex){ 3465 return 'up'; 3466 } 3467 return 'down'; 3468 } 3469 3470 /** 3471 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 3472 * from the current slide. 3473 */ 3474 function getXmovement(fromIndex, toIndex){ 3475 if( fromIndex == toIndex){ 3476 return 'none'; 3477 } 3478 if(fromIndex > toIndex){ 3479 return 'left'; 3480 } 3481 return 'right'; 3482 } 3483 3484 /** 3485 * Checks if the element needs scrollbar and if the user wants to apply it. 3486 * If so it creates it. 3487 * 3488 * @param {Object} element jQuery object of the section or slide 3489 */ 3490 function createSlimScrolling(element){ 3491 3492 var $fpScrollOverflow = ($('#nectar_fullscreen_rows').attr('data-content-overflow') == 'hidden') ? false : true; 3493 if( $('#nectar_fullscreen_rows[data-animation="free-scroll"]').length > 0 ) { 3494 $fpScrollOverflow = false; 3495 return; 3496 } 3497 //User doesn't want scrollbar here? Sayonara baby! 3498 if(element.hasClass('fp-noscroll')) return; 3499 3500 //needed to make `scrollHeight` work under Opera 12 3501 element.css('overflow', 'hidden'); 3502 3503 var scrollOverflowHandler = options.scrollOverflowHandler; 3504 var wrap = scrollOverflowHandler.wrapContent(); 3505 //in case element is a slide 3506 var section = element.closest(SECTION_SEL); 3507 var scrollable = scrollOverflowHandler.scrollable(element); 3508 var contentHeight; 3509 3510 //if there was scroll, the contentHeight will be the one in the scrollable section 3511 if(scrollable.length){ 3512 /* nectar addition */ 3513 //contentHeight = scrollOverflowHandler.scrollHeight(element); 3514 contentHeight = ( element.find('.full-page-inner-wrap > .full-page-inner > .container > .span_12').length > 0 ) ? element.find('.full-page-inner-wrap > .full-page-inner > .container > .span_12').outerHeight(true) : element.find('.full-page-inner-wrap > .full-page-inner > .span_12').outerHeight(true); 3515 /* nectar addition end */ 3516 } else{ 3517 /* nectar addition */ 3518 contentHeight = ( element.find('.full-page-inner-wrap > .full-page-inner > .container > .span_12').length > 0 ) ? element.find('.full-page-inner-wrap > .full-page-inner > .container > .span_12').outerHeight(true) : element.find('.full-page-inner-wrap > .full-page-inner > .span_12').outerHeight(true); 3519 if(options.verticalCentered){ 3520 contentHeight = ( element.find('.full-page-inner-wrap > .full-page-inner > .container > .span_12').length > 0 ) ? element.find('.full-page-inner-wrap > .full-page-inner > .container > .span_12').outerHeight(true) : element.find('.full-page-inner-wrap > .full-page-inner > .span_12').outerHeight(true); 3521 } 3522 } 3523 3524 /* nectar addition */ 3525 var $headerNavSpace = ($('body[data-header-format="left-header"]').length > 0 && $(window).width() > 1000) ? 0 : $('#header-outer').outerHeight(); 3526 var $adminBar = ($('#wpadminbar').length > 0) ? $('#wpadminbar').height() : 0; //admin bar 3527 if(window.vc_iframe) { $adminBar = 0; } 3528 var $headerHeight = ($('#header-outer.transparent').length == 0 ) ? $headerNavSpace : 0 ; 3529 if( $('#header-outer.transparent').length > 0 && $('#header-secondary-outer[data-mobile="display_full"]').length > 0 && $(window).width() <= 1000 ) { 3530 $headerHeight += $('#header-secondary-outer').height(); 3531 } 3532 var $borderMultiplier = ($('.body-border-right').length > 0 && $('#header-outer').css('background-color') == $('.body-border-right').css('background-color')) ? 1 : 2; 3533 var $borderHeight = ($('.body-border-right').length > 0 && $(window).width()>1000) ? $('.body-border-right').width()*$borderMultiplier : 0; 3534 var $materialExtra = ($('body.material .ocm-effect-wrap').length > 0) ? 2 : 0; //fix for showing material ocm BG since overflow is hidden on effect wrap 3535 3536 windowsHeight = $window.height() - $adminBar - $headerHeight - $borderHeight + $materialExtra; 3537 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 3538 3539 //needs scroll? 3540 if ( contentHeight > windowsHeight+5 && $(element).find('.nectar-slider-wrap[data-fullscreen="true"]').length == 0 && !($(window).width() > 1000 && $fpScrollOverflow == false) ) { 3541 3542 3543 //was there already an scroll ? Updating it 3544 if(scrollable.length){ 3545 scrollOverflowHandler.update(element, scrollHeight); 3546 } 3547 //creating the scrolling 3548 else{ 3549 3550 if(options.verticalCentered){ 3551 element.find(TABLE_CELL_SEL).wrapInner(wrap); 3552 }else{ 3553 element.wrapInner(wrap); 3554 } 3555 scrollOverflowHandler.create(element, scrollHeight); 3556 } 3557 } 3558 //removing the scrolling when it is not necessary anymore 3559 else{ 3560 scrollOverflowHandler.remove(element); 3561 } 3562 3563 //undo 3564 element.css('overflow', ''); 3565 } 3566 3567 function addTableClass(element){ 3568 /*nectar addition - front end editor*/ 3569 if(window.vc_iframe) { 3570 element.addClass(TABLE).find('> .wpb_row').wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 3571 } else { 3572 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 3573 } 3574 } 3575 3576 function getTableHeight(element){ 3577 var sectionHeight = windowsHeight; 3578 3579 if(options.paddingTop || options.paddingBottom){ 3580 var section = element; 3581 if(!section.hasClass(SECTION)){ 3582 section = element.closest(SECTION_SEL); 3583 } 3584 3585 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 3586 sectionHeight = (windowsHeight - paddings); 3587 } 3588 3589 return sectionHeight; 3590 } 3591 3592 /** 3593 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 3594 */ 3595 function transformContainer(translate3d, animated){ 3596 if(animated){ 3597 addAnimation(container); 3598 }else{ 3599 removeAnimation(container); 3600 } 3601 3602 container.css(getTransforms(translate3d)); 3603 3604 //syncronously removing the class after the animation has been applied. 3605 setTimeout(function(){ 3606 container.removeClass(NO_TRANSITION); 3607 },10); 3608 } 3609 3610 /** 3611 * Gets a section by its anchor / index 3612 */ 3613 function getSectionByAnchor(sectionAnchor){ 3614 //section 3615 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 3616 if(!section.length){ 3617 section = $(SECTION_SEL).eq( (sectionAnchor -1) ); 3618 } 3619 3620 return section; 3621 } 3622 3623 /** 3624 * Gets a slide inside a given section by its anchor / index 3625 */ 3626 function getSlideByAnchor(slideAnchor, section){ 3627 var slides = section.find(SLIDES_WRAPPER_SEL); 3628 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 3629
3630 if(!slide.length){ 3631 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 3632 } 3633 3634 return slide; 3635 } 3636 3637 /** 3638 * Scrolls to the given section and slide anchors 3639 */ 3640 function scrollPageAndSlide(destiny, slide){ 3641 var section = getSectionByAnchor(destiny); 3642 3643 //default slide 3644 if (typeof slide === 'undefined') { 3645 slide = 0; 3646 } 3647 3648 //we need to scroll to the section and then to the slide 3649 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 3650 scrollPage(section, function(){ 3651 scrollSlider(section, slide); 3652 }); 3653 } 3654 //if we were already in the section 3655 else{ 3656 scrollSlider(section, slide); 3657 } 3658 } 3659 3660 /** 3661 * Scrolls the slider to the given slide destination for the given section 3662 */ 3663 function scrollSlider(section, slideAnchor){ 3664 if(typeof slideAnchor !== 'undefined'){ 3665 var slides = section.find(SLIDES_WRAPPER_SEL); 3666 var destiny = getSlideByAnchor(slideAnchor, section); 3667 3668 if(destiny.length){ 3669 landscapeScroll(slides, destiny); 3670 } 3671 } 3672 } 3673 3674 /** 3675 * Creates a landscape navigation bar with dots for horizontal sliders. 3676 */ 3677 function addSlidesNavigation(section, numSlides){ 3678 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 3679 var nav = section.find(SLIDES_NAV_SEL); 3680 3681 //top or bottom 3682 nav.addClass(options.slidesNavPosition); 3683 3684 for(var i=0; i< numSlides; i++){ 3685 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 3686 } 3687 3688 //centering it 3689 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 3690 3691 nav.find('li').first().find('a').addClass(ACTIVE); 3692 } 3693 3694 3695 /** 3696 * Sets the state of the website depending on the active section/slide. 3697 * It changes the URL hash when needed and updates the body class. 3698 */ 3699 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 3700 var sectionHash = ''; 3701 3702 if(options.anchors.length && !options.lockAnchors){ 3703 3704 //isn't it the first slide? 3705 if(slideIndex){ 3706 if(typeof anchorLink !== 'undefined'){ 3707 sectionHash = anchorLink; 3708 } 3709 3710 //slide without anchor link? We take the index instead. 3711 if(typeof slideAnchor === 'undefined'){ 3712 slideAnchor = slideIndex; 3713 } 3714 3715 lastScrolledSlide = slideAnchor; 3716 setUrlHash(sectionHash + '/' + slideAnchor); 3717 3718 //first slide won't have slide anchor, just the section one 3719 }else if(typeof slideIndex !== 'undefined'){ 3720 lastScrolledSlide = slideAnchor; 3721 setUrlHash(anchorLink); 3722 } 3723 3724 //section without slides 3725 else{ 3726 3727 // nectar addition - stop empty anchor sections (including footer) from causing page jump 3728 if(anchorLink) { 3729 setUrlHash(anchorLink); 3730 } 3731 // nectar addition end 3732 3733 } 3734 } 3735 3736 setBodyClass(); 3737 } 3738 3739 /** 3740 * Sets the URL hash. 3741 */ 3742 function setUrlHash(url){ 3743 if(options.recordHistory){ 3744 location.hash = url; 3745 }else{ 3746 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 3747 if(isTouchDevice || isTouch){ 3748 window.history.replaceState(undefined, undefined, '#' + url); 3749 }else{ 3750 var baseUrl = window.location.href.split('#')[0]; 3751 window.location.replace( baseUrl + '#' + url ); 3752 } 3753 } 3754 } 3755 3756 /**
3757 * Gets the anchor for the given slide / section. Its index will be used if there's none. 3758 */ 3759 function getAnchor(element){ 3760 var anchor = element.data('anchor'); 3761 var index = element.index(); 3762 3763 //Slide without anchor link? We take the index instead. 3764 if(typeof anchor === 'undefined'){ 3765 anchor = index; 3766 } 3767 3768 return anchor; 3769 } 3770 3771 /** 3772 * Sets a class for the body of the page depending on the active section / slide 3773 */ 3774 function setBodyClass(){ 3775 /* nectar addition */ 3776 /* 3777 var section = $(SECTION_ACTIVE_SEL); 3778 var slide = section.find(SLIDE_ACTIVE_SEL); 3779 3780 var sectionAnchor = getAnchor(section); 3781 var slideAnchor = getAnchor(slide); 3782 3783 var text = String(sectionAnchor); 3784 3785 if(slide.length){ 3786 text = text + '-' + slideAnchor; 3787 } 3788 3789 //changing slash for dash to make it a valid CSS style 3790 text = text.replace('/', '-').replace('#',''); 3791 3792 //removing previous anchor classes 3793 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 3794 $body[0].className = $body[0].className.replace(classRe, ''); 3795 3796 //adding the current anchor 3797 $body.addClass(VIEWING_PREFIX + '-' + text); 3798 */ 3799 } 3800 3801 /** 3802 * Checks for translate3d support 3803 * @return boolean 3804 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 3805 */ 3806 function support3d() { 3807 var el = document.createElement('p'), 3808 has3d, 3809 transforms = { 3810 'webkitTransform':'-webkit-transform', 3811 'OTransform':'-o-transform', 3812 'msTransform':'-ms-transform', 3813 'MozTransform':'-moz-transform', 3814 'transform':'transform' 3815 }; 3816 3817 // Add it to the body to get the computed style. 3818 document.body.insertBefore(el, null); 3819 3820 for (var t in transforms) { 3821 if (el.style[t] !== undefined) { 3822 el.style[t] = 'translate3d(1px,1px,1px)'; 3823 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 3824 } 3825 } 3826 3827 document.body.removeChild(el); 3828 3829 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 3830 } 3831 3832 /** 3833 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 3834 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 3835 */ 3836 function removeMouseWheelHandler(){ 3837 if (document.addEventListener) { 3838 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 3839 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 3840 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 3841 } else { 3842 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 3843 } 3844 } 3845 3846 /** 3847 * Adds the auto scrolling action for the mouse wheel and trackpad. 3848 * After this function is called, the mousewheel and trackpad movements will scroll through sections 3849 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 3850 */ 3851 function addMouseWheelHandler(){ 3852 var prefix = ''; 3853 var _addEventListener; 3854 3855 if (window.addEventListener){ 3856 _addEventListener = "addEventListener"; 3857 }else{ 3858 _addEventListener = "attachEvent"; 3859 prefix = 'on'; 3860 } 3861 3862 // detect available wheel event 3863 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 3864 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 3865 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 3866 3867 3868 if(support == 'DOMMouseScroll'){ 3869 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, false); 3870 } 3871 3872 //handle MozMousePixelScroll in older Firefox 3873 else{ 3874 document[ _addEventListener ](prefix + support, MouseWheelHandler, false); 3875 } 3876 } 3877 3878 /** 3879 * Binding the mousemove when the mouse's middle button is pressed 3880 */ 3881 function addMiddleWheelHandler(){ 3882 container 3883 .on('mousedown', mouseDownHandler) 3884 .on('mouseup', mouseUpHandler); 3885 } 3886 3887 /** 3888 * Unbinding the mousemove when the mouse's middle button is released 3889 */ 3890 function removeMiddleWheelHandler(){ 3891 container 3892 .off('mousedown', mouseDownHandler) 3893 .off('mouseup', mouseUpHandler); 3894 } 3895 3896 /** 3897 * Adds the possibility to auto scroll through sections on touch devices. 3898 */ 3899 function addTouchHandler(){ 3900 if(isTouchDevice || isTouch){ 3901 //Microsoft pointers 3902 var MSPointer = getMSPointer(); 3903 3904 $(WRAPPER_SEL).off('touchstart ' + MSPointer.down).on('touchstart ' + MSPointer.down, touchStartHandler); 3905 $(WRAPPER_SEL).off('touchmove ' + MSPointer.move).on('touchmove ' + MSPointer.move, touchMoveHandler); 3906 } 3907 } 3908 3909 /** 3910 * Removes the auto scrolling for touch devices. 3911 */ 3912 function removeTouchHandler(){ 3913 if(isTouchDevice || isTouch){ 3914 //Microsoft pointers 3915 var MSPointer = getMSPointer(); 3916 3917 $(WRAPPER_SEL).off('touchstart ' + MSPointer.down); 3918 $(WRAPPER_SEL).off('touchmove ' + MSPointer.move); 3919 } 3920 } 3921 3922 /* 3923 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
3924 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 3925 */ 3926 function getMSPointer(){ 3927 var pointer; 3928 3929 //IE >= 11 & rest of browsers 3930 if(window.PointerEvent){ 3931 pointer = { down: 'pointerdown', move: 'pointermove'}; 3932 } 3933 3934 //IE < 11 3935 else{ 3936 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 3937 } 3938 3939 return pointer; 3940 } 3941 3942 /** 3943 * Gets the pageX and pageY properties depending on the browser. 3944 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 3945 */ 3946 function getEventsPage(e){ 3947 var events = []; 3948 3949 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 3950 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 3951 3952 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 3953 if(isTouch && isReallyTouch(e) && options.scrollBar){ 3954 events.y = e.touches[0].pageY; 3955 events.x = e.touches[0].pageX; 3956 } 3957 3958 return events; 3959 } 3960 3961 /** 3962 * Slides silently (with no animation) the active slider to the given slide. 3963 */ 3964 function silentLandscapeScroll(activeSlide, noCallbacks){ 3965 FP.setScrollingSpeed (0, 'internal'); 3966 3967 if(typeof noCallbacks !== 'undefined'){ 3968 //preventing firing callbacks afterSlideLoad etc. 3969 isResizing = true; 3970 } 3971 3972 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 3973 3974 if(typeof noCallbacks !== 'undefined'){ 3975 isResizing = false; 3976 } 3977 3978 FP.setScrollingSpeed(originals.scrollingSpeed, 'internal'); 3979 } 3980 3981 /** 3982 * Scrolls silently (with no animation) the page to the given Y position. 3983 */ 3984 function silentScroll(top){ 3985 if(options.scrollBar){ 3986 container.scrollTop(top); 3987 } 3988 else if (options.css3) { 3989 var translate3d = 'translate3d(0px, -' + top + 'px, 0px)'; 3990 transformContainer(translate3d, false); 3991 } 3992 else { 3993 container.css('top', -top); 3994 } 3995 } 3996 3997 /** 3998 * Returns the cross-browser transform string. 3999 */ 4000 function getTransforms(translate3d){ 4001 return { 4002 '-webkit-transform': translate3d, 4003 '-moz-transform': translate3d, 4004 '-ms-transform':translate3d, 4005 'transform': translate3d 4006 }; 4007 } 4008 4009 /** 4010 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 4011 * @type m (mouse) or k (keyboard) 4012 */ 4013 function setIsScrollAllowed(value, direction, type){ 4014 switch (direction){ 4015 case 'up': isScrollAllowed[type].up = value; break; 4016 case 'down': isScrollAllowed[type].down = value; break; 4017 case 'left': isScrollAllowed[type].left = value; break; 4018 case 'right': isScrollAllowed[type].right = value; break; 4019 case 'all': 4020 if(type == 'm'){ 4021 FP.setAllowScrolling(value); 4022 }else{ 4023 FP.setKeyboardScrolling(value); 4024 } 4025 } 4026 } 4027 4028 /* 4029 * Destroys fullpage.js plugin events and optinally its html markup and styles 4030 */ 4031 FP.destroy = function(all){ 4032 FP.setAutoScrolling(false, 'internal'); 4033 FP.setAllowScrolling(false); 4034 FP.setKeyboardScrolling(false); 4035 container.addClass(DESTROYED); 4036 4037 clearTimeout(afterSlideLoadsId); 4038 clearTimeout(afterSectionLoadsId); 4039 clearTimeout(resizeId); 4040 clearTimeout(scrollId); 4041 clearTimeout(scrollId2); 4042 4043 $window 4044 .off('scroll', scrollHandler) 4045 .off('hashchange', hashChangeHandler) 4046 .off('resize', resizeHandler); 4047 4048 $document 4049 .off('click', SECTION_NAV_SEL + ' a') 4050 .off('mouseenter', SECTION_NAV_SEL + ' li') 4051 .off('mouseleave', SECTION_NAV_SEL + ' li') 4052 .off('click', SLIDES_NAV_LINK_SEL) 4053 .off('mouseover', options.normalScrollElements) 4054 .off('mouseout', options.normalScrollElements); 4055 4056 $(SECTION_SEL) 4057 .off('click', SLIDES_ARROW_SEL); 4058 4059 clearTimeout(afterSlideLoadsId); 4060 clearTimeout(afterSectionLoadsId); 4061 4062 //lets make a mess! 4063 if(all){ 4064 destroyStructure(); 4065 } 4066 }; 4067 4068 /* 4069 * Removes inline styles added by fullpage.js 4070 */ 4071 function destroyStructure(){ 4072 //reseting the `top` or `translate` properties to 0 4073 silentScroll(0); 4074 4075 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 4076 4077 //removing inline styles 4078 $(SECTION_SEL).css( { 4079 'height': '', 4080 'background-color' : '', 4081 'padding': '' 4082 }); 4083 4084 $(SLIDE_SEL).css( { 4085 'width': '' 4086 }); 4087 4088 container.css({ 4089 'height': '', 4090 'position': '',
4091 '-ms-touch-action': '', 4092 'touch-action': '' 4093 }); 4094 4095 $htmlBody.css({ 4096 'overflow': '', 4097 'height': '' 4098 }); 4099 4100 // remove .fp-enabled class 4101 $('html').removeClass(ENABLED); 4102 4103 // remove all of the .fp-viewing- classes 4104 $.each($body.get(0).className.split(/\s+/), function (index, className) { 4105 if (className.indexOf(VIEWING_PREFIX) === 0) { 4106 $body.removeClass(className); 4107 } 4108 }); 4109 4110 //removing added classes 4111 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 4112 options.scrollOverflowHandler.remove($(this)); 4113 $(this).removeClass(TABLE + ' ' + ACTIVE); 4114 }); 4115 4116 removeAnimation(container); 4117 4118 //Unwrapping content 4119 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 4120 //unwrap not being use in case there's no child element inside and its just text 4121 $(this).replaceWith(this.childNodes); 4122 }); 4123 4124 //scrolling the page to the top with no animation 4125 $htmlBody.scrollTop(0); 4126 4127 //removing selectors 4128 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 4129 $.each(usedSelectors, function(index, value){ 4130 $('.' + value).removeClass(value); 4131 }); 4132 } 4133 4134 /* 4135 * Sets the state for a variable with multiple states (original, and temporal) 4136 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 4137 * This function is used to keep track of both states, the original and the temporal one. 4138 * If type is not 'internal', then we assume the user is globally changing the variable. 4139 */ 4140 function setVariableState(variable, value, type){ 4141 options[variable] = value; 4142 if(type !== 'internal'){ 4143 originals[variable] = value; 4144 } 4145 } 4146 4147 /** 4148 * Displays warnings 4149 */ 4150 function displayWarnings(){ 4151 if($('html').hasClass(ENABLED)){ 4152 showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 4153 return; 4154 } 4155 4156 // Disable mutually exclusive settings 4157 if (options.continuousVertical && 4158 (options.loopTop || options.loopBottom)) { 4159 options.continuousVertical = false;
4160 showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 4161 } 4162 4163 if(options.scrollBar && options.scrollOverflow){ 4164 showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 4165 } 4166 4167 if(options.continuousVertical && options.scrollBar){ 4168 options.continuousVertical = false; 4169 showError('warn', 'Option `scrollBar` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 4170 } 4171 4172 //anchors can not have the same value as any element ID or NAME 4173 $.each(options.anchors, function(index, name){ 4174 4175 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 4176 var nameAttr = $document.find('[name]').filter(function() { 4177 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 4178 }); 4179 4180 var idAttr = $document.find('[id]').filter(function() { 4181 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 4182 }); 4183 4184 if(idAttr.length || nameAttr.length ){ 4185 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 4186 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 4187 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 4188 } 4189 }); 4190 } 4191 4192 /** 4193 * Shows a message in the console of the given type. 4194 */ 4195 function showError(type, text){ 4196 console && console[type] && console[type]('fullPage: ' + text); 4197 } 4198 }; //end of $.fn.fullpage 4199 4200 if(typeof IScroll !== 'undefined'){ 4201 /* 4202 * Turns iScroll `mousewheel` option off dynamically 4203 * https://github.com/cubiq/iscroll/issues/1036 4204 */ 4205 IScroll.prototype.wheelOn = function () { 4206 this.wrapper.addEventListener('wheel', this); 4207 this.wrapper.addEventListener('mousewheel', this); 4208 this.wrapper.addEventListener('DOMMouseScroll', this); 4209 }; 4210 4211 /* 4212 * Turns iScroll `mousewheel` option on dynamically 4213 * https://github.com/cubiq/iscroll/issues/1036 4214 */ 4215 IScroll.prototype.wheelOff = function () { 4216 this.wrapper.removeEventListener('wheel', this); 4217 this.wrapper.removeEventListener('mousewheel', this); 4218 this.wrapper.removeEventListener('DOMMouseScroll', this); 4219 }; 4220 } 4221 4222 /** 4223 * An object to handle overflow scrolling. 4224 * This uses jquery.slimScroll to accomplish overflow scrolling. 4225 * It is possible to pass in an alternate scrollOverflowHandler 4226 * to the fullpage.js option that implements the same functions 4227 * as this handler. 4228 * 4229 * @type {Object} 4230 */ 4231 var iscrollHandler = { 4232 refreshId: null, 4233 iScrollInstances: [], 4234 4235 /** 4236 * Turns off iScroll for the destination section. 4237 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would 4238 * scroll the destination section/slide before the sections animations ends. 4239 */ 4240 onLeave: function(){ 4241 var scroller = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL).data('iscrollInstance'); 4242 4243 if(typeof scroller !== 'undefined' && scroller){ 4244 scroller.wheelOff(); 4245 } 4246 4247 4248 }, 4249 4250 // Turns on iScroll on section load 4251 afterLoad: function(){ 4252 4253 var scroller = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL).data('iscrollInstance'); 4254 if(typeof scroller !== 'undefined' && scroller){ 4255 scroller.wheelOn(); 4256 } 4257 }, 4258 4259 /** 4260 * Called when overflow scrolling is needed for a section. 4261 * 4262 * @param {Object}
4262 element jQuery object containing current section 4263 * @param {Number} scrollHeight Current window height in pixels 4264 */ 4265 create: function(element, scrollHeight) { 4266 var scrollable = element.find(SCROLLABLE_SEL); 4267 4268 scrollable.height(scrollHeight); 4269 scrollable.each(function() { 4270 var $this = jQuery(this); 4271 var iScrollInstance = $this.data('iscrollInstance'); 4272 if (iScrollInstance) { 4273 $.each(iscrollHandler.iScrollInstances, function(){ 4274 $(this).destroy(); 4275 }); 4276 } 4277 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 4278 iscrollHandler.iScrollInstances.push(iScrollInstance); 4279 $this.data('iscrollInstance', iScrollInstance); 4280 }); 4281 }, 4282 4283 /** 4284 * Return a boolean depending on whether the scrollable element is a 4285 * the end or at the start of the scrolling depending on the given type. 4286 * 4287 * @param {String} type Either 'top' or 'bottom' 4288 * @param {Object} scrollable jQuery object for the scrollable element 4289 * @return {Boolean} 4290 */ 4291 isScrolled: function(type, scrollable) { 4292 var scroller = scrollable.data('iscrollInstance'); 4293 4294 if (!scroller) { 4295 return false; 4296 } 4297 4298 /* nectar addition */ 4299 if (type === 'top') { 4300 $('#nectar_fullscreen_rows').addClass('nextSectionAllowed'); 4301 return scroller.y >= 0 && !scrollable.scrollTop(); 4302 } else if (type === 'bottom') { 4303 4304 //also changed >= scrollable[0].scrollHeight-4 to scrollable.find('.fp-scroller').height()-4 4305 return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable.find('.fp-scroller').height() - 4; 4306 } 4307 /* nectar addition end */ 4308 }, 4309 4310 /** 4311 * Returns the scrollable element for the given section. 4312 * If there are landscape slides, will only return a scrollable element 4313 * if it is in the active slide. 4314 * 4315 * @param {Object} activeSection jQuery object containing current section 4316 * @return {Boolean} 4317 */ 4318 scrollable: function(activeSection){ 4319 // if there are landscape slides, we check if the scrolling bar is in the current one or not 4320 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 4321 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 4322 } 4323 return activeSection.find(SCROLLABLE_SEL); 4324 }, 4325 4326 /** 4327 * Returns the scroll height of the wrapped content. 4328 * If this is larger than the window height minus section padding, 4329 * overflow scrolling is needed. 4330 * 4331 * @param {Object} element jQuery object containing current section 4332 * @return {Number} 4333 */ 4334 scrollHeight: function(element) { 4335 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 4336 }, 4337 4338 /** 4339 * Called when overflow scrolling is no longer needed for a section. 4340 * 4341 * @param {Object} element jQuery object containing current section 4342 */ 4343 remove: function(element) { 4344 var scrollable = element.find(SCROLLABLE_SEL); 4345 if (scrollable.length) { 4346 var iScrollInstance = scrollable.data('iscrollInstance'); 4347 iScrollInstance.destroy(); 4348 4349 scrollable.data('iscrollInstance', 'undefined'); 4350 } 4351 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 4352 }, 4353 4354 /** 4355 * Called when overflow scrolling has already been setup but the 4356 * window height has potentially changed. 4357 * 4358 * @param {Object} element jQuery object containing current section 4359 * @param {Number} scrollHeight Current window height in pixels 4360 */ 4361 update: function(element, scrollHeight) { 4362 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 4363 //short period of time. 4364 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 4365 clearTimeout(iscrollHandler.refreshId); 4366 iscrollHandler.refreshId = setTimeout(function(){ 4367 $.each(iscrollHandler.iScrollInstances, function(){ 4368 $(this).get(0).refresh(); 4369 }); 4370 }, 150); 4371 4372 //updating the wrappers height 4373 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 4374 }, 4375 4376 /** 4377 * Called to get any additional elements needed to wrap the section 4378 * content in order to facilitate overflow scrolling. 4379 * 4380 * @return {String|Object} Can be a string containing HTML, 4381 * a DOM element, or jQuery object. 4382 */ 4383 wrapContent: function() { 4384 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 4385 } 4386 }; 4387 4388});
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.