// ==UserScript== // @name Ozon and Wildberries customizer: sorting reviews by ascending rating // @name:ru Ozon и Wildberries настройка: сортировка отзывов по возрастанию рейтинга // @namespace http://tampermonkey.net/ // @version 2024-05-18 // @description Ozon.ru with reviews sorted in descending order of rating // @description:ru Ozon и Wildberries: сортировка отзывов по товару по возрастанию рейтинга // @author Igor Lebedev // @license GPL-3.0-or-later // @icon https://raw.githubusercontent.com/LebedevIV/Ozon-and-Wildberries-customizer/master/icons/ozon_wildberries_44x44.png // @match http://*.ozon.ru/* // @match https://*.ozon.ru/* // @match http://*.wildberries.ru/* // @match https://*.wildberries.ru/* // @downloadURL none // ==/UserScript== (function() { 'use strict' // получаем текущий адрес страницы const currentURL = window.location.href // Wildberries: Ожидание загружки страницы товара до появления элемента сортировки рейтинга и искусственное двойное нажатие этого элемента чтобы добиться сортировки рейтинга по возрастанию function sortWildberriesReviews() { const interval = setInterval(() => { // ожидание загрузки страницы до необходимого значения const sortButton = document.querySelector("#app > div:nth-child(5) > div > section > div.product-feedbacks__main > div.user-activity__tab-content > div.product-feedbacks__sorting > ul > li:nth-child(2) > a"); // if (sortButton) { // sortButton.click(); // Первый клик по кнопке сортировки // sortButton.click(); // Второй клик с непонятной целью - потенциально для удостоверения сортировки // clearInterval(interval); // } if (sortButton) { // Создаем событие click // let eventClick = new MouseEvent("click", { // bubbles: true, // cancelable: true, // // clientX: 100, // // clientY: 100 // }); // Инициируем событие на элементе // Проверяет, содержит ли элемент класс 'sorting__selected' if (sortButton.classList.contains('sorting__selected')) { // Находим элемент внутри найденного let span = sortButton.querySelector('span'); // Проверяем, содержит ли класс 'sorting__decor--up' // Если содержит, значит, сортировка по возрастанию уже произведена и никаких действий производить не нужно (всё равно приходится произвести два клика, так как, по-видимому, по мере загрузки происходит последующий сброс настроек) - надо отловить объект, который появляется уже после сброса, и зацепиться за него if (span && span.classList.contains('sorting__decor--up')) { // console.log('Элемент внутри принадлежит классу sorting__decor--up.'); // Первое нажатие производит сортировку по убыванию рейтинга // sortButton.dispatchEvent(eventClick); // sortButton.click(); // Второе нажатие производит сортировку по возрастанию рейтинга // sortButton.dispatchEvent(eventClick); // sortButton.click(); } else { // Нажатие производит сортировку по возрастанию рейтинга // sortButton.dispatchEvent(eventClick); sortButton.click(); } } else { // Первое нажатие производит сортировку по убыванию рейтинга // sortButton.dispatchEvent(eventClick); sortButton.click(); // Второе нажатие производит сортировку по возрастанию рейтинга // sortButton.dispatchEvent(eventClick); sortButton.click(); } clearInterval(interval); } }, 500); } // Ozon: Функция для добавления к ссылкам параметра сортировки рейтинга по возрастанию - на случай если пользователь будет вручную открывать ссылки с карточкой товара в новой вкладке function addOzonSortParamToLinks() { const links = document.querySelectorAll('a[href^="/product/"]:not([href*="&sort=score_asc"])'); links.forEach(link => { link.href += '&sort=score_asc'; }); } // Проверка, является ли страница карточкой товара, содержащей отзывы, и если да - сортировка отзывов по возрастанию рейтинга: // Ozon: начинается ли адрес страницы со 'https://www.ozon.ru/product/' и не содержит ли он уже '&sort=score_asc' if (currentURL.includes('ozon.ru/product/') && !currentURL.includes('&sort=score_asc')) { // Если условия выполняются - добавляем к адресу параметр и перезагружаем страницу с новым адресом, производящим сортировку рейтингов по возрастанию window.location.href ||= `${currentURL}&sort=score_asc`; // Wildberries: } else if (currentURL.includes('wildberries.ru/catalog/') && currentURL.includes('/feedbacks?imtId=')) { sortWildberriesReviews(); } // Wildberries: определение совершения перехода на карточку товара с разделом отзывов // перехват событияй истории (кнопок назад-вперёд) window.onpopstate = () => { // получаем текущий адрес страницы if (new URL(window.location.href).pathname.startsWith('/catalog/') && window.location.search.includes('feedbacks?imtId=')) { sortWildberriesReviews(); } }; // перехват события обновления адреса страницы другим скриптом без перезагрузки страницы // const originalHistoryMethods = { // pushState: history.pushState, // replaceState: history.replaceState // }; // history.pushState = function(state, ...rest) { // if (typeof history.onpushstate === "function") { // history.onpushstate({state}); // } // return originalHistoryMethods.pushState.apply(history, [state, ...rest]); // }; // history.replaceState = function(state, ...rest) { // if (typeof history.onreplacestate === "function") { // history.onreplacestate({state}); // } // return originalHistoryMethods.replaceState.apply(history, [state, ...rest]); // }; const originalPushState = history.pushState; history.pushState = function (state, ...args) { originalPushState.apply(this, [state, ...args]); // Вызываем функцию сортировки после пуша состояния sortWildberriesReviews(); }; // const originalReplaceState = history.replaceState; // history.replaceState = function (state, ...args) { // originalReplaceState.apply(this, [state, ...args]); // // Вызываем функцию сортировки после замены состояния // sortWildberriesReviews(); // }; // window.history.onpushstate = () => { // // if (new URL(window.location.href).pathname.startsWith('/catalog/') && window.location.search.includes('feedbacks?imtId=')) { // if (new URL(window.location.href).pathname.startsWith('/catalog/') ) { // sortWildberriesReviews(); // } // }; // history.pushState = new Proxy(history.pushState, { // apply: function(target, thisArg, argArray) { // target.apply(thisArg, argArray); // sortWildberriesReviews(); // } // }); history.replaceState = new Proxy(history.replaceState, { apply: function(target, thisArg, argArray) { target.apply(thisArg, argArray); sortWildberriesReviews(); } }); // Ozon: Замена ссылок на странице на случай если пользователь захочет открыть ссылку карточки товара в новой вкладке. Отработает позднее, после загрузки. Не обязательное действие. // Вызываем функцию сразу после загрузки страницы if (currentURL.startsWith('https://www.ozon.ru/')) { window.addEventListener('load', addOzonSortParamToLinks) } })();