PageSourceSearch

https://gdekomfort.ru/resource/js/core6/rsplugins/ajaxpaginator.js

js gdekomfort.ru collected 2026-10-05 02:26:23 UTC 4,563 bytes, 138 lines download raw bytes

1/**
2 * Плагин инициализирует работу Ajax-пагинаторов.
3 */
4new class AjaxPaginator extends RsJsCore.classes.plugin {
5    init(selector, settings, context) {
6        (context ? context : document).querySelectorAll(selector).forEach((element) => {
7            if (!element.ajaxPaginator) {
8                element.ajaxPaginator = new ElementAjaxPaginator(element, settings);
9            }
10        });
11    }
12};
13
14/**
15 * Класс одного паинатора
16 */
17class ElementAjaxPaginator {
18
19    constructor(startElement, settings) {
20        let defaults = {
21            method: 'GET',
22            findElement: '',
23            loaderButton: '.rs-ajax-paginator',
24            loaderBlock: '', // селектор блока пагинации (loaderButton должен находиться в нём)
25            loadingClass: 'rs-in-loading',
26            appendElement: '',
27            contextElement: null,
28            clickOnScroll: false,
29            scrollDistance: 100,
30        };
31
32        if (startElement.dataset.paginationOptions) {
33            //Получим все настройки у элемента
34            defaults = {...defaults, ...JSON.parse(startElement.dataset.paginationOptions)};
35        }
36        this.settings = {...defaults, ...settings};
37
38        if (!this.settings.findElement) {
39            this.settings.findElement = this.settings.appendElement;
40        }
41
42        this.element = startElement;
43
44        this.bindEvents();
45    }
46
47    /**
48     * Навешивает обработчики событий
49     */
50    bindEvents() {
51        if (this.element) {
52            this.element.addEventListener('click', event => this.load(event));
53
54            if (this.settings.clickOnScroll) {
55                window.addEventListener('scroll', event => this.checkScroll(event));
56            }
57        }
58    }
59
60    /**
61     * Проверяет, нужно ли запускать автоподгрузку следующей страницы
62     */
63    checkScroll() {
64        if (this.element && this.element.isConnected) {
65            let bottom = window.pageYOffset + window.innerHeight + this.settings.scrollDistance;
66            if (!this.element.classList.contains(this.settings.loadingClass) && bottom > this.element.offsetTop) {
67                this.element.click();
68            }
69        }
70    }
71
72    /**
73     * Загружает новый контент
74     *
75     * @param event
76     * @returns {boolean}
77     */
78    load(event) {
79        let target = event.target.closest(this.settings.loaderButton);
80        if (target.classList.contains(this.settings.loadingClass)) return false;
81
82        let url = target.hasAttribute('href')
83            ? target.getAttribute('href') : target.dataset.url;
84
85        target.classList.add(this.settings.loadingClass);
86
87        RsJsCore.utils.fetchJSON(url, {
88            method: this.settings.method
89        }).then(response => this.onResponse(url, response));
90
91    }
92
93    /**
94     * Обрабатывает загруженный контент перед вставкой
95     *
96     * @param url
97     * @param response
98     */
99    onResponse(url, response) {
100
101        let parsed = document.createElement('div');
102        parsed.innerHTML = response.html;
103        let appendElement = parsed.querySelector(this.settings.findElement);
104
105        let destination = (this.settings.contextElement ? this.settings.contextElement : document)
106            .querySelector(this.settings.appendElement);
107
108        if (appendElement) {
109            while (appendElement.children.length > 0) {
110                destination.append(appendElement.children[0]);
111            }
112        }
113
114        let newLoader = parsed.querySelector(this.settings.loaderButton);
115        let replaceElement = this.element;
116
117        if (this.settings.loaderBlock) {
118            newLoader = parsed.querySelector(this.settings.loaderBlock);
119            replaceElement = (this.settings.contextElement ? this.settings.contextElement : document)
120                .querySelector(this.settings.loaderBlock);
121        }
122
123        this.element = parsed.querySelector(this.settings.loaderButton);
124
125        if (newLoader) {
126            replaceElement.parentNode.replaceChild(newLoader, replaceElement);
127            this.bindEvents();
128        } else {
129            replaceElement.remove();
130        }
131
132        if (this.settings.replaceBrowserUrl) {
133            history.replaceState(null, null, url);
134        }
135
136        document.body.dispatchEvent(new CustomEvent('new-content', {bubbles: true}));
137    }
138}

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.