PageSourceSearch

https://www.the-journal.com/wp-content/themes/ballantine-news-theme/js/gallery-slider.js?ver=1786834150

js the-journal.com collected 2026-10-02 03:23:19 UTC 5,889 bytes, 151 lines download raw bytes

1/**
2 * Naviga Gallery Slider
3 * Targets .gallery-slider > .gallery-image-slider markup.
4 * Builds an inline prev/next slider with #900 arrows, counter, caption and byline.
5 */
6(function () {
7    'use strict';
8
9    function buildSlider(wrapper) {
10        var slides = Array.prototype.slice.call(wrapper.querySelectorAll('.gallery-image-slider'));
11        if (slides.length < 1) return;
12
13        // Collect slide data from existing DOM
14        var items = slides.map(function (slide) {
15            var img     = slide.querySelector('img.gallery_image');
16            var caption = slide.querySelector('.bottom-container .caption');
17            var byline  = slide.querySelector('.bottom-container .byline');
18            return {
19                src:     img     ? img.src                  : '',
20                alt:     img     ? (img.alt || '')          : '',
21                caption: caption ? caption.textContent.trim() : '',
22                byline:  byline  ? byline.textContent.trim()  : ''
23            };
24        });
25
26        var total   = items.length;
27        var current = 0;
28
29        // ── Build slider DOM ──────────────────────────────────────────────
30
31        var slider = document.createElement('div');
32        slider.className = 'naviga-slider';
33
34        // Image track
35        var track = document.createElement('div');
36        track.className = 'naviga-slider-track';
37
38        var mainImg      = document.createElement('img');
39        mainImg.className = 'naviga-slider-img';
40        mainImg.decoding  = 'async';
41        mainImg.loading   = 'eager';
42        track.appendChild(mainImg);
43
44        slider.appendChild(track);
45
46        // Controls bar (prev | counter | next)
47        var controls = document.createElement('div');
48        controls.className = 'naviga-slider-controls';
49
50        function makeArrow(dir) {
51            var btn = document.createElement('button');
52            btn.type      = 'button';
53            btn.className = 'naviga-slider-arrow naviga-slider-arrow--' + dir;
54            btn.setAttribute('aria-label', dir === 'prev' ? 'Previous image' : 'Next image');
55            btn.innerHTML = dir === 'prev'
56                ? '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>'
57                : '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>';
58            return btn;
59        }
60
61        var prevBtn = makeArrow('prev');
62        var counter = document.createElement('span');
63        counter.className = 'naviga-slider-counter';
64        var nextBtn = makeArrow('next');
65
66        controls.appendChild(prevBtn);
67        controls.appendChild(counter);
68        controls.appendChild(nextBtn);
69        slider.appendChild(controls);
70
71        // Caption / byline bar
72        var captionBar = document.createElement('div');
73        captionBar.className = 'naviga-slider-caption-bar';
74
75        var captionEl = document.createElement('p');
76        captionEl.className = 'naviga-slider-caption';
77
78        var bylineEl = document.createElement('p');
79        bylineEl.className = 'naviga-slider-byline';
80
81        captionBar.appendChild(captionEl);
82        captionBar.appendChild(bylineEl);
83        slider.appendChild(captionBar);
84
85        // ── Update function ───────────────────────────────────────────────
86
87        function goTo(index) {
88            current = (index + total) % total;
89            var item = items[current];
90
91            mainImg.src = item.src;
92            mainImg.alt = item.alt;
93
94            counter.textContent = (current + 1) + ' / ' + total;
95
96            captionEl.textContent = item.caption;
97            captionEl.style.display = item.caption ? '' : 'none';
98
99            bylineEl.textContent = item.byline;
100            bylineEl.style.display = item.byline ? '' : 'none';
101
102            captionBar.style.display = (item.caption || item.byline) ? '' : 'none';
103
104            // Disable arrows at ends (non-looping feel) - keep clickable for looping
105            prevBtn.disabled = false;
106            nextBtn.disabled = false;
107        }
108
109        prevBtn.addEventListener('click', function () { goTo(current - 1); });
110        nextBtn.addEventListener('click', function () { goTo(current + 1); });
111
112        // Touch / swipe
113        var touchStartX = null;
114        track.addEventListener('touchstart', function (e) {
115            touchStartX = e.touches[0].clientX;
116        }, { passive: true });
117        track.addEventListener('touchend', function (e) {
118            if (touchStartX === null) return;
119            var delta = e.changedTouches[0].clientX - touchStartX;
120            if (Math.abs(delta) > 40) {
121                delta < 0 ? goTo(current + 1) : goTo(current - 1);
122            }
123            touchStartX = null;
124        }, { passive: true });
125
126        // Keyboard support when slider is focused
127        slider.setAttribute('tabindex', '0');
128        slider.addEventListener('keydown', function (e) {
129            if (e.key === 'ArrowLeft')  goTo(current - 1);
130            if (e.key === 'ArrowRight') goTo(current + 1);
131        });
132
133        // Init first slide
134        goTo(0);
135
136        // Replace wrapper contents with the built slider
137        wrapper.innerHTML = '';
138        wrapper.appendChild(slider);
139    }
140
141    function init() {
142        var galleries = document.querySelectorAll('.gallery-slider');
143        Array.prototype.forEach.call(galleries, buildSlider);
144    }
145
146    if (document.readyState === 'loading') {
147        document.addEventListener('DOMContentLoaded', init);
148    } else {
149        init();
150    }
151}());

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.