Бесконечный контент в темах
As of
// ==UserScript==
// @name ThreadScroll
// @namespace https://greasyfork.org/ru/users/1142494-llimonix
// @version 0.6
// @description Бесконечный контент в темах
// @author llimonix
// @license MIT
// @match https://lolz.live/threads/*
// @icon https://i.imgur.com/ZiddNv0.png
// @run-at document-start
// @grant none
// ==/UserScript==
(function() {
'use strict';
const SCROLL_THRESHOLD_MOBILE = 150;
const SCROLL_THRESHOLD_DESKTOP = 10;
const MOBILE_WIDTH = 480;
let currentPageURL = null;
let currentPage = 1;
let lastPage = 1;
let currentURL = window.location.href;
let isLoading = false;
function initialize() {
currentPageURL = $("a[rel='start']").attr("href");
currentPage = parseInt($(".currentPage").text()) || 1;
lastPage = parseInt($("nav > a:last").text()) || 1;
}
function checkURLChange() {
const newURL = window.location.href;
if (newURL !== currentURL) {
currentURL = newURL;
currentPage = parseInt($(".currentPage").text()) || 1;
lastPage = parseInt($("nav > a:last").text()) || 1;
}
requestAnimationFrame(checkURLChange);
}
function updateURL(newURL) {
window.history.pushState({ path: newURL }, '', newURL);
}
function createLoadingSpinner() {
return $('<div class="Spinner spinner small loadingContent">')
.css({
background: 'center center rgb(39, 39, 39)',
padding: '0 15px',
borderStyle: 'none',
borderRadius: '10px',
lineHeight: '34px',
verticalAlign: 'top',
height: '40px',
width: '200px',
display: 'block',
margin: '15px auto'
})
.html('<div class="bounce1 bounce"></div><div class="bounce2 bounce"></div><div class="bounce3 bounce"></div>');
}
function updateCurrentPageLink(pageNum) {
const pageURL = `${currentPageURL}page-${pageNum}`;
const $link = $(`a[href='${pageURL}']`);
if ($link.length === 0) {
// Если ссылка не найдена, прокликиваем навигацию
while ($(`a[href='${pageURL}']`).length === 0) {
$(".PageNavNext").trigger("click");
}
}
$(".currentPage").removeClass("currentPage");
$(`a[href='${pageURL}']`).addClass("currentPage");
updateURL(`/${pageURL}`);
}
async function loadNextPage() {
if (isLoading) return;
isLoading = true;
currentPage++;
const $messageList = $('.messageList');
const $spinner = createLoadingSpinner();
$messageList.append($spinner);
try {
const data = await XenForo.ajax(`/${currentPageURL}page-${currentPage}`, {});
const parser = new DOMParser();
const doc = parser.parseFromString(data.templateHtml, 'text/html');
const messages = $(doc).find('li.message');
$spinner.remove();
$messageList.append(messages).xfActivate();
updateCurrentPageLink(currentPage);
} catch (error) {
console.error('Ошибка загрузки страницы:', error);
$spinner.remove();
currentPage--; // Откатываем счетчик при ошибке
} finally {
isLoading = false;
}
}
function handleScroll() {
const documentHeight = $(document).height();
const scrollPosition = $(window).scrollTop();
const windowHeight = $(window).height();
const isMobile = screen.width <= MOBILE_WIDTH;
const threshold = isMobile ? SCROLL_THRESHOLD_MOBILE : SCROLL_THRESHOLD_DESKTOP;
if (scrollPosition + windowHeight >= documentHeight - threshold) {
if (currentPage < lastPage && !isLoading) {
loadNextPage();
}
}
}
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
document.addEventListener("DOMContentLoaded", () => {
initialize();
checkURLChange();
$(window).on('scroll', debounce(handleScroll, 100));
});
})();