PageSourceSearch

https://www.madamella.com/theme/standart/js/blok-v4/product-loader.js

js madamella.com collected 2026-10-08 06:25:11 UTC 8,829 bytes, 208 lines download raw bytes

1if (getVar('ps') && Number(getVar('ps')) > 1 && DYNAMIC_LOADING_SHOW_BUTTON == 1) {
2    if (history.scrollRestoration) history.scrollRestoration = 'manual';
3}
4
5window.pushstateloaded = false;
6
7function paginationPushState(key, title, url) {
8    window.pushstateloaded = true;
9    if (window.history && window.history.pushState) window.history.replaceState(key, title, url);
10}
11
12function ProductLoader(opt) {
13    let downLoaded = true;
14    let upLoaded = true;
15    let scrollY;
16
17    const defaults = {
18        pageNo: '',
19        //baseUrl: '.BASE_URL:last',
20        equalParent: '#katalog',
21        parentDiv: '.catalogWrapper',
22        productDiv: '.productItem',
23        loadMoreButton: '.LoadMoreButton',
24        heightEqualDiv: '.productItem:first',
25        loadMoreStatus: true,
26        scrollLoadStatus: true,
27        loadingStatus: false,
28        up: false,
29    };
30
31    const options = { ...defaults, ...opt };
32    options.parentDiv = options.equalParent + ' ' + options.parentDiv;
33    options.pageNo = Number(getVar('ps') || 1);
34
35    const addClassProduct = async function(products) {
36        products[0].dataset.page = options.pageNo;
37        products[products.length - 1].dataset.page = options.pageNo;
38
39        Array.from(products).forEach((product, index) => {
40            product.dataset.index = `${options.pageNo}-${index}`;
41            product.classList.remove('ease');
42            product.addEventListener('click', e => {
43                let setProduct = {
44                    category: window.location.pathname,
45                    product: product.dataset.index,
46                };
47                if (setProduct.product) setCookie('productIndex', JSON.stringify(setProduct));
48            });
49        });
50    };
51
52    const appendProduct = async function(result, prepend = false) {
53        const domParser = new DOMParser();
54        const resultElm = domParser.parseFromString(result, "text/html");
55        const products = resultElm.documentElement.querySelectorAll(options.productDiv);
56
57        if (products.length == 0) return;
58
59        for(let i=0; i<products.length; i++) {
60            if (prepend == false) {
61                document.querySelector(options.parentDiv).append(products[i]);
62            } else {
63                document.querySelector(options.parentDiv).prepend(products[(products.length - 1) - i]);
64            }
65        }
66
67        if (prepend != false) {
68            scrollY = products[products.length - 1].offsetTop + products[products.length - 1].offsetHeight;
69            window.scrollTo(0, scrollY);
70            window.onscroll = function() { window.scrollTo(0, scrollY); };
71        }
72
73        $(options.equalParent).equalizer();
74        $(document).ready(function() {
75            FavouriteApi.setButtons();
76        });
77
78        if (typeof loaderCallback == 'function' && loaderCallback != 'undefined') {
79            loaderCallback(products);
80        }
81
82        for(let i=0; i < TSOFT_APPS.product.dynamicLoader.length; i++){
83            if(typeof TSOFT_APPS.product.dynamicLoader[i] === 'function'){
84                try {
85                    const regex = /PRODUCT_DATA\.push\(JSON\.parse\('([^']+)'\)\);/g;
86                    const matches = [];
87
88                    for (const match of result.matchAll(regex)) {
89                        let jsonData = eval("'" + match[1] + "'");
90                        matches.push(JSON.parse(jsonData));
91                    }
92                    TSOFT_APPS.product.dynamicLoader[i]?.(matches);
93                } catch (error) { console.log('Product dynamicLoader Callback Error =>' + error); }
94            }
95        }
96
97        addClassProduct(products);
98
99        window.onscroll = null;
100
101        setTimeout(() => {
102            prepend == false ? downLoaded = true : upLoaded = true;
103        }, 300);
104    };
105
106    const getProduct = async function(page, prepend = false) {
107        options.pageNo = prepend == false ? Number(page) + 1 : Number(page) - 1;
108        if (options.pageNo < 1) return;
109
110        const products = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}[data-page="${options.pageNo}"]`);
111        if (products.length > 0) return;
112
113        document.body.classList.add('is-loading-products');
114        prepend == false ? downLoaded = false : upLoaded = false;
115
116        let params = getLink('link', window.location.pathname.replaceAll(/^\//ig, ''));
117        params = getLink('ps', '', params);
118        params = getLink('pg', options.pageNo, params);
119        params = params.replaceAll(/^[^?]*\//g, '');
120        params = params.replace('?', '&');
121
122        await $.ajax({
123            url: '/srv/service/product/loader?' + params,
124            success: async function (result) {
125                if (result) await appendProduct(result, prepend);
126            }
127        });
128
129        document.body.classList.remove('is-loading-products');
130    };
131
132    let lastScrollTop = 0;
133    const runScroll = async function() {
134        const { clientHeight } = document.documentElement,
135        pageProducts = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}[data-page]`);
136        if (pageProducts.length == 0) return;
137
138        pageProducts.forEach(async (product) => {
139            const productRect = product.getBoundingClientRect();
140            const productGap = productRect.height > window.innerHeight ? productRect.height / 2 : 0;
141            if (productRect.top >= 0 && (productRect.bottom - productGap <= window.innerHeight) && getVar('ps') != product.dataset.page) {
142                if (product.dataset.page == 1) {
143                    paginationPushState('pagination', `Page ${product.dataset.page}`, getLink('ps', ''));
144                } else {
145                    paginationPushState('pagination', `Page ${product.dataset.page}`, getLink('ps', product.dataset.page));
146                }
147            }
148        });
149
150        const products = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}[data-page="${getVar('ps') || 1}"]`),
151            firstProduct = products[0].getBoundingClientRect(), 
152            lastProduct = products[1] ? products[1].getBoundingClientRect() : products[0].getBoundingClientRect();
153
154        let currentScrollTop = window.scrollY || document.documentElement.scrollTop;
155        if (currentScrollTop > lastScrollTop) {
156            if (((lastProduct.height / 2) + lastProduct.top) < clientHeight && downLoaded == true) getProduct(getVar('ps') || 1);
157        } else if (currentScrollTop < lastScrollTop) {
158            if (firstProduct.top > 0 && (firstProduct.bottom  / 2) < clientHeight && options.up == true && upLoaded == true) getProduct(getVar('ps') || 1, true);
159        }
160        lastScrollTop = currentScrollTop;
161    };
162
163    $(window).load(function() {
164        window.addEventListener('scroll', runScroll);
165        document.body.addEventListener('touchend', runScroll, false);
166
167        if (getVar('ps') && Number(getVar('ps')) > 1 && DYNAMIC_LOADING_SHOW_BUTTON == 1) {
168            if (history.scrollRestoration) history.scrollRestoration = 'manual';
169
170            const getProductIdCookie = getCookie('productIndex');
171            setCookie('productIndex', '');
172            if (getProductIdCookie) {
173                const getProductId = JSON.parse(getProductIdCookie);
174                if (getProductId?.category == window.location.pathname && getProductId?.product) {
175                    const product = document.querySelector(`${options.parentDiv} ${options.productDiv}[data-index="${getProductId.product}"]`);
176                    const otherProduct = document.querySelector(`${options.parentDiv} ${options.productDiv}`);
177
178                    let scrollY = 0;
179                    if (product) {
180                        scrollY = product.offsetTop - 100;
181                    } else if (otherProduct) {
182                        scrollY = otherProduct.offsetTop - 100;
183                    }
184
185                    window.scrollTo(0, scrollY);
186                }
187            }
188        }
189    });
190
191    this.run = function() {
192        const products = document.querySelectorAll(`${options.parentDiv} ${options.productDiv}`);
193        if (products.length > 0) addClassProduct(products);
194    }
195
196    if (getVar('ps') && Number(getVar('ps')) > 1 && DYNAMIC_LOADING_SHOW_BUTTON == 1) {
197        const loadBtn = document.createElement('div');
198        loadBtn.className = 'col col-12 mb product-loader-btn';
199        loadBtn.style = 'display: flex; justify-content: center';
200        loadBtn.innerHTML = `<button id="product-loader-btn" class="btn btn-warning">
200${LANG.get('show_more_products')}</button>`;
201        document.querySelector(options.parentDiv).before(loadBtn);
202        loadBtn.querySelector('#product-loader-btn').addEventListener('click', () => {
203            loadBtn.remove();
204            options.up = true;
205            getProduct(getVar('ps'), true);
206        });
207    }
208};

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.