PageSourceSearch

https://gestorderesiduosmadrid.es/wp-content/themes/gogreen/js/smoothscroll.js?ver=1.0

js gestorderesiduosmadrid.es collected 2026-10-05 21:45:36 UTC 21,314 bytes, 727 lines download raw bytes

1//
2// SmoothScroll for websites v1.4.4 (Balazs Galambosi)
3// http://www.smoothscroll.net/
4//
5// Licensed under the terms of the MIT license.
6//
7// You may use it in your theme if you credit me. 
8// It is also free to use on any individual website.
9//
10// Exception:
11// The only restriction is to not publish any  
12// extension for browsers or native application
13// without getting a written permission first.
14//
15
16if( window.wyde && wyde.page.smooth_scroll ) {
17
18(function () {
19  
20// Scroll Variables (tweakable)
21var defaultOptions = {
22
23    // Scrolling Core
24    frameRate        : 150, // [Hz]
25    animationTime    : 800, // [ms]
26    stepSize         : 150, // [px]
27
28    // Pulse (less tweakable)
29    // ratio of "tail" to "acceleration"
30    pulseAlgorithm   : true,
31    pulseScale       : 6,
32    pulseNormalize   : 1,
33
34    // Acceleration
35    accelerationDelta : 20,  // 50
36    accelerationMax   : 1,   // 3
37
38    // Keyboard Settings
39    keyboardSupport   : true,  // option
40    arrowScroll       : 50,    // [px]
41
42    // Other
43    touchpadSupport   : false, // ignore touchpad by default
44    fixedBackground   : true, 
45    excluded          : ''    
46};
47
48var options = defaultOptions;
49
50
51// Other Variables
52var isExcluded = false;
53var isFrame = false;
54var direction = { x: 0, y: 0 };
55var initDone  = false;
56var root = document.documentElement;
57var activeElement;
58var observer;
59var refreshSize;
60var deltaBuffer = [];
61var isMac = /^Mac/.test(navigator.platform);
62
63var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, 
64            pageup: 33, pagedown: 34, end: 35, home: 36 };
65
66
67/***********************************************
68 * INITIALIZE
69 ***********************************************/
70
71/**
72 * Tests if smooth scrolling is allowed. Shuts down everything if not.
73 */
74function initTest() {
75    if (options.keyboardSupport) {
76        addEvent('keydown', keydown);
77    }
78}
79
80/**
81 * Sets up scrolls array, determines if frames are involved.
82 */
83function init() {
84  
85    if (initDone || !document.body) return;
86
87    initDone = true;
88
89    var body = document.body;
90    var html = document.documentElement;
91    var windowHeight = window.innerHeight; 
92    var scrollHeight = body.scrollHeight;
93    
94    // check compat mode for root element
95    root = (document.compatMode.indexOf('CSS') >= 0) ? html : body;
96    activeElement = body;
97    
98    initTest();
99
100    // Checks if this script is running in a frame
101    if (top != self) {
102        isFrame = true;
103    }
104
105    /**
106     * Please duplicate this radar for a Safari fix! 
107     * rdar://22376037
108     * https://openradar.appspot.com/radar?id=4965070979203072
109     * 
110     * Only applies to Safari now, Chrome fixed it in v45:
111     * This fixes a bug where the areas left and right to 
112     * the content does not trigger the onmousewheel event
113     * on some pages. e.g.: html, body { height: 100% }
114     */
115    else if (scrollHeight > windowHeight &&
116            (body.offsetHeight <= windowHeight || 
117             html.offsetHeight <= windowHeight)) {
118
119        var fullPageElem = document.createElement('div');
120        fullPageElem.style.cssText = 'position:absolute; z-index:-10000; ' +
121                                     'top:0; left:0; right:0; height:' + 
122                                      root.scrollHeight + 'px';
123        document.body.appendChild(fullPageElem);
124        
125        // DOM changed (throttled) to fix height
126        var pendingRefresh;
127        refreshSize = function () {
128            if (pendingRefresh) return; // could also be: clearTimeout(pendingRefresh);
129            pendingRefresh = setTimeout(function () {
130                if (isExcluded) return; // could be running after cleanup
131                fullPageElem.style.height = '0';
132                fullPageElem.style.height = root.scrollHeight + 'px';
133                pendingRefresh = null;
134            }, 500); // act rarely to stay fast
135        };
136  
137        setTimeout(refreshSize, 10);
138
139        addEvent('resize', refreshSize);
140
141        // TODO: attributeFilter?
142        var config = {
143            attributes: true, 
144            childList: true, 
145            characterData: false 
146            // subtree: true
147        };
148
149        observer = new MutationObserver(refreshSize);
150        observer.observe(body, config);
151
152        if (root.offsetHeight <= windowHeight) {
153            var clearfix = document.createElement('div');   
154            clearfix.style.clear = 'both';
155            body.appendChild(clearfix);
156        }
157    }
158
159    // disable fixed background
vendor: 5,352 bytes, lines 160-349
160    if (!options.fixedBackground && !isExcluded) {
161        body.style.backgroundAttachment = 'scroll';
162        html.style.backgroundAttachment = 'scroll';
163    }
164}
165
166/**
167 * Removes event listeners and other traces left on the page.
168 */
169function cleanup() {
170    observer && observer.disconnect();
171    removeEvent(wheelEvent, wheel);
172    removeEvent('mousedown', mousedown);
173    removeEvent('keydown', keydown);
174    removeEvent('resize', refreshSize);
175    removeEvent('load', init);
176}
177
178
179/************************************************
180 * SCROLLING 
181 ************************************************/
182 
183var que = [];
184var pending = false;
185var lastScroll = Date.now();
186
187/**
188 * Pushes scroll actions to the scrolling queue.
189 */
190function scrollArray(elem, left, top) {
191    
192    directionCheck(left, top);
193
194    if (options.accelerationMax != 1) {
195        var now = Date.now();
196        var elapsed = now - lastScroll;
197        if (elapsed < options.accelerationDelta) {
198            var factor = (1 + (50 / elapsed)) / 2;
199            if (factor > 1) {
200                factor = Math.min(factor, options.accelerationMax);
201                left *= factor;
202                top  *= factor;
203            }
204        }
205        lastScroll = Date.now();
206    }          
207    
208    // push a scroll command
209    que.push({
210        x: left, 
211        y: top, 
212        lastX: (left < 0) ? 0.99 : -0.99,
213        lastY: (top  < 0) ? 0.99 : -0.99, 
214        start: Date.now()
215    });
216        
217    // don't act if there's a pending queue
218    if (pending) {
219        return;
220    }  
221
222    var scrollWindow = (elem === document.body);
223    
224    var step = function (time) {
225        
226        var now = Date.now();
227        var scrollX = 0;
228        var scrollY = 0; 
229    
230        for (var i = 0; i < que.length; i++) {
231            
232            var item = que[i];
233            var elapsed  = now - item.start;
234            var finished = (elapsed >= options.animationTime);
235            
236            // scroll position: [0, 1]
237            var position = (finished) ? 1 : elapsed / options.animationTime;
238            
239            // easing [optional]
240            if (options.pulseAlgorithm) {
241                position = pulse(position);
242            }
243            
244            // only need the difference
245            var x = (item.x * position - item.lastX) >> 0;
246            var y = (item.y * position - item.lastY) >> 0;
247            
248            // add this to the total scrolling
249            scrollX += x;
250            scrollY += y;            
251            
252            // update last values
253            item.lastX += x;
254            item.lastY += y;
255        
256            // delete and step back if it's over
257            if (finished) {
258                que.splice(i, 1); i--;
259            }           
260        }
261
262        // scroll left and top
263        if (scrollWindow) {
264            window.scrollBy(scrollX, scrollY);
265        } 
266        else {
267            if (scrollX) elem.scrollLeft += scrollX;
268            if (scrollY) elem.scrollTop  += scrollY;                    
269        }
270        
271        // clean up if there's nothing left to do
272        if (!left && !top) {
273            que = [];
274        }
275        
276        if (que.length) { 
277            requestFrame(step, elem, (1000 / options.frameRate + 1)); 
278        } else { 
279            pending = false;
280        }
281    };
282    
283    // start a new queue of actions
284    requestFrame(step, elem, 0);
285    pending = true;
286}
287
288
289/***********************************************
290 * EVENTS
291 ***********************************************/
292
293/**
294 * Mouse wheel handler.
295 * @param {Object} event
296 */
297function wheel(event) {
298
299    if (!initDone) {
300        init();
301    }
302    
303    var target = event.target;
304    var overflowing = overflowingAncestor(target);
305
306    // use default if there's no overflowing
307    // element or default action is prevented   
308    // or it's a zooming event with CTRL 
309    if (!overflowing || event.defaultPrevented || event.ctrlKey) {
310        return true;
311    }
312    
313    // leave embedded content alone (flash & pdf)
314    if (isNodeName(activeElement, 'embed') || 
315       (isNodeName(target, 'embed') && /\.pdf/i.test(target.src)) ||
316       isNodeName(activeElement, 'object')) {
317        return true;
318    }
319
320    var deltaX = -event.wheelDeltaX || event.deltaX || 0;
321    var deltaY = -event.wheelDeltaY || event.deltaY || 0;
322    
323    if (isMac) {
324        if (event.wheelDeltaX && isDivisible(event.wheelDeltaX, 120)) {
325            deltaX = -120 * (event.wheelDeltaX / Math.abs(event.wheelDeltaX));
326        }
327        if (event.wheelDeltaY && isDivisible(event.wheelDeltaY, 120)) {
328            deltaY = -120 * (event.wheelDeltaY / Math.abs(event.wheelDeltaY));
329        }
330    }
331    
332    // use wheelDelta if deltaX/Y is not available
333    if (!deltaX && !deltaY) {
334        deltaY = -event.wheelDelta || 0;
335    }
336
337    // line based scrolling (Firefox mostly)
338    if (event.deltaMode === 1) {
339        deltaX *= 40;
340        deltaY *= 40;
341    }
342    
343    // check if it's a touchpad scroll that should be ignored
344    if (!options.touchpadSupport && isTouchpad(deltaY)) {
345        return true;
346    }
347
348    // scale by step size
349    // delta is 120 most of the time
350    // synaptics seems to send 1 sometimes
351    if (Math.abs(deltaX) > 1.2) {
352        deltaX *= options.stepSize / 120;
353    }
354    if (Math.abs(deltaY) > 1.2) {
355        deltaY *= options.stepSize / 120;
356    }
357    
358    scrollArray(overflowing, deltaX, deltaY);
359    event.preventDefault();
360    scheduleClearCache();
361}
362
363/**
364 * Keydown event handler.
365 * @param {Object} event
366 */
367function keydown(event) {
368
369    var target   = event.target;
370    var modifier = event.ctrlKey || event.altKey || event.metaKey || 
371                  (event.shiftKey && event.keyCode !== key.spacebar);
372    
373    // our own tracked active element could've been removed from the DOM
374    if (!document.body.contains(activeElement)) {
375        activeElement = document.activeElement;
376    }
377
378    // do nothing if user is editing text
379    // or using a modifier key (except shift)
380    // or in a dropdown
381    // or inside interactive elements
382    var inputNodeNames = /^(textarea|select|embed|object)$/i;
383    var buttonTypes = /^(button|submit|radio|checkbox|file|color|image)$/i;
384    if ( inputNodeNames.test(target.nodeName) ||
385         isNodeName(target, 'input') && !buttonTypes.test(target.type) ||
386         isNodeName(activeElement, 'video') ||
387         isInsideYoutubeVideo(event) ||
388         target.isContentEditable || 
389         event.defaultPrevented   ||
390         modifier ) {
391      return true;
392    }
393    
394    // spacebar should trigger button press
395    if ((isNodeName(target, 'button') ||
396         isNodeName(target, 'input') && buttonTypes.test(target.type)) &&
397        event.keyCode === key.spacebar) {
398      return true;
399    }
400    
401    var shift, x = 0, y = 0;
402    var elem = overflowingAncestor(activeElement);
403    var clientHeight = elem.clientHeight;
404
405    if (elem == document.body) {
406        clientHeight = window.innerHeight;
407    }
408
409    switch (event.keyCode) {
410        case key.up:
411            y = -options.arrowScroll;
412            break;
413        case key.down:
414            y = options.arrowScroll;
415            break;         
416        case key.spacebar: // (+ shift)
417            shift = event.shiftKey ? 1 : -1;
418            y = -shift * clientHeight * 0.9;
419            break;
420        case key.pageup:
421            y = -clientHeight * 0.9;
422            break;
423        case key.pagedown:
424            y = clientHeight * 0.9;
425            break;
426        case key.home:
427            y = -elem.scrollTop;
428            break;
429        case key.end:
430            var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
431            y = (damt > 0) ? damt+10 : 0;
432            break;
433        case key.left:
434            x = -options.arrowScroll;
435            break;
436        case key.right:
437            x = options.arrowScroll;
438            break;            
439        default:
440            return true; // a key we don't care about
441    }
442
443    scrollArray(elem, x, y);
444    event.preventDefault();
445    scheduleClearCache();
446}
447
448/**
449 * Mousedown event only for updating activeElement
450 */
451function mousedown(event) {
452    activeElement = event.target;
453}
454
455
456/***********************************************
457 * OVERFLOW
458 ***********************************************/
459
460var uniqueID = (function () {
461    var i = 0;
462    return function (el) {
463        return el.uniqueID || (el.uniqueID = i++);
464    };
465})();
466
467var cache = {}; // cleared out after a scrolling session
468var clearCacheTimer;
469
470//setInterval(function () { cache = {}; }, 10 * 1000);
471
472function scheduleClearCache() {
473    clearTimeout(clearCacheTimer);
474    clearCacheTimer = setInterval(function () { cache = {}; }, 1*1000);
475}
476
477function setCache(elems, overflowing) {
478    for (var i = elems.length; i--;)
479        cache[uniqueID(elems[i])] = overflowing;
480    return overflowing;
481}
482
483//  (body)                (root)
484//         | hidden | visible | scroll |  auto  |
485// hidden  |   no   |    no   |   YES  |   YES  |
486// visible |   no   |   YES   |   YES  |   YES  |
487// scroll  |   no   |   YES   |   YES  |   YES  |
488// auto    |   no   |   YES   |   YES  |   YES  |
489
490function overflowingAncestor(el) {
491    var elems = [];
492    var body = document.body;
493    var rootScrollHeight = root.scrollHeight;
494    do {
495        var cached = cache[uniqueID(el)];
496        if (cached) {
497            return setCache(elems, cached);
498        }
499        elems.push(el);
500        if (rootScrollHeight === el.scrollHeight) {
501            var topOverflowsNotHidden = overflowNotHidden(root) && overflowNotHidden(body);
502            var isOverflowCSS = topOverflowsNotHidden || overflowAutoOrScroll(root);
503            if (isFrame && isContentOverflowing(root) || 
504               !isFrame && isOverflowCSS) {
505                return setCache(elems, getScrollRoot()); 
506            }
507        } else if (isContentOverflowing(el) && overflowAutoOrScroll(el)) {
508            return setCache(elems, el);
509        }
510    } while (el = el.parentElement);
511}
512
513function isContentOverflowing(el) {
514    return (el.clientHeight + 10 < el.scrollHeight);
515}
516
517// typically for <body> and <html>
518function overflowNotHidden(el) {
519    var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y');
520    return (overflow !== 'hidden');
521}
522
523// for all other elements
524function overflowAutoOrScroll(el) {
525    var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y');
526    return (overflow === 'scroll' || overflow === 'auto');
527}
528
529
530/***********************************************
531 * HELPERS
532 ***********************************************/
533
534function addEvent(type, fn) {
535    window.addEventListener(type, fn, false);
536}
537
538function removeEvent(type, fn) {
539    window.removeEventListener(type, fn, false);  
540}
541
542function isNodeName(el, tag) {
543    return (el.nodeName||'').toLowerCase() === tag.toLowerCase();
544}
545
546function directionCheck(x, y) {
547    x = (x > 0) ? 1 : -1;
548    y = (y > 0) ? 1 : -1;
549    if (direction.x !== x || direction.y !== y) {
550        direction.x = x;
551        direction.y = y;
552        que = [];
553        lastScroll = 0;
554    }
555}
556
557var deltaBufferTimer;
558
559if (window.localStorage && localStorage.SS_deltaBuffer) {
560    deltaBuffer = localStorage.SS_deltaBuffer.split(',');
561}
562
563function isTouchpad(deltaY) {
564    if (!deltaY) return;
565    if (!deltaBuffer.length) {
566        deltaBuffer = [deltaY, deltaY, deltaY];
567    }
568    deltaY = Math.abs(deltaY)
569    deltaBuffer.push(deltaY);
570    deltaBuffer.shift();
571    clearTimeout(deltaBufferTimer);
572    deltaBufferTimer = setTimeout(function () {
573        if (window.localStorage) {
574            localStorage.SS_deltaBuffer = deltaBuffer.join(',');
575        }
576    }, 1000);
577    return !allDeltasDivisableBy(120) && !allDeltasDivisableBy(100);
578} 
579
580function isDivisible(n, divisor) {
581    return (Math.floor(n / divisor) == n / divisor);
582}
583
584function allDeltasDivisableBy(divisor) {
585    return (isDivisible(deltaBuffer[0], divisor) &&
586            isDivisible(deltaBuffer[1], divisor) &&
587            isDivisible(deltaBuffer[2], divisor));
588}
589
590function isInsideYoutubeVideo(event) {
591    var elem = event.target;
592    var isControl = false;
593    if (document.URL.indexOf ('www.youtube.com/watch') != -1) {
594        do {
595            isControl = (elem.classList && 
596                         elem.classList.contains('html5-video-controls'));
597            if (isControl) break;
598        } while (elem = elem.parentNode);
599    }
600    return isControl;
601}
602
603var requestFrame = (function () {
604      return (window.requestAnimationFrame       || 
605              window.webkitRequestAnimationFrame || 
606              window.mozRequestAnimationFrame    ||
607              function (callback, element, delay) {
608                 window.setTimeout(callback, delay || (1000/60));
609             });
610})();
611
612var MutationObserver = (window.MutationObserver || 
613                        window.WebKitMutationObserver ||
614                        window.MozMutationObserver);  
615
616var getScrollRoot = (function() {
617  var SCROLL_ROOT;
618  return function() {
619    if (!SCROLL_ROOT) {
620      var dummy = document.createElement('div');
621      dummy.style.cssText = 'height:10000px;width:1px;';
622      document.body.appendChild(dummy);
623      var bodyScrollTop  = document.body.scrollTop;
624      var docElScrollTop = document.documentElement.scrollTop;
625      window.scrollBy(0, 3);
626      if (document.body.scrollTop != bodyScrollTop)
627        (SCROLL_ROOT = document.body);
628      else 
629        (SCROLL_ROOT = document.documentElement);
630      window.scrollBy(0, -3);
631      document.body.removeChild(dummy);
632    }
633    return SCROLL_ROOT;
634  };
635})();
636
637
638/***********************************************
639 * PULSE (by Michael Herf)
640 ***********************************************/
641 
642/**
643 * Viscous fluid with a pulse for part and decay for the rest.
644 * - Applies a fixed force over an interval (a damped acceleration), and
645 * - Lets the exponential bleed away the velocity over a longer interval
646 * - Michael Herf, http://stereopsis.com/stopping/
647 */
648function pulse_(x) {
649    var val, start, expx;
650    // test
651    x = x * options.pulseScale;
652    if (x < 1) { // acceleartion
653        val = x - (1 - Math.exp(-x));
654    } else {     // tail
655        // the previous animation ended here:
656        start = Math.exp(-1);
657        // simple viscous drag
658        x -= 1;
659        expx = 1 - Math.exp(-x);
660        val = start + (expx * (1 - start));
661    }
662    return val * options.pulseNormalize;
663}
664
665function pulse(x) {
666    if (x >= 1) return 1;
667    if (x <= 0) return 0;
668
669    if (options.pulseNormalize == 1) {
670        options.pulseNormalize /= pulse_(1);
671    }
672    return pulse_(x);
673}
674
675
676/***********************************************
677 * FIRST RUN
678 ***********************************************/
679
680var userAgent = window.navigator.userAgent;
681var isEdge    = /Edge/.test(userAgent); // thank you MS
682var isChrome  = /chrome/i.test(userAgent) && !isEdge; 
683var isSafari  = /safari/i.test(userAgent) && !isEdge; 
684var isMobile  = /mobile/i.test(userAgent);
685var isIEWin7  = /Windows NT 6.1/i.test(userAgent) && /rv:11/i.test(userAgent);
686var isEnabledForBrowser = (isChrome || isSafari || isIEWin7) && !isMobile;
687
688var wheelEvent;
689if ('onwheel' in document.createElement('div'))
690    wheelEvent = 'wheel';
691else if ('onmousewheel' in document.createElement('div'))
692    wheelEvent = 'mousewheel';
693
694if (wheelEvent && isEnabledForBrowser) {
695    addEvent(wheelEvent, wheel);
696    addEvent('mousedown', mousedown);
697    addEvent('load', init);
698}
699
700
701/***********************************************
702 * PUBLIC INTERFACE
703 ***********************************************/
704
705function SmoothScroll(optionsToSet) {
706    for (var key in optionsToSet)
707        if (defaultOptions.hasOwnProperty(key)) 
708            options[key] = optionsToSet[key];
709}
710SmoothScroll.destroy = cleanup;
711
712if (window.SmoothScrollOptions) // async API
713    SmoothScroll(window.SmoothScrollOptions)
714
715if (typeof define === 'function' && define.amd)
716    define(function() {
717        return SmoothScroll;
718    });
719else if ('object' == typeof exports)
720    module.exports = SmoothScroll;
721else
722    window.SmoothScroll = SmoothScroll;
723
724})();
725
726
727}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.