Welcome Guest, Not a member yet? Register   Sign In
My Simple JS to set "active" Menu
#1

[eluser]the real rlee[/eluser]
Here's a simple bit of JavaScript which sets the currently active link. Perhaps someone could build this into a helper or library

JS:
Code:
/*
@author: Richard Lee aka the real rlee
A simple JavaScript to set "active" class to active menu item based on url
*/
initMenu = function(){
    
    var url = "<?=site_url($this->uri->uri_string())?>";
    var menu = document.getElementById('main-nav').getElementsByTagName("A");
    
    for( var x = 0; x < menu.length ; x++ ){
        
        if (menu[x].href == url) {
            menu[x].className = 'active';
        }
      }
}

if (window.addEventListener) {
    window.addEventListener('load', initMenu, false);
} else if (window.attachEvent) {
    window.attachEvent("onload", initMenu);
}

</script>
HTML:
Code:
<ul id="main-menu">
  <li>
    &lt;?=anchor('home', 'home')?&gt;
  </li>
  <li>
    &lt;?=anchor('about', 'about')?&gt;
  </li>
  <li>
    &lt;?=anchor('locations', 'locations')?&gt;
  </li>
</ul>
#2

[eluser]the real rlee[/eluser]
UPDATE:

For some reason in the previous version i was using the uri class to give me the current url, when i could have used javascript - this.location.href. Also i've used a modified version of [url="http://dean.edwards.name/weblog/2005/10/add-event2/"]Dean Edwards addEvent()[/url] to limit possible conflict with other code using onload...

Here's the code, the forums wouldnt let me upload the files or use correct script tags in the html example but its all there Smile

Code:
/*
menu.js

@author: Richard Lee aka the real rlee
A simple JavaScript to set "active" class to active menu item based on url
*/
function initMenu(){
    
    var url = this.location.href;
    var menu = document.getElementById('main-nav').getElementsByTagName("A");
    
    for( var x = 0; x &lt; menu.length ; x++ ){
        
        if (menu[x].href == url) {
            menu[x].className = 'active';
        }
      }
}

addEvent(window,"load",initMenu);

Code:
/*
addevent.js

@author Dean Edwards, 2005
@modified Tino Zijdel - [email protected]
http://dean.edwards.name/weblog/2005/10/add-event/
*/

function addEvent(element, type, handler)
{
    if (element.addEventListener)
        element.addEventListener(type, handler, false);
    else
    {
        if (!handler.$$guid) handler.$$guid = addEvent.guid++;
        if (!element.events) element.events = {};
        var handlers = element.events[type];
        if (!handlers)
        {
            handlers = element.events[type] = {};
            if (element['on' + type]) handlers[0] = element['on' + type];
            element['on' + type] = handleEvent;
        }
    
        handlers[handler.$$guid] = handler;
    }
}
addEvent.guid = 1;

function removeEvent(element, type, handler)
{
    if (element.removeEventListener)
        element.removeEventListener(type, handler, false);
    else if (element.events && element.events[type] && handler.$$guid)
        delete element.events[type][handler.$$guid];
}

function handleEvent(event)
{
    event = event || fixEvent(window.event);
    var returnValue = true;
    var handlers = this.events[event.type];

    for (var i in handlers)
    {
        if (!Object.prototype[i])
        {
            this.$$handler = handlers[i];
            if (this.$$handler(event) === false) returnValue = false;
        }
    }

    if (this.$$handler) this.$$handler = null;

    return returnValue;
}

function fixEvent(event)
{
    event.preventDefault = fixEvent.preventDefault;
    event.stopPropagation = fixEvent.stopPropagation;
    return event;
}
fixEvent.preventDefault = function()
{
    this.returnValue = false;
}
fixEvent.stopPropagation = function()
{
    this.cancelBubble = true;
}

// This little snippet fixes the problem that the onload attribute on the body-element will overwrite
// previous attached events on the window object for the onload event
if (!window.addEventListener)
{
    document.onreadystatechange = function()
    {
        if (window.onload && window.onload != handleEvent)
        {
            addEvent(window, 'load', window.onload);
            window.onload = handleEvent;
        }
    }
}

Code:
&lt;html&gt;
  &lt;head&gt;
    &lt;!-- link addevent script here --&gt;
    &lt;!-- link menu script here (IMPORTANT must come after addevent) --&gt;
  &lt;/head&gt;
&lt;body&gt;
  <h1&gt;My Page</h1>
  <div id="main-nav">
  <ul>
    <li><a href="mypage.html">My Page</a></li>
  </ul>
  &lt;/body&gt;
&lt;/html&gt;
#3

[eluser]wemago[/eluser]
nice work Smile
you did something i was going to do Tongue
now i have more time to work in other stuff
#4

[eluser]the real rlee[/eluser]
Thanks, glad to give something back to the community Smile I spent a lot of time trying to create a menu library, but since my site was pretty static - my menu's were actually in view files i.e. main-nav.php - a bit of javascript made sense
#5

[eluser]Jumper[/eluser]
Why not just call directly initMenu() at the bottom of the html body?
instead of using this messy event handler ?
#6

[eluser]the real rlee[/eluser]
i just prefer to keep my scripts within the header when possible Wink
#7

[eluser]Jumper[/eluser]
[quote author="the real rlee" date="1183972297"]i just prefer to keep my scripts within the header when possible Wink[/quote]
Even at the cost of those big and ugly handler functions?
I would make an exception if i were you, but it's a matter of taste Smile
#8

[eluser]the real rlee[/eluser]
yeah very true, the handler function does over complicate things in this case. Nevertheless a very handy function to avoid collisions with multiple onloads Tongue




Theme © iAndrew 2016 - Forum software by © MyBB