Приветствую, есть три переменные типа string.
Одна - пусть будет так: const rootUrl = window.location.origin;
Вторая - скажем relativePath как очевидно является стринговым представлением относительного url, берется из атрибута. Сложение этих двух стрингов сравнивается с третьей переменной -
var currentUrl = window.location.href;
Проблема в том, что вторая переменная - relativePath - может быть записана несколькими вариантами - со слешами и/или в начале и/или в конце, и так и так, и совсем без них.
Например -
/category/product1/
/category/product2
category/product3/
/page.html/
и тд и тп.
Последняя переменная currentUrl также может быть как со слешем в конце так и без слеша.
Поэтому, перед конкатинацией и сравнением надо сначала удалить слеши у relativePath и у currentUrl, но только если слеш первый и/или последний символ в строке, чтобы не удалить промежуточные слеши, а потом уже например
rootUrl.concat('/', relativePath); - и уже сравнивать с currentUrl
Проблема что я с регулярками не дружу почти, подскажите как правильную составить )
Однако стоит учесть, что window.location.href может содержать query string и hash string.
Поэтому лучше преобразовать все адреса в URL (new URL(window.location.href)) и уже из этого объекта собирать URL domain + pathname.
Тогда и регулярки не понадобятся скорее всего.
спасибо, все в принципе работает, где то туплю с синтаксиксом -
мне надо перебрать массив в меню, выдернуть из них атрибуты, почистить их от этих слешей(если есть), добавить их стрингами (если пути относительные) и сравнить с текущим url.
Ну например, что то вроде
$('.uxnav li a,').each(function () {
if ($(this).attr('href') == currentUrl || rootUrl.....дальше остальные условия {
здесь код по условию
}
Если не убирать слеши, то приходится ставить много логических "или", но все работает.
Однако если я у $(this).attr('href') пытаюсь убрать слеши - $(this).attr('href').replace(/^\/|\/$/g, '')
сразу получаю
Cannot read properties of undefined (reading 'replace')
lagudal, Эта ошибка значит, что в $(this).attr('href') у вас undefined.
Может запятая в селекторе лишняя. (Она там стопроцентно лишняя, но я не знаю как ведет себя выборка в таком случае).
Сергей delphinpro,
в принципе все получилось, я часто воообще не понимаю, почему например в переборе такого массива, если обращаешься к this по селектору возникает ошибка.
т.е. если вот так -
$('.uxnav li a').each(function () {
if ($(this).attr('href').replace(....) == currentUrl || rootUrl.....дальше остальные условия {
здесь код по условию
}
- undefined,
a если так -
var relativeUrl = $('.uxnav li a');
relativeUrl.each(function () {
if ($(this).attr('href').replace(.....) == currentUrl || rootUrl.....дальше остальные условия {
здесь код по условию
}
то все работает. Хотя внешне ну вроде одно и то же.
lagudal, я подозреваю, что проблема в запятой в селекторе $('.uxnav li a,') // Здесь
Повторюсь, что я не знаю какая будет выборка. Ну не приходило мне в голову этот странный случай потестить. Могу лишь предположить, что там в выборке помимо ссылко, будут и все остальные элементы, или еще какая-то дичь, кроме ссылок. А у всего, кроме ссылок отсутствует атрибут href. Вот вам и undefined.
Сергей delphinpro,
да вы правы, ошибка не в этом была. У меня на самом деле 2 селектора, я их оба в одном цикле перебирал. Оттуда и ошибочная запятая )
И вот тут ошибка -- если так делаю
$('.uxnav li a , .uxnav li span.redir-mask').each(function () {
.... тут код с заменой и функционалом...
}
то вот ошибка c undefined replace
Если 2 отдельных цикла то без проблем.
Причем, если нет этой замены, то нет и ошибки, поскольку нет replace.
не поэтому. Я же написал выше предположение – потому что в выборку попадают не ссылки. Конкретно – спаны. У них нет атрибутов href, и получается undefined
Сергей delphinpro,
эти спаны - замаскированные ссылки, у них нет атрибутов href, но есть другой атрибут, в моем случае data-submit.
Чисто интерес, непонятка.
Ну вот воспроизвел ситуацию тут.
Проблему со слешами - а именно почему их надо удалять - воспроизвести сложнее, она существует на реальном проекте - на суть что меня интересует тут это не влияет.
Пункты меню раскрываются по клику, не по hover, После перехода по клику по любому подменю пункту добавляется класс current для корневого пункта меню. Добавил пару маскированных меню пунктов (спанов) - можно увидеть в woman - additional link-2, additional link-4.
Сейчас как видно нужная функциональность не работает - Uncaught TypeError: Cannot read properties of undefined (reading 'replace')
Текущий код( можно увидеть в файле uxmenuprod.js - функция markCurrent
Для удобства.
require(['jquery'], function ($) {
var removeSlash = function (string) {
return string.replace(/^\/|\/$/g, '');
}
const rootUrl = window.location.origin;
var currentUrl = window.location.href;
$('.uxnav-main-prod li a, .uxnav-main-prod li span.redir-mask').each(function () {
if (removeSlash(currentUrl) === [rootUrl, removeSlash($(this).attr('href'))].join('/') || removeSlash(currentUrl) === removeSlash($(this).attr('href')) || removeSlash(currentUrl) === [rootUrl, removeSlash($(this).attr('data-submit'))].join('/')) {
$(this).parents('li.level0.category-item').addClass('current');
}
})
})
НО если убрать replace - то можно просто в консоли убедиться, что все работает.
require(['jquery'], function ($) {
const rootUrl = window.location.origin;
var currentUrl = window.location.href;
$('.uxnav-main-prod li a, .uxnav-main-prod li span.redir-mask').each(function () {
if (currentUrl === [rootUrl, $(this).attr('href')].join('/') || currentUrl === $(this).attr('href') || currentUrl === [rootUrl, $(this).attr('data-submit')].join('/')) {
$(this).parents('li.level0.category-item').addClass('current');
}
})
})
Если же мне действительно нужна эта замена (а она мне обязательно нужна) то работает только если выбираю из 2 циклов, например:
require(['jquery'], function ($) {
var removeSlash = function (string) {
return string.replace(/^\/|\/$/g, '');
}
const rootUrl = window.location.origin;
var currentUrl = window.location.href;
$('.uxnav-main-prod li a').each(function () {
if (removeSlash(currentUrl) === [rootUrl, removeSlash($(this).attr('href'))].join('/') || removeSlash(currentUrl) === removeSlash($(this).attr('href'))) {
$(this).parents('li.level0.category-item').addClass('current');
}
})
$('.uxnav-main-prod li span.redir-mask').each(function () {
if (removeSlash(currentUrl) === [rootUrl, removeSlash($(this).attr('data-submit'))].join('/')) {
$(this).parents('li.level0.category-item').addClass('current');
}
})
})