I’ll build this as a production-style standalone slider chunk for your RX Theme path, with no dependency on jQuery and safe guards so it does not break pages without a slider.
My dear friend, create this file:
assets/static-js/static-chunks-js/chunk-038-slider.js
This is an advanced vanilla JavaScript slider chunk for RX Theme. It supports autoplay, loop, arrows, dots, swipe, drag, keyboard, pause on hover, lazy image loading, accessibility, responsive slides per view, progress bar, thumbnails, custom events, and auto-initialization.
/*!
* RX Theme Advanced Slider Chunk
* File: assets/static-js/static-chunks-js/chunk-038-slider.js
* Version: 1.0.0
* Author: RX Theme
*
* Usage:
* <div class="rx-slider" data-rx-slider data-autoplay="true" data-loop="true">
* <div class="rx-slider__viewport">
* <div class="rx-slider__track">
* <div class="rx-slider__slide">Slide 1</div>
* <div class="rx-slider__slide">Slide 2</div>
* <div class="rx-slider__slide">Slide 3</div>
* </div>
* </div>
* </div>
*/
(function () {
'use strict';
const RX_SLIDER_VERSION = '1.0.0';
const RX_SLIDER_SELECTOR = '[data-rx-slider]';
const RX_SLIDER_INSTANCE_KEY = '__rxAdvancedSliderInstance';
const defaults = {
viewportSelector: '.rx-slider__viewport',
trackSelector: '.rx-slider__track',
slideSelector: '.rx-slider__slide',
arrowPrevClass: 'rx-slider__arrow--prev',
arrowNextClass: 'rx-slider__arrow--next',
dotsClass: 'rx-slider__dots',
dotClass: 'rx-slider__dot',
dotActiveClass: 'is-active',
activeClass: 'is-active',
initializedClass: 'is-initialized',
draggingClass: 'is-dragging',
disabledClass: 'is-disabled',
hiddenClass: 'is-hidden',
perView: 1,
gap: 0,
startIndex: 0,
loop: true,
autoplay: false,
autoplayDelay: 5000,
autoplayDirection: 'next',
speed: 450,
easing: 'ease',
draggable: true,
swipe: true,
keyboard: true,
mousewheel: false,
pauseOnHover: true,
pauseOnFocus: true,
stopOnInteraction: false,
arrows: true,
dots: true,
pagination: true,
progress: true,
thumbnails: false,
lazyLoad: true,
autoHeight: false,
adaptiveHeight: false,
observeResize: true,
observeMutation: false,
intersectionPause: true,
threshold: 50,
dragThreshold: 0.18,
breakpoints: {
480: {
perView: 1,
gap: 12
},
768: {
perView: 2,
gap: 16
},
1024: {
perView: 3,
gap: 20
}
}
};
function toBool(value, fallback) {
if (value === undefined || value === null || value === '') return fallback;
if (typeof value === 'boolean') return value;
return String(value).toLowerCase() === 'true';
}
function toNumber(value, fallback) {
const num = Number(value);
return Number.isFinite(num) ? num : fallback;
}
function clamp(value, min, max) {
return Math.max(min, Math.min(value, max));
}
function prefersReducedMotion() {
return window.matchMedia &&
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}
function mergeOptions(base, custom) {
const output = Object.assign({}, base);
Object.keys(custom || {}).forEach(function (key) {
if (
typeof custom[key] === 'object' &&
custom[key] !== null &&
!Array.isArray(custom[key])
) {
output[key] = Object.assign({}, output[key] || {}, custom[key]);
} else {
output[key] = custom[key];
}
});
return output;
}
function getDatasetOptions(root) {
return {
perView: toNumber(root.dataset.perView, defaults.perView),
gap: toNumber(root.dataset.gap, defaults.gap),
startIndex: toNumber(root.dataset.startIndex, defaults.startIndex),
loop: toBool(root.dataset.loop, defaults.loop),
autoplay: toBool(root.dataset.autoplay, defaults.autoplay),
autoplayDelay: toNumber(root.dataset.autoplayDelay, defaults.autoplayDelay),
autoplayDirection: root.dataset.autoplayDirection || defaults.autoplayDirection,
speed: toNumber(root.dataset.speed, defaults.speed),
draggable: toBool(root.dataset.draggable, defaults.draggable),
swipe: toBool(root.dataset.swipe, defaults.swipe),
keyboard: toBool(root.dataset.keyboard, defaults.keyboard),
mousewheel: toBool(root.dataset.mousewheel, defaults.mousewheel),
pauseOnHover: toBool(root.dataset.pauseOnHover, defaults.pauseOnHover),
pauseOnFocus: toBool(root.dataset.pauseOnFocus, defaults.pauseOnFocus),
stopOnInteraction: toBool(root.dataset.stopOnInteraction, defaults.stopOnInteraction),
arrows: toBool(root.dataset.arrows, defaults.arrows),
dots: toBool(root.dataset.dots, defaults.dots),
progress: toBool(root.dataset.progress, defaults.progress),
lazyLoad: toBool(root.dataset.lazyLoad, defaults.lazyLoad),
autoHeight: toBool(root.dataset.autoHeight, defaults.autoHeight),
adaptiveHeight: toBool(root.dataset.adaptiveHeight, defaults.adaptiveHeight)
};
}
class RXAdvancedSlider {
constructor(root, options) {
if (!root) return;
this.root = root;
this.options = mergeOptions(defaults, options || {});
this.options = mergeOptions(this.options, getDatasetOptions(root));
this.viewport = this.root.querySelector(this.options.viewportSelector);
this.track = this.root.querySelector(this.options.trackSelector);
this.slides = [];
this.index = this.options.startIndex || 0;
this.previousIndex = this.index;
this.slideWidth = 0;
this.maxIndex = 0;
this.perView = this.options.perView;
this.gap = this.options.gap;
this.isInitialized = false;
this.isDragging = false;
this.isPointerDown = false;
this.isHovered = false;
this.isFocused = false;
this.isVisible = true;
this.isDestroyed = false;
this.startX = 0;
this.currentX = 0;
this.dragDelta = 0;
this.dragStartTranslate = 0;
this.autoplayTimer = null;
this.resizeObserver = null;
this.mutationObserver = null;
this.intersectionObserver = null;
this.dotsWrapper = null;
this.progressWrapper = null;
this.progressBar = null;
this.prevButton = null;
this.nextButton = null;
this.bound = {
onPrevClick: this.prev.bind(this),
onNextClick: this.next.bind(this),
onKeydown: this.onKeydown.bind(this),
onMouseEnter: this.onMouseEnter.bind(this),
onMouseLeave: this.onMouseLeave.bind(this),
onFocusIn: this.onFocusIn.bind(this),
onFocusOut: this.onFocusOut.bind(this),
onPointerDown: this.onPointerDown.bind(this),
onPointerMove: this.onPointerMove.bind(this),
onPointerUp: this.onPointerUp.bind(this),
onWheel: this.onWheel.bind(this),
onResize: this.onResize.bind(this),
onVisibilityChange: this.onVisibilityChange.bind(this)
};
this.init();
}
init() {
if (!this.viewport || !this.track) return;
if (this.root[RX_SLIDER_INSTANCE_KEY]) return;
this.root[RX_SLIDER_INSTANCE_KEY] = this;
this.collectSlides();
if (!this.slides.length) return;
this.applyAccessibility();
this.applyResponsiveOptions();
this.createControls();
this.createDots();
this.createProgress();
this.updateLayout();
this.goTo(this.index, false);
this.bindEvents();
this.observe();
this.lazyLoadAround(this.index);
this.updateState();
this.root.classList.add(this.options.initializedClass);
this.root.dataset.rxSliderReady = 'true';
this.isInitialized = true;
if (this.options.autoplay && !prefersReducedMotion()) {
this.startAutoplay();
}
this.emit('rxSlider:init', {
version: RX_SLIDER_VERSION,
index: this.index,
total: this.slides.length
});
}
collectSlides() {
this.slides = Array.prototype.slice.call(
this.track.querySelectorAll(this.options.slideSelector)
);
this.slides.forEach((slide, i) => {
slide.dataset.rxSlideIndex = String(i);
slide.setAttribute('role', 'group');
slide.setAttribute('aria-roledescription', 'slide');
slide.setAttribute('aria-label', `${i + 1} of ${this.slides.length}`);
});
}
applyAccessibility() {
this.root.setAttribute('role', 'region');
this.root.setAttribute('aria-roledescription', 'carousel');
if (!this.root.getAttribute('aria-label')) {
this.root.setAttribute('aria-label', 'RX content slider');
}
this.viewport.setAttribute('tabindex', '0');
this.viewport.setAttribute('aria-live', this.options.autoplay ? 'off' : 'polite');
}
applyResponsiveOptions() {
const width = window.innerWidth;
let responsive = {};
Object.keys(this.options.breakpoints || {})
.map(Number)
.sort((a, b) => a - b)
.forEach((point) => {
if (width >= point) {
responsive = mergeOptions(responsive, this.options.breakpoints[point]);
}
});
this.perView = toNumber(responsive.perView, this.options.perView);
this.gap = toNumber(responsive.gap, this.options.gap);
this.perView = Math.max(1, this.perView);
this.gap = Math.max(0, this.gap);
}
createControls() {
if (!this.options.arrows) return;
this.prevButton = this.root.querySelector('[data-rx-slider-prev]');
this.nextButton = this.root.querySelector('[data-rx-slider-next]');
if (!this.prevButton) {
this.prevButton = document.createElement('button');
this.prevButton.type = 'button';
this.prevButton.className = `rx-slider__arrow ${this.options.arrowPrevClass}`;
this.prevButton.setAttribute('data-rx-slider-prev', '');
this.prevButton.setAttribute('aria-label', 'Previous slide');
this.prevButton.innerHTML = '<span aria-hidden="true">‹</span>';
this.root.appendChild(this.prevButton);
}
if (!this.nextButton) {
this.nextButton = document.createElement('button');
this.nextButton.type = 'button';
this.nextButton.className = `rx-slider__arrow ${this.options.arrowNextClass}`;
this.nextButton.setAttribute('data-rx-slider-next', '');
this.nextButton.setAttribute('aria-label', 'Next slide');
this.nextButton.innerHTML = '<span aria-hidden="true">›</span>';
this.root.appendChild(this.nextButton);
}
}
createDots() {
if (!this.options.dots) return;
this.dotsWrapper = this.root.querySelector('[data-rx-slider-dots]');
if (!this.dotsWrapper) {
this.dotsWrapper = document.createElement('div');
this.dotsWrapper.className = this.options.dotsClass;
this.dotsWrapper.setAttribute('data-rx-slider-dots', '');
this.dotsWrapper.setAttribute('role', 'tablist');
this.dotsWrapper.setAttribute('aria-label', 'Slider pagination');
this.root.appendChild(this.dotsWrapper);
}
this.renderDots();
}
renderDots() {
if (!this.dotsWrapper) return;
this.dotsWrapper.innerHTML = '';
const dotCount = this.getPageCount();
for (let i = 0; i < dotCount; i++) {
const dot = document.createElement('button');
dot.type = 'button';
dot.className = this.options.dotClass;
dot.setAttribute('data-rx-slider-dot', String(i));
dot.setAttribute('role', 'tab');
dot.setAttribute('aria-label', `Go to slide ${i + 1}`);
dot.innerHTML = '<span></span>';
dot.addEventListener('click', () => {
this.interact();
this.goTo(i);
});
this.dotsWrapper.appendChild(dot);
}
}
createProgress() {
if (!this.options.progress) return;
this.progressWrapper = this.root.querySelector('[data-rx-slider-progress]');
if (!this.progressWrapper) {
this.progressWrapper = document.createElement('div');
this.progressWrapper.className = 'rx-slider__progress';
this.progressWrapper.setAttribute('data-rx-slider-progress', '');
this.progressWrapper.innerHTML = '<span class="rx-slider__progress-bar"></span>';
this.root.appendChild(this.progressWrapper);
}
this.progressBar = this.progressWrapper.querySelector('.rx-slider__progress-bar');
}
bindEvents() {
if (this.prevButton) {
this.prevButton.addEventListener('click', this.bound.onPrevClick);
}
if (this.nextButton) {
this.nextButton.addEventListener('click', this.bound.onNextClick);
}
if (this.options.keyboard) {
this.viewport.addEventListener('keydown', this.bound.onKeydown);
}
if (this.options.pauseOnHover) {
this.root.addEventListener('mouseenter', this.bound.onMouseEnter);
this.root.addEventListener('mouseleave', this.bound.onMouseLeave);
}
if (this.options.pauseOnFocus) {
this.root.addEventListener('focusin', this.bound.onFocusIn);
this.root.addEventListener('focusout', this.bound.onFocusOut);
}
if (this.options.draggable || this.options.swipe) {
this.viewport.addEventListener('pointerdown', this.bound.onPointerDown);
this.viewport.addEventListener('pointermove', this.bound.onPointerMove);
this.viewport.addEventListener('pointerup', this.bound.onPointerUp);
this.viewport.addEventListener('pointercancel', this.bound.onPointerUp);
this.viewport.addEventListener('lostpointercapture', this.bound.onPointerUp);
}
if (this.options.mousewheel) {
this.viewport.addEventListener('wheel', this.bound.onWheel, {
passive: false
});
}
window.addEventListener('resize', this.bound.onResize);
document.addEventListener('visibilitychange', this.bound.onVisibilityChange);
}
observe() {
if (this.options.observeResize && 'ResizeObserver' in window) {
this.resizeObserver = new ResizeObserver(() => {
this.onResize();
});
this.resizeObserver.observe(this.root);
this.resizeObserver.observe(this.viewport);
}
if (this.options.observeMutation && 'MutationObserver' in window) {
this.mutationObserver = new MutationObserver(() => {
this.refresh();
});
this.mutationObserver.observe(this.track, {
childList: true,
subtree: false
});
}
if (this.options.intersectionPause && 'IntersectionObserver' in window) {
this.intersectionObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
this.isVisible = entry.isIntersecting;
if (this.isVisible) {
this.resumeAutoplay();
} else {
this.pauseAutoplay();
}
});
}, {
threshold: 0.15
});
this.intersectionObserver.observe(this.root);
}
}
updateLayout() {
this.applyResponsiveOptions();
const viewportWidth = this.viewport.clientWidth;
const totalGap = this.gap * (this.perView - 1);
this.slideWidth = (viewportWidth - totalGap) / this.perView;
this.maxIndex = Math.max(0, this.slides.length - this.perView);
this.track.style.display = 'flex';
this.track.style.gap = `${this.gap}px`;
this.track.style.transition = `transform ${this.options.speed}ms ${this.options.easing}`;
this.track.style.willChange = 'transform';
this.slides.forEach((slide) => {
slide.style.flex = `0 0 ${this.slideWidth}px`;
slide.style.maxWidth = `${this.slideWidth}px`;
});
this.index = clamp(this.index, 0, this.maxIndex);
if (this.dotsWrapper) {
this.renderDots();
}
this.updateHeight();
this.updateTransform(false);
this.updateState();
}
updateTransform(animate = true) {
if (!animate) {
this.track.style.transition = 'none';
} else {
this.track.style.transition = `transform ${this.options.speed}ms ${this.options.easing}`;
}
const translate = this.getTranslateForIndex(this.index);
this.track.style.transform = `translate3d(${translate}px, 0, 0)`;
if (!animate) {
this.track.offsetHeight;
this.track.style.transition = `transform ${this.options.speed}ms ${this.options.easing}`;
}
}
getTranslateForIndex(index) {
return -index * (this.slideWidth + this.gap);
}
getPageCount() {
if (!this.slides.length) return 0;
return Math.max(1, this.maxIndex + 1);
}
goTo(targetIndex, animate = true) {
if (!this.slides.length) return;
this.previousIndex = this.index;
let nextIndex = Number(targetIndex);
if (this.options.loop) {
if (nextIndex < 0) nextIndex = this.maxIndex;
if (nextIndex > this.maxIndex) nextIndex = 0;
} else {
nextIndex = clamp(nextIndex, 0, this.maxIndex);
}
this.index = nextIndex;
this.updateTransform(animate);
this.lazyLoadAround(this.index);
this.updateHeight();
this.updateState();
this.emit('rxSlider:change', {
index: this.index,
previousIndex: this.previousIndex,
total: this.slides.length
});
}
next() {
this.interact();
this.goTo(this.index + 1);
}
prev() {
this.interact();
this.goTo(this.index - 1);
}
first() {
this.interact();
this.goTo(0);
}
last() {
this.interact();
this.goTo(this.maxIndex);
}
updateState() {
this.slides.forEach((slide, i) => {
const isVisible = i >= this.index && i < this.index + this.perView;
const isActive = i === this.index;
slide.classList.toggle(this.options.activeClass, isActive);
slide.setAttribute('aria-hidden', isVisible ? 'false' : 'true');
const focusable = slide.querySelectorAll(
'a, button, input, textarea, select, iframe, [tabindex]'
);
focusable.forEach((element) => {
if (isVisible) {
if (element.dataset.rxOldTabindex !== undefined) {
element.setAttribute('tabindex', element.dataset.rxOldTabindex);
delete element.dataset.rxOldTabindex;
} else {
element.removeAttribute('tabindex');
}
} else {
if (!element.hasAttribute('data-rx-old-tabindex')) {
element.dataset.rxOldTabindex = element.getAttribute('tabindex') || '';
}
element.setAttribute('tabindex', '-1');
}
});
});
if (this.prevButton) {
const disabled = !this.options.loop && this.index === 0;
this.prevButton.disabled = disabled;
this.prevButton.classList.toggle(this.options.disabledClass, disabled);
this.prevButton.setAttribute('aria-disabled', disabled ? 'true' : 'false');
}
if (this.nextButton) {
const disabled = !this.options.loop && this.index >= this.maxIndex;
this.nextButton.disabled = disabled;
this.nextButton.classList.toggle(this.options.disabledClass, disabled);
this.nextButton.setAttribute('aria-disabled', disabled ? 'true' : 'false');
}
this.updateDots();
this.updateProgress();
}
updateDots() {
if (!this.dotsWrapper) return;
const dots = this.dotsWrapper.querySelectorAll('[data-rx-slider-dot]');
dots.forEach((dot, i) => {
const active = i === this.index;
dot.classList.toggle(this.options.dotActiveClass, active);
dot.setAttribute('aria-selected', active ? 'true' : 'false');
dot.setAttribute('tabindex', active ? '0' : '-1');
});
}
updateProgress() {
if (!this.progressBar) return;
const total = this.getPageCount();
const percent = total <= 1 ? 100 : ((this.index + 1) / total) * 100;
this.progressBar.style.width = `${percent}%`;
}
updateHeight() {
if (!this.options.autoHeight && !this.options.adaptiveHeight) return;
const visibleSlides = this.slides.slice(this.index, this.index + this.perView);
let maxHeight = 0;
visibleSlides.forEach((slide) => {
maxHeight = Math.max(maxHeight, slide.offsetHeight);
});
if (maxHeight > 0) {
this.viewport.style.height = `${maxHeight}px`;
}
}
lazyLoadAround(index) {
if (!this.options.lazyLoad) return;
const from = Math.max(0, index - 1);
const to = Math.min(this.slides.length - 1, index + this.perView + 1);
for (let i = from; i <= to; i++) {
this.lazyLoadSlide(this.slides[i]);
}
}
lazyLoadSlide(slide) {
if (!slide) return;
const lazyItems = slide.querySelectorAll(
'img[data-src], img[data-srcset], source[data-srcset], iframe[data-src]'
);
lazyItems.forEach((item) => {
if (item.dataset.src) {
item.setAttribute('src', item.dataset.src);
delete item.dataset.src;
}
if (item.dataset.srcset) {
item.setAttribute('srcset', item.dataset.srcset);
delete item.dataset.srcset;
}
item.classList.add('is-loaded');
});
}
startAutoplay() {
this.stopAutoplay();
if (!this.options.autoplay || prefersReducedMotion()) return;
if (!this.isVisible || this.isHovered || this.isFocused) return;
this.autoplayTimer = window.setInterval(() => {
if (this.options.autoplayDirection === 'prev') {
this.goTo(this.index - 1);
} else {
this.goTo(this.index + 1);
}
}, this.options.autoplayDelay);
this.root.dataset.rxAutoplay = 'running';
this.emit('rxSlider:autoplayStart', {
delay: this.options.autoplayDelay
});
}
stopAutoplay() {
if (this.autoplayTimer) {
window.clearInterval(this.autoplayTimer);
this.autoplayTimer = null;
}
this.root.dataset.rxAutoplay = 'stopped';
this.emit('rxSlider:autoplayStop', {});
}
pauseAutoplay() {
if (!this.options.autoplay) return;
this.stopAutoplay();
this.root.dataset.rxAutoplay = 'paused';
}
resumeAutoplay() {
if (!this.options.autoplay) return;
if (this.isHovered || this.isFocused || !this.isVisible) return;
this.startAutoplay();
}
interact() {
if (this.options.stopOnInteraction) {
this.stopAutoplay();
}
}
onKeydown(event) {
const key = event.key;
if (key === 'ArrowLeft') {
event.preventDefault();
this.prev();
}
if (key === 'ArrowRight') {
event.preventDefault();
this.next();
}
if (key === 'Home') {
event.preventDefault();
this.first();
}
if (key === 'End') {
event.preventDefault();
this.last();
}
}
onMouseEnter() {
this.isHovered = true;
this.pauseAutoplay();
}
onMouseLeave() {
this.isHovered = false;
this.resumeAutoplay();
}
onFocusIn() {
this.isFocused = true;
this.pauseAutoplay();
}
onFocusOut() {
this.isFocused = false;
this.resumeAutoplay();
}
onPointerDown(event) {
if (!this.options.draggable && !this.options.swipe) return;
if (event.button !== undefined && event.button !== 0) return;
this.isPointerDown = true;
this.isDragging = false;
this.startX = event.clientX;
this.currentX = event.clientX;
this.dragDelta = 0;
this.dragStartTranslate = this.getTranslateForIndex(this.index);
this.viewport.setPointerCapture &&
this.viewport.setPointerCapture(event.pointerId);
this.track.style.transition = 'none';
this.pauseAutoplay();
this.emit('rxSlider:dragStart', {
index: this.index
});
}
onPointerMove(event) {
if (!this.isPointerDown) return;
this.currentX = event.clientX;
this.dragDelta = this.currentX - this.startX;
if (Math.abs(this.dragDelta) > 5) {
this.isDragging = true;
this.root.classList.add(this.options.draggingClass);
}
if (!this.options.loop) {
if (this.index === 0 && this.dragDelta > 0) {
this.dragDelta *= 0.35;
}
if (this.index === this.maxIndex && this.dragDelta < 0) {
this.dragDelta *= 0.35;
}
}
const nextTranslate = this.dragStartTranslate + this.dragDelta;
this.track.style.transform = `translate3d(${nextTranslate}px, 0, 0)`;
}
onPointerUp(event) {
if (!this.isPointerDown) return;
this.isPointerDown = false;
this.viewport.releasePointerCapture &&
this.viewport.releasePointerCapture(event.pointerId);
this.track.style.transition = `transform ${this.options.speed}ms ${this.options.easing}`;
this.root.classList.remove(this.options.draggingClass);
const movedEnough =
Math.abs(this.dragDelta) > Math.max(this.options.threshold, this.slideWidth * this.options.dragThreshold);
if (movedEnough) {
if (this.dragDelta < 0) {
this.goTo(this.index + 1);
} else {
this.goTo(this.index - 1);
}
} else {
this.updateTransform(true);
}
this.isDragging = false;
this.dragDelta = 0;
this.resumeAutoplay();
this.emit('rxSlider:dragEnd', {
index: this.index
});
}
onWheel(event) {
if (!this.options.mousewheel) return;
const absX = Math.abs(event.deltaX);
const absY = Math.abs(event.deltaY);
if (absX <= absY) return;
event.preventDefault();
if (event.deltaX > 0) {
this.next();
} else {
this.prev();
}
}
onResize() {
window.requestAnimationFrame(() => {
this.updateLayout();
});
}
onVisibilityChange() {
if (document.hidden) {
this.pauseAutoplay();
} else {
this.resumeAutoplay();
}
}
refresh() {
this.collectSlides();
this.applyResponsiveOptions();
this.updateLayout();
this.goTo(this.index, false);
this.emit('rxSlider:refresh', {
index: this.index,
total: this.slides.length
});
}
emit(name, detail) {
const event = new CustomEvent(name, {
bubbles: true,
detail: detail || {}
});
this.root.dispatchEvent(event);
}
destroy() {
if (this.isDestroyed) return;
this.stopAutoplay();
if (this.prevButton) {
this.prevButton.removeEventListener('click', this.bound.onPrevClick);
}
if (this.nextButton) {
this.nextButton.removeEventListener('click', this.bound.onNextClick);
}
this.viewport.removeEventListener('keydown', this.bound.onKeydown);
this.root.removeEventListener('mouseenter', this.bound.onMouseEnter);
this.root.removeEventListener('mouseleave', this.bound.onMouseLeave);
this.root.removeEventListener('focusin', this.bound.onFocusIn);
this.root.removeEventListener('focusout', this.bound.onFocusOut);
this.viewport.removeEventListener('pointerdown', this.bound.onPointerDown);
this.viewport.removeEventListener('pointermove', this.bound.onPointerMove);
this.viewport.removeEventListener('pointerup', this.bound.onPointerUp);
this.viewport.removeEventListener('pointercancel', this.bound.onPointerUp);
this.viewport.removeEventListener('lostpointercapture', this.bound.onPointerUp);
this.viewport.removeEventListener('wheel', this.bound.onWheel);
window.removeEventListener('resize', this.bound.onResize);
document.removeEventListener('visibilitychange', this.bound.onVisibilityChange);
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
if (this.mutationObserver) {
this.mutationObserver.disconnect();
}
if (this.intersectionObserver) {
this.intersectionObserver.disconnect();
}
this.track.removeAttribute('style');
this.viewport.removeAttribute('style');
this.slides.forEach((slide) => {
slide.removeAttribute('style');
slide.classList.remove(this.options.activeClass);
slide.removeAttribute('aria-hidden');
});
this.root.classList.remove(this.options.initializedClass);
delete this.root[RX_SLIDER_INSTANCE_KEY];
this.isDestroyed = true;
this.emit('rxSlider:destroy', {});
}
}
function initRXSliders(context) {
const scope = context || document;
const sliders = scope.querySelectorAll(RX_SLIDER_SELECTOR);
sliders.forEach((slider) => {
if (!slider[RX_SLIDER_INSTANCE_KEY]) {
new RXAdvancedSlider(slider);
}
});
}
function destroyRXSliders(context) {
const scope = context || document;
const sliders = scope.querySelectorAll(RX_SLIDER_SELECTOR);
sliders.forEach((slider) => {
if (slider[RX_SLIDER_INSTANCE_KEY]) {
slider[RX_SLIDER_INSTANCE_KEY].destroy();
}
});
}
function refreshRXSliders(context) {
const scope = context || document;
const sliders = scope.querySelectorAll(RX_SLIDER_SELECTOR);
sliders.forEach((slider) => {
if (slider[RX_SLIDER_INSTANCE_KEY]) {
slider[RX_SLIDER_INSTANCE_KEY].refresh();
}
});
}
window.RXAdvancedSlider = RXAdvancedSlider;
window.RXSlider = {
version: RX_SLIDER_VERSION,
init: initRXSliders,
refresh: refreshRXSliders,
destroy: destroyRXSliders,
getInstance: function (element) {
return element ? element[RX_SLIDER_INSTANCE_KEY] : null;
}
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function () {
initRXSliders(document);
});
} else {
initRXSliders(document);
}
document.addEventListener('rxTheme:contentLoaded', function (event) {
initRXSliders(event.detail && event.detail.container ? event.detail.container : document);
});
})();
Use this basic HTML structure:
<section class="rx-slider" data-rx-slider data-autoplay="true" data-loop="true" data-per-view="1">
<div class="rx-slider__viewport">
<div class="rx-slider__track">
<article class="rx-slider__slide">
<h2>Slide One</h2>
<p>RX Theme medical content slider.</p>
</article>
<article class="rx-slider__slide">
<h2>Slide Two</h2>
<p>Fast, accessible, SEO-friendly layout.</p>
</article>
<article class="rx-slider__slide">
<h2>Slide Three</h2>
<p>Works without jQuery.</p>
</article>
</div>
</div>
</section>
Add this CSS later in your slider CSS file:
.rx-slider {
position: relative;
width: 100%;
overflow: hidden;
}
.rx-slider__viewport {
overflow: hidden;
width: 100%;
}
.rx-slider__track {
display: flex;
will-change: transform;
}
.rx-slider__slide {
min-width: 0;
}
.rx-slider__arrow {
position: absolute;
top: 50%;
z-index: 5;
transform: translateY(-50%);
border: 0;
cursor: pointer;
}
.rx-slider__arrow--prev {
left: 12px;
}
.rx-slider__arrow--next {
right: 12px;
}
.rx-slider__dots {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 16px;
}
.rx-slider__dot {
width: 10px;
height: 10px;
border-radius: 999px;
border: 0;
cursor: pointer;
}
.rx-slider__dot.is-active {
transform: scale(1.25);
}
.rx-slider__progress {
width: 100%;
height: 3px;
overflow: hidden;
}
.rx-slider__progress-bar {
display: block;
height: 100%;
width: 0;
transition: width 300ms ease;
}
.rx-slider.is-dragging {
cursor: grabbing;
}
.rx-slider.is-dragging .rx-slider__track {
user-select: none;
}
For functions.php, enqueue it like this:
wp_enqueue_script(
'rx-chunk-038-slider',
get_template_directory_uri() . '/assets/static-js/static-chunks-js/chunk-038-slider.js',
array(),
wp_get_theme()->get( 'Version' ),
true
);
Best idea for RX Theme: keep this file only for slider functionality. Do not put unrelated header, menu, search, AJAX, or popup code inside this chunk. That will keep your theme faster and easier to debug.