PageSourceSearch

https://sol.no/view-resources/baseview/public/common/AutoScroller.js?v=1790840215-L4

js sol.no collected 2026-10-01 11:35:32 UTC 5,722 bytes, 195 lines download raw bytes

1/**
2 * Infinite scroller for articles.
3 * Require CSS to support transform using translateX.
4 * This is optimized to use GPU instead og CPU.
5 * (c) Publish Lab AS 2018
6 */
7
8if (!window.Dac) window.Dac = {}
9var Dac = window.Dac;
10
11Dac.AutoScroller = function(boxContainer, autoscroll, interval) {
12
13    var autoscrollId = null;
14    if (!boxContainer) return;
15    var container = boxContainer.querySelector('ul.articles');
16    if (!container) return;
17    var articleList = container.children;
18    if (!articleList.length) return;
19    var leftNav = boxContainer.querySelector('span.left');
20    var rightNav = boxContainer.querySelector('span.right');
21    var currentIndex = 0;
22    var elementWidth = articleList[0].offsetWidth;
23    var visibleCount = Math.round(container.offsetWidth / elementWidth);
24    var scrollWidth = container.offsetWidth / visibleCount;
25    var intervalPeriod = interval || 4000;
26
27    if (visibleCount >= articleList.length) return;
28    var slots = [];
29
30    var setupSlots = function() {
31        slots = [];
32        for (var i = 0; i < articleList.length; i++) {
33            slots.push(new slot(articleList[i], scrollWidth));
34        }
35    }
36
37    var resizeObserver;
38    if (window.ResizeObserver) {
39        resizeObserver = new ResizeObserver(entries => {
40            for (let entry of entries) {
41                if (entry.target === container) {
42                    var newElementWidth = articleList[0].offsetWidth;
43                    if (newElementWidth !== elementWidth) {
44                        elementWidth = newElementWidth;
45                        scrollWidth = container.offsetWidth / visibleCount;
46                        setupSlots();
47                        repositionLast(1);
48                    }
49                }
50            }
51        });
52    }
53
54    var start = function() {
55        setupSlots();
56        repositionLast(1);
57        if (resizeObserver) { resizeObserver.observe(container); }
58        if (autoscroll) {
59            autoscrollId = window.setInterval(function() {
60                if (!autoscroll) {
61                    window.clearInterval(autoscrollId);
62                    return;
63                }
64                step(1);
65            }, intervalPeriod);
66        }
67    }
68
69    var dotsContainer = boxContainer.querySelector('ul.dots');
70
71
72    // Eks: "transition: transform 0.5s;" -> more than 500.
73    // CSS-class "transformHidden" should move the element instantly and hide it.
74    var slot = function(element, slotWidth) {
75        this.element = element;
76        this.slotWidth = slotWidth;
77        this.xPos = 0;
78
79        this.step = function(amount, hidden) {
80            this.xPos -= this.slotWidth * amount;
81            this.move(this.xPos, hidden);
82        }
83
84        this.reset = function() {
85            this.xPos = 0;
86            this.move(0);
87        }
88
89        this.move = function(xPos, hidden) {
90            var el = this.element;
91            if (hidden) {
92                el.classList.add('transformHidden');
93            } else {
94                el.classList.remove('transformHidden');
95            }
96            el.style.transform = 'translateX(' + xPos + 'px)'; // transitionend
97        }
98
99        var self = this;
100        return {
101            step: function(amount, hidden) {
102                self.step(amount, hidden);
103            },
104            reset: function() {
105                self.reset();
106            }
107        }
108    }
109
110    var step = function(amount, hidden) {
111        var oldIndex = currentIndex;
112        currentIndex += amount;
113        if (Math.abs(currentIndex) >= slots.length) {
114            currentIndex = 0;
115        }
116        slots.forEach(function(obj) {
117            obj.step(amount, hidden);
118        })
119        if (amount > 0) {
120            repositionFirst(Math.abs(amount));
121        } else if (amount < 0) {
122            repositionLast(Math.abs(amount));
123        }
124        updateDots(currentIndex, oldIndex);
125    }
126
127    var repositionFirst = function(count) {
128        var first = slots.shift();
129        first.step(-2 - slots.length, true);
130        window.setTimeout(function() {
131            first.step(1);
132        }, 50);
133        slots.push(first);
134        count--;
135        if (count > 0) repositionFirst(count);
136    }
137
138    var repositionLast = function(count) {
139        var last = slots.pop();
140        slots.unshift(last);
141        last.step(slots.length, true);
142        count--;
143        if (count > 0) repositionLast(count);
144    }
145
146    var slideToPrevious = function() {
147        step(-1);
148        autoscroll = false;
149    }
150
151    var slideToNext = function() {
152        step(1);
153        autoscroll = false;
154    }
155
156    if (leftNav) {
157        leftNav.addEventListener('click', slideToPrevious, false);
158    }
159    if (rightNav) {
160        rightNav.addEventListener('click', slideToNext, false);
161    }
162
163    function getIndex(element) {
164        var nodes = Array.prototype.slice.call(element.parentNode.children);
165        return nodes.indexOf(element);
166    }
167
168    function dotClicked(event) {
169        event.preventDefault();
170        event.stopPropagation();
171        var index = getIndex(this);
172        if (index > -1) {
173            step(index - currentIndex, true);
174        }
175        autoscroll = false;
176    }
177
178    function updateDots(newIndex, oldIndex) {
179        if (!dotsContainer) return;
180        var oldEl = dotsContainer.children[oldIndex];
181        if (oldEl) oldEl.classList.remove('selected');
182        var newEl = dotsContainer.children[newIndex];
183        if (newEl) newEl.classList.add('selected');
184    }
185
186
187    if (dotsContainer) {
188        for (var i = 0; i < dotsContainer.children.length; i++) {
189            dotsContainer.children[i].addEventListener('click', dotClicked, false);
190        }
191        updateDots(0);
192    }
193
194    start();
195}

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.