views:

107

answers:

1

Bit of a jquery Newbie here, so go easy.

Basically I'm trying to plug hoverIntent into this dropdown menu:

http://www.sooperthemes.com/open-source/jquery/jquery-sooperfish-dropdown-menus

I've been stuck with this for a few days now, and I know it's probably very simple, but I can't seem to find the right selector to apply the intent function onto.

Any help would be appreciated.

-- UPDATE --

I think I nearly have it, just something not quite right. I've updated the js below.

Hover intent code is at the bottom

$.fn.sooperfish = function(op) {

  var sf = $.fn.sooperfish;
  sf.o = [];
  sf.op = {};
  sf.c = {
    menuClass   : 'sf-js-enabled',
    isParent : 'sf-parent',
    arrowClass  : 'sf-arrow'
  };
  if ($.easing.easeOutOvershoot) { //set default easing
    sooperEasingShow = 'easeOutOvershoot';
  } else {
    sooperEasingShow = 'linear';
  };
  if ($.easing.easeInTurbo) {
    sooperEasingHide = 'easeInTurbo';
  } else {
    sooperEasingHide = 'linear';
  };  
  sf.defaults = {
    multiColumn  : true,
    dualColumn  : 12, //if a submenu has at least this many items it will be divided in 2 columns
    tripleColumn  : 18, //if a submenu has at least this many items it will be divided in 3 columns
    hoverClass  : 'sfHover',
    delay    : 500, //make sure menus only disappear when intended, 500ms is advised by Jacob Nielsen
    animationShow  : {height:'show',delay:'500'},
    speedShow    : 400,
    easingShow      : sooperEasingShow,
    animationHide  : {height:'hide',opacity:'hide'},
    speedHide    : 0,
    easingHide      : sooperEasingHide,
    autoArrows  : true, //Adds span elements to parent li elements, projecting arrow images on these items to indicate submenus. I added an alternative image file with white arrows.
    onShow    : function(){}, //callback after showing menu
    onHide    : function(){} //callback after hiding menu
  };


  //Merge default settings with o function parameter
  var o = $.extend({},sf.defaults,op);
  if (!o.sooperfishWidth) {
  o.sooperfishWidth = $('ul:first li:first', this).width(); //if no width is set in options try to read it from DOM
  } else {
  $('ul li', this).width(o.sooperfishWidth) //if width is set in invocation make sure this width is true for all submenus
  }

  this.each(function() {

    //Check dom for submenus
    var parentLi = $('li:has(ul)', this);
    parentLi.each(function(){
      if (o.autoArrows) { //Add autoArrows if requested
      $('>a',this).append('<span class="'+sf.c.arrowClass+'"></span>');
      }
      $(this).addClass(sf.c.isParent);
    });

    $('ul',this).css({left: 'auto',display: 'none'}); //The script needs to use display:none to make the hiding animation possible

    //Divide menu in columns
    //Set width override
    if (o.multiColumn) {
    var uls = $('ul',this);
    uls.each(function(){
      var ulsize = $('>li:not(.backLava)',this).length; //Skip list items added by Lavalamp plugin
      if (ulsize >= o.dualColumn) {
        if (ulsize >= o.tripleColumn) {
          $(this).width(3*o.sooperfishWidth).addClass('multicolumn triplecolumn');
        } else {
          $(this).width(2*o.sooperfishWidth).addClass('multicolumn dualcolumn');
        }
      }
    });
    }

    var root = this, zIndex = 1000;

    function getSubmenu(ele) {
      if (ele.nodeName.toLowerCase() == 'li') {
        var submenu = $('> ul', ele);
        return submenu.length ? submenu[0] : null;
      } else {
        return ele;
      }
    }

    function getActuator(ele) {
      if (ele.nodeName.toLowerCase() == 'ul') {
        return $(ele).parents('li')[0];
      } else {
        return ele;
      }
    }

    function hideSooperfishUl() {
      var submenu = getSubmenu(this);
      if (!submenu) return;
      $.data(submenu, 'cancelHide', false);
      setTimeout(function() {
        if (!$.data(submenu, 'cancelHide')) {
          $(submenu).animate(o.animationHide,o.speedHide,o.easingHide,function(){ o.onHide.call(submenu); });
        }
      }, o.delay);
    }

    function showSooperfishUl() {
      var submenu = getSubmenu(this);
      if (!submenu) return;
      $.data(submenu, 'cancelHide', true);
      $(submenu).css({zIndex: zIndex++}).animate(o.animationShow,o.speedShow,o.easingShow, function(){ o.onShow.call(submenu); });


      if (this.nodeName.toLowerCase() == 'ul') {
        var li = getActuator(this);
        $(li).addClass('hover');
        $('> a', li).addClass('hover');
        }
     }


    // Bind Events. Yes it's that simple!
    $('li', this).unbind().hover(showSooperfishUl, hideSooperfishUl);


    $("ul#nav li.current").hoverIntent(
        {                      
         sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)    
         interval: 200,  // number = milliseconds for onMouseOver polling interval    
         hoverIntent: showSooperfishUl,   // function = onMouseOver callback (REQUIRED)    
         timeout: 200,   // number = milliseconds delay before onMouseOut    
         out: hideSooperfishUl,    // function = onMouseOut callback (REQUIRED)  );
        })

  });

};
A: 

Remove the extra hoverIntent() call you added and, instead, replace the original Sooperfish hover() call:

$('li', this).unbind().hover(showSooperfishUl, hideSooperfishUl);

with:

$('li', this).unbind().hoverIntent({
  over: showSooperfishUl,
  timeout: 200,
  out: hideSooperfishUl,
  sensitivity: 3,
  interval: 200
});
scronide
Thanks so much, that worked perfectly.So obvious now as well!Thanks again!
misterpixel
No problem. Glad I could help.
scronide