Как добавить класс к ссылке открытой страницы плюс с пагинацией?

Ссылка скопирована
1 ответ

Доброго дня!

Есть блок меню, написан на PHP, на выходе имеет вот такой HTML-код (примерно):

<div class="tag_menu"> <ul class="dop_product_tag"> <li><a href="https://test.ru/primer1" class="primer1">Пример1</a></li> <li><a href="https://test.ru/primer2" class="primer2">Пример2</a></li> <li><a href="https://test.ru/primer3" class="primer3">Пример3</a></li> <li><a href="https://test.ru/primer4" class="primer4">Пример4</a></li> <li><a href="https://test.ru/primer5" class="primer5">Пример5</a></li> </div>

<div class="tag_menu"> <ul class="dop_product_tag"> <li><a href="https://test.ru/primer1" class="primer1">Пример1</a></li> <li><a href="https://test.ru/primer2" class="primer2">Пример2</a></li> <li><a href="https://test.ru/primer3" class="primer3">Пример3</a></li> <li><a href="https://test.ru/primer4" class="primer4">Пример4</a></li> <li><a href="https://test.ru/primer5" class="primer5">Пример5</a></li> </div>

Мне нужно подсветить ссылку открытой страницы, то есть добавить дополнительный класс к элементу.
Я это сделал через JavaScript:

document.addEventListener("DOMContentLoaded", function() {   var currentPage = window.location.pathname;   var menuLinks = document.querySelectorAll(".dop_product_tag a");   for (var i = 0; i < menuLinks.length; i++) {     if (menuLinks[i].pathname === currentPage) {        menuLinks[i].classList.add("active");     }   } });

document.addEventListener("DOMContentLoaded", function() { var currentPage = window.location.pathname; var menuLinks = document.querySelectorAll(".dop_product_tag a"); for (var i = 0; i < menuLinks.length; i++) { if (menuLinks[i].pathname === currentPage) { menuLinks[i].classList.add("active"); } } });

Всё работает, он к элементу открытой странице добавляет класс active например:

<li><a href="https://test.ru/primer2" class="primer2 active">Пример2</a></li>

<li><a href="https://test.ru/primer2" class="primer2 active">Пример2</a></li>

Но когда я дописываю скрипт на проверку пагинации, он не работает: (пагинация в виде: https://test.ru/primer2/page/2/)
я дописываю в if || is_paged()

if (menuLinks[i].pathname === currentPage || is_paged())

if (menuLinks[i].pathname === currentPage || is_paged())

а далее функцию (соответственно после всего кода)

document.addEventListener("DOMContentLoaded", function() {   var currentPage = window.location.pathname;   var menuLinks = document.querySelectorAll(".dop_product_tag a");   for (var i = 0; i < menuLinks.length; i++) {     if (menuLinks[i].pathname === currentPage || is_paged()) {        menuLinks[i].classList.add("active");     }   } }); function is_paged() {   return window.location.pathname.includes("/page/"); }

document.addEventListener("DOMContentLoaded", function() { var currentPage = window.location.pathname; var menuLinks = document.querySelectorAll(".dop_product_tag a"); for (var i = 0; i < menuLinks.length; i++) { if (menuLinks[i].pathname === currentPage || is_paged()) { menuLinks[i].classList.add("active"); } } }); function is_paged() { return window.location.pathname.includes("/page/"); }

класс не добавляется и соответственно ссылка не подсвечивается.
также есть фильтр товаров в виде /?filter_type_test=test45

какой код для фильтра писать, чтобы добавлялся класс я не знаю.

Подскажите пожалуйста, может поможет кто решить?

Спасибо!

Дополнительно:

такие классы лучше расставлять в php. Нормальный роутер обычно знает, что данная ссылка является текущей страницей

Как добавить класс к ссылке открытой страницы плюс с пагинацией?

szQocks @szQocks

Но когда я дописываю скрипт на проверку пагинации, он не работает

function is_paged() {   return window.location.pathname.split("/").includes('page') }

function is_paged() { return window.location.pathname.split("/").includes('page') }

какой код для фильтра писать, чтобы добавлялся класс я не знаю.

function isFilter(){   return window.location.pathname.split("/").some(n => n.split('=').includes('?filter_type_test')) }

function isFilter(){ return window.location.pathname.split("/").some(n => n.split('=').includes('?filter_type_test')) }

  • кстати функцию isFilter можно переписать и прокидывать в неё сепаратор с параметром
    function isParam(param, separator){   return window.location.pathname.split("/").some(n => n.split(separator).includes(param)) }  isParam('?filter_type_test',  '=')

    function isParam(param, separator){ return window.location.pathname.split("/").some(n => n.split(separator).includes(param)) } isParam('?filter_type_test', '=')

  • Спасибо большое, работает!
    Но есть другая проблема: с фильтром работает, но только после обновления страницы. (видимо из-за AJAX)
    А с пагинацией после обновления страницы класс добавляется ко всем ссылкам.
  • Роман,
    function is_paged() {   const arr = window.location.pathname.split("/");   let index = arr.indexOf("page");   return index >= 0 ? +arr[++index] : false }

    function is_paged() { const arr = window.location.pathname.split("/"); let index = arr.indexOf("page"); return index >= 0 ? +arr[++index] : false }

    for (var i = 0; i < menuLinks.length; i++) {     const page = is_paged();     if (menuLinks[i].pathname === currentPage) {        menuLinks[i].classList.add("active");     } else if (page == i){        menuLinks[i].classList.add("active");     }   }

    for (var i = 0; i < menuLinks.length; i++) { const page = is_paged(); if (menuLinks[i].pathname === currentPage) { menuLinks[i].classList.add("active"); } else if (page == i){ menuLinks[i].classList.add("active"); } }

    ну попробуй так чтоле
    вообще там на самом деле ещё нюансы есть типа атрибуты на ссылки повесить что бы потом понимать что это ссылка, ну пока я в условии с индексом написал, ну как ты собираешь писать если не знаешь js, странно это, ну на вопрос я ответил в любом случае, если что-то не отработает задавай новый вопрос

  • хорошо, спасибо большое за помощь, завтра проверю, отпишусь.
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Виктор Sys Ответ

Для подсветки текущей ссылки лучше сравнивать не весь URL, а нормализованный путь. При пагинации URL может быть /primer1/page/2/, а ссылка в меню — /primer1/. Простое сравнение pathname === currentPage в таком случае не сработает.

Вариант на JavaScript: убираем из текущего пути хвост пагинации и сравниваем с путём ссылки.

document.addEventListener('DOMContentLoaded', function () {
    const normalizePath = function (path) {
        return path
            .replace(//page/d+/?$/, '/')
            .replace(//+$/, '/');
    };
 
    const currentPath = normalizePath(window.location.pathname);
    const links = document.querySelectorAll('.dop_product_tag a');
 
    links.forEach(function (link) {
        const linkPath = normalizePath(new URL(link.href).pathname);
 
        if (linkPath === currentPath) {
            link.classList.add('active');
        }
    });
});

document.addEventListener('DOMContentLoaded', function () { const normalizePath = function (path) { return path .replace(//page/d+/?$/, '/') .replace(//+$/, '/'); }; const currentPath = normalizePath(window.location.pathname); const links = document.querySelectorAll('.dop_product_tag a'); links.forEach(function (link) { const linkPath = normalizePath(new URL(link.href).pathname); if (linkPath === currentPath) { link.classList.add('active'); } }); });

CSS для активного пункта:

.dop_product_tag a.active {
    color: #fff;
    background: #1b5083;
}

.dop_product_tag a.active { color: #fff; background: #1b5083; }

Если меню генерируется PHP-кодом, ещё лучше добавить класс сразу на сервере. Тогда подсветка будет работать без ожидания JavaScript и не будет мигать при загрузке.

$current_path = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
$current_path = preg_replace('~page/[0-9]+/?$~', '', $current_path);
$current_path = trim($current_path, '/');
 
foreach ($links as $item) {
    $link_path = trim(parse_url($item['url'], PHP_URL_PATH), '/');
    $is_active = ($link_path === $current_path);
 
    echo '<a href="' . esc_url($item['url']) . '" class="' . ($is_active ? 'active' : '') . '">';
    echo esc_html($item['title']);
    echo '</a>';
}

$current_path = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/'); $current_path = preg_replace('~page/[0-9]+/?$~', '', $current_path); $current_path = trim($current_path, '/'); foreach ($links as $item) { $link_path = trim(parse_url($item['url'], PHP_URL_PATH), '/'); $is_active = ($link_path === $current_path); echo '<a href="' . esc_url($item['url']) . '" class="' . ($is_active ? 'active' : '') . '">'; echo esc_html($item['title']); echo '</a>'; }

Если это WordPress-меню, штатный wp_nav_menu() уже добавляет классы вроде current-menu-item, current_page_item и current-menu-ancestor. В этом случае не нужен свой скрипт, достаточно CSS под эти классы.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно