2

I am trying to iterate through a collection of elements, trying to locate a specific element and apply a class to that element. The problem is that, even though the selector returns a collection of objects, and does enter the conditional that applies the class, when looking at the source the class is not applied.

This is the function:

function HighlightNav() {

$('.quick-launch-nav').css('visibility', 'visible');
var navitems = $('a.topnav-item[href]');
$(navitems).each(function () {
    var item = this;
    var linkUrl = item.href;
    var webUrl = IPC_siteUrl + IPC_webUrl;

    if (webUrl.match('^' + linkUrl)) {
        $(item).addClass('topnavselected');
        var parent = $(item).parent('.topnav-item');
        $(parent).addClass('topnavselected');
    }
});
}

When I try to debug it by looking at the inner html, it returns a javascript function and not what I expected.

Am I doing something wrong here?

Here is the markup. FYI its SharePoint so its ugly.

<td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="zz1_TopNavigationMenun0">
    <table class="topnav-item zz1_TopNavigationMenu_4" cellpadding="0" cellspacing="0" border="0" width="100%">
        <tr>
            <td style="white-space:nowrap;">
                <a class="zz1_TopNavigationMenu_1 topnav-item zz1_TopNavigationMenu_3"
                 href="http://webapp/en/about" 
                 accesskey="1" style="border-style:none;font-size:1em;">About</a>
            </td>
        </tr>
    </table>
</td>

And when I try to do $(item).html.toString() this is what I get:

function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)}"
6
  • 1
    Could you post the markup too? Commented May 1, 2012 at 16:20
  • 1
    BTW, navitems is already a jQuery object, you don't need to make $(navitems) again. Commented May 1, 2012 at 16:21
  • @mattytommo I added the markup. Commented May 1, 2012 at 16:26
  • @JohnS thanks, but I can't see where the function HighlightNav() is called in that markup :) Commented May 1, 2012 at 16:28
  • Its run after the SP.js script file is loaded. Commented May 1, 2012 at 16:31

2 Answers 2

1

Following your JavaScript code and HTML markup, the problem seems to be in this line:

var parent = $(item).parent('.topnav-item');

The selector .topnav-item should select the parent node with class name topnav-item. However, the parent item of each a item is td which does not have this class.

So, if you need to add topnavselected class to table node then you can use this:

var parent = $(item).parentsUntil('.topnav-item').parent();

So, the final code should look like:

function HighlightNav() {
    $('.quick-launch-nav').css('visibility', 'visible');
    $('a.topnav-item[href]').each(function() {
        var item = $(this);
        var linkUrl = this.href;
        var webUrl = IPC_siteUrl + IPC_webUrl;

        if (webUrl.match('^' + linkUrl)) {
            item.addClass('topnavselected');
            var parent = item.parentsUntil('.topnav-item').parent();
            parent.addClass('topnavselected');
        }
    });
}​
Sign up to request clarification or add additional context in comments.

4 Comments

Ill give that a shot, however when this line is run "$(item).addClass('topnavselected');" the class still doesnt get added to that element in the html.
@JohnS, please try the HighlightNav() method from the updated version of the answer. If webUrl.match(...) condition works properly, the classes should be added.
When im in the developer console of internet explorer, and use item.attr('class'); in the script window I see that the class has been added, but the display is not updated, and checking the source does not show that the class has been added.
@JohnS, JavaScript makes dynamic changes to your markup, so the sources of your HTML page won't be changed (only the debugger can show the changes). To see that the class was added you can also use CSS stylesheets in order to highlight your element with the certain class. Add a class .topnavselected { background: red; } to check if the class was added to a and to table elements.
0

item will be an html element inside the each. If you want a jQuery object, which it looks like you do:

$(item) will give you that inside the each

1 Comment

Im not sure I follow. Should I replace the item=this with item=$(this) ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.