开发者

jQuery: Finding link best matching to current URL

I have the following code which tries to add a class of selected to a link that matches the 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.) So for example if I have a url like /Organisations/Journal and /Organisations/Journal/Edit a link with Organisations and Journal will show as being selected. This is fine!

2.) However sometimes I have urls like: /Organisations and /Organisations/Archived and if I have a link to the Archived then both will be selected BUT I don't want this to happen because the Organisations like doesn't have the second part of the url so shouldn't match.

Can anyone help with getting this working for the second types Without breaking the first type? Also none of this can be hardcoded regex looking for keywords as the urls have lots of different parameters!

Cheers

EXAMPLES:

If the url is /Organisations/ Or /Organisations then a link with /Organisations should be selected. If the URL is /Organisations/Journal/New then a link with /Organisations/Journal or /Organisations/Journal/New would be selected.

BUT if I have a url with /Organisations/Recent and have two links: /Organisations and /Organisations/Recent then only the seco开发者_开发知识库nd should be selected! So the thing to note here is that it must have a third parameter before it should look for bits of the URL more loosly rather than an exact match.

Remember it might not always be Organisations so it can't be hardcoded into the JS!


Edit: My previous solution was quite over-complicated. Updated answer and fiddle.

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');
    }
});

The best match is calculated like so:

Assume our pathname is "/foo/bar/baz/x". We have two links in question:

  • /foo/bar/
  • /foo/bar/baz

This is what happens:

  1. /foo/bar/baz/x (the first link's url is deleted from the path name pathname.replace($(this).attr('href'), ''))
  2. "baz/x" is what remains.
  3. The character count (length) of this remainder is 5. this is our "penalty" for the link.
  4. We compare 5 to our previous best distance (if (overlap_penalty < best_distance)). 5 is lower (=better) than 999.
  5. We save this (being the <a href="/foo/bar/"> DOM object) for possible later use.
  6. The second link is handled in the same manner:
  7. /foo/bar/baz/x (the second link's url is deleted from the path name)
  8. "/x" is what remains.
  9. The character count of this remainder is 2.
  10. We compare 2 to our previous best distance (being 5). 2 is lower than 5.
  11. We save this (being the <a href="/foo/bar/baz"> DOM object) for possible later use.

In the end, we just check if we found any matching link and, if so, apply addClass('selected') to its closest <li> parent.


Why dont u use

if($(this).attr('href') == pathname )

instead of

if (pathname.indexOf($(this).attr('href')) == 0)


<!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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜