#jquery #url-routing
#jquery #url-маршрутизация
Вопрос:
У меня есть следующий код, который пытается добавить класс selected к ссылке, соответствующей URL:
var pathname = window.location.pathname;
$(document).ready(function ()
{
$('ul#ui-ajax-tabs li a').each(function()
{
if (pathname.indexOf($(this).attr('href')) == 0)
{
$(this).parents('li').addClass('selected');
}
});
});
1.) Так, например, если у меня есть URL /Organisations/Journal
-адрес, и /Organisations/Journal/Edit
ссылка с организациями и журналом будет отображаться как выбранная. Это нормально!
2.) Однако иногда у меня есть URL-адреса типа: /Organisations
и /Organisations/Archived
и если у меня есть ссылка на архив, то будут выбраны оба, НО я не хочу, чтобы это произошло, потому что организации, подобные, не имеют второй части URL, поэтому не должны совпадать.
Может ли кто-нибудь помочь заставить это работать для вторых типов, не нарушая первый тип? Также ничто из этого не может быть жестко запрограммированным регулярным выражением для поиска ключевых слов, поскольку URL-адреса имеют множество разных параметров!
Приветствия
ПРИМЕРЫ:
Если URL- /Organisations/
адрес Или /Organisations
, то /Organisations
должна быть выбрана ссылка с. Если URL-адрес является /Organisations/Journal/New
ссылкой с /Organisations/Journal
или /Organisations/Journal/New
будет выбран.
НО если у меня есть URL с /Organisations/Recent
и есть две ссылки: /Organisations
и /Organisations/Recent
тогда должна быть выбрана только вторая! Итак, здесь следует отметить, что у него должен быть третий параметр, прежде чем он будет искать биты URL более свободно, а не точное совпадение.
Помните, что это не всегда могут быть организации, поэтому они не могут быть жестко запрограммированы в JS!
Комментарии:
1. Не могли бы вы подробнее остановиться на своих примерах? Возможно, даже предоставить jsFiddle с двумя случаями?
2. Хорошо, я правильно понял … Вы хотите, чтобы наилучшее совпадение было выделено как текущее?
3. Да, это правильно, но, как показано в примерах, по существу, будет выделена только одна ссылка, если они лучше совпадают, выделите ее по сравнению с другой, которая могла быть близка.
4. Это ограничение по времени, прежде чем я смогу принять ответ, и у меня не всегда есть время проверить, когда оно истекло, а иногда я не всегда получаю ответ, который хочу!
![]()
Ответ №1:
Редактировать: мое предыдущее решение было довольно сложным. Обновленный ответ и скрипка.
var pathname = window.location.pathname;
$(document).ready(function ()
{
var best_distance = 999; // var to hold best distance so far
var best_match = false; // var to hold best match object
$('ul#ui-ajax-tabs li a').each(function()
{
if (pathname.indexOf($(this).attr('href')) == 0)
{
// we know that the link is part of our path name.
// the next line calculates how many characters the path name is longer than our link
overlap_penalty = pathname.replace($(this).attr('href'), '').length;
if (overlap_penalty < best_distance) { // if we found a link that has less difference in length that all previous ones ...
best_distance = overlap_penalty; // remember the length difference
best_match = this; // remember the link
}
}
});
if (best_match !== false)
{
$(best_match).closest('li').addClass('selected');
}
});
Наилучшее совпадение вычисляется следующим образом:
Предположим, что наш путь — «/foo/bar/baz /x». У нас есть две ссылки, о которых идет речь:
- /foo/bar/
- /foo/bar/baz
Вот что происходит:
/foo/bar/baz /x (URL-адрес первой ссылки удаляется из имени путиpathname.replace($(this).attr('href'), '')
)- «baz / x» — это то, что остается.
- Количество символов (
length
) этого остатка равно 5. это наш «штраф» за ссылку. - Мы сравниваем 5 с нашим предыдущим лучшим расстоянием (
if (overlap_penalty < best_distance)
). 5 меньше (= лучше), чем 999. - Мы сохраняем
this
(будучи объектом<a href="/foo/bar/">
DOM) для возможного последующего использования. - Вторая ссылка обрабатывается таким же образом:
/foo/bar/baz/x (URL-адрес второй ссылки удаляется из имени пути)- «/ x» — это то, что остается.
- Количество символов в этом остатке равно 2.
- Мы сравниваем 2 с нашим предыдущим лучшим расстоянием (равным 5). 2 меньше 5.
- Мы сохраняем
this
(будучи объектом<a href="/foo/bar/baz">
DOM) для возможного последующего использования.
В конце мы просто проверяем, нашли ли мы какую-либо подходящую ссылку, и, если да, применяем addClass('selected')
к ее ближайшему <li>
родителю.
Комментарии:
1. Святая корова, это какой-то сложный код: P, хотя, похоже, выполняет свою работу. Есть ли шанс, что вы могли бы объяснить, что он делает в каждой строке? Хотелось бы узнать больше. Приветствия.
2. Обновлен ответ. Получайте удовольствие!
Ответ №2:
Почему вы не используете
if($(this).attr('href') == pathname )
вместо
if (pathname.indexOf($(this).attr('href')) == 0)
Комментарии:
1. Потому что это будет искать точные совпадения!
Ответ №3:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var windowLocationPathname = "/HTMLPage14.htm"; // For testing purpose.
//Or
//var windowLocationPathname = window.location.pathname;
$('ul.ui-ajax-tab').find('a[href^="' windowLocationPathname '"]').addClass('currentPage');
});
</script>
<style type="text/css">
.ui-ajax-tab
{
list-style: none;
}
a.currentPage
{
color: Red;
background-color: Yellow;
}
</style>
</head>
<body>
<ul class="ui-ajax-tab">
<li><a href="/HTMLPage14.htm">Test 1 (/HTMLPage14.htm)</a></li>
<li><a href="/HTMLPage15.htm">Test 2 (/HTMLPage15.htm)</a></li>
<li><a href="/HTMLPage16.htm">Test 3 (/HTMLPage16.htm)</a></li>
<li><a href="/HTMLPage17.htm">Test 4 (/HTMLPage17.htm)</a></li>
</ul>
</body>
</html>
Комментарии:
1. Это будет соответствовать ТОЧНЫМ совпадениям… Это не то, чего я хотел.