Menú horizontal al estilo Flickr o Facebook

Posted by vigosan, Fri Mar 21 19:17:00 UTC 2008

I write my own similar Facebook horizontal menu using DOM (Document Object Model). The advantage of DOM is that the menu doesn’t depend of any external library such as jQuery or Scriptaculous. You can download the code pressing here. If you found any incompatibility, please let me know.

// fMenu v1.0.2
// By Vicent Gozalbes [vigosan@gmail.com]

var imgs = [];

function init() {
  if (!document.getElementsByTagName || !document.getElementById) { return; }
  var uls = document.getElementsByTagName('ul');

  for (var u=0; u < uls.length; u++) {
    if (uls[u].className.search(/\bmenu\b/) == -1) { continue; }
    var lis = uls[u].getElementsByTagName('li')
    for (var l=0; l < lis.length; l++) {
      var spans = lis[l].getElementsByTagName('span');
      for (var s=0; s < spans.length; s++) {
        var node = spans[s];
        if(node.className == 'head_menu' && lis[l].getElementsByTagName('ul').length > 0) {
          var image = node.childNodes[1];
          addEvent(image, 'mouseover', getMoverFor(image), false);
          addEvent(image, 'mouseout', getMoutFor(image), false);
          addEvent(image, 'click', getMclickFor(image), false);
          addEvent(document, 'click', getMclickFor(document), false);
          image.topul = lis[l].getElementsByTagName('ul')[0];
          image.topul.isOpen = false;
          imgs.push(image);
        }
      }
    }
  }
}

function addEvent(elm, evType, fn, useCapture) {
  if(elm.addEventListener) {
    elm.addEventListener(evType, fn, useCapture);
    return true;
  } else if (elm.attachEvent) {
    var r = elm.attachEvent('on' + evType, fn);
    return r;
  } else {
    elm['on' + evType] = fn;
  }
}

function stopEvent(e) {
  if(!e) var e = window.event;

  //e.cancelBubble is supported by IE 
  e.cancelBubble = true;

  //e.stopPropagation works only in Firefox.
  if (e.stopPropagation) {
    e.stopPropagation();
    }
  return false;
}

function closeUls() {        
  for (var i = 0; i < imgs.length; i++) {
    imgs[i].topul.style.display = 'none';
    imgs[i].src = 'images/arrow.png';
    imgs[i].topul.isOpen = false;
  }
}

function setMover(e, targetElement) {
  var el = window.event ? targetElement : e ? e.currentTarget : null;
  if (!el) return;
  el.src = 'images/arrow_hover.png';
}

function setMout(e, targetElement) {
  var el = window.event ? targetElement : e ? e.currentTarget : null;
  if (!el) return;
  el.src = el.topul.isOpen ? 'images/arrow_select.png' : 'images/arrow.png';
}

function setMclick(e, targetElement) {
  stopEvent(e);
   var el = window.event ? targetElement : e ? e.currentTarget : null;
  if (!el) return;

  if(el.nodeName.toLowerCase() != 'img' && !el.topul) {
    closeUls();
    return;
  } else if (el.topul.isOpen) {
    el.src = 'images/arrow.png';
    el.topul.style.display = 'none';
    el.topul.isOpen = false;
  } else {
    closeUls();
    el.src = 'images/arrow_select.png';
    el.topul.style.display = 'block';
    el.topul.isOpen = true;
  }
}

function getMoverFor(node) {
  return function(e) { setMover(e, node); };
}

function getMoutFor(node) {
  return function(e) { setMout(e, node); };
}

function getMclickFor(node) {
  return function(e) { setMclick(e, node); };
}

addEvent(window, 'load', init, false);

Filed Under: Proyectos | Tags:

Comments