jquerysuperfish

Superfish Menu - Display subitems left if there is not enough screenspace on the right


I have 3 level menu. I want the sub menus to be open in left direction instead of right when there is not enough screenspace to show them.

Please take a look at the screenshot to get the exact idea.

enter image description here

I want to use the onBeforeShow() function of superfish menu to fix this, but I am not able to make it work as desired.

Here's my code so far:

$("ul.sf-menu").superfish({
    delay: 1000,
    speed: 'fast',
    disableHI: true,
    onBeforeShow: function()
    {
      thisWidth = $(this).width();
      if  ( thisWidth > 0 ) 
      {
        thisParent = this.parent();
        parentLeft = thisParent.offset().left;
        parentWidth = this.parent().width();
        parentRight = parentWidth + parentLeft ;

        mainLeft =  document
          .getElementsByClassName('sf-menu')[0].offsetLeft;

        mainRight = document
          .getElementsByClassName('sf-menu')[0].offsetWidth;

        if  ( ( thisWidth + parentLeft ) < ( mainLeft + mainRight ) )   
        {
          if  ( thisWidth > ( parentLeft + parentHeight ) ) 
          {
            $(this).css('left', - (parentLeft - mainLeft));
          } 
          else 
          {
            // open left
            $(this).css('left', - (thisWidth - parentWidth));
          }
        }
      }
    }
});

Solution

  • I am currently using this code to solve the problem on a site I work on:

    onBeforeShow: function() {
       if($(this).parents("ul").length > 1){
          var w = $(window).width();  
          var ul_offset = $(this).parents("ul").offset();
          var ul_width = $(this).parents("ul").outerWidth();
    
          // Shouldn't be necessary, but just doing the straight math
          // on dimensions can still allow the menu to float off screen
          // by a little bit.
          ul_width = ul_width + 50;
    
          if((ul_offset.left+ul_width > w-(ul_width/2)) && (ul_offset.left-ul_width > 0)) {
             $(this).addClass('too_narrow_fix');
          }
          else {
             $(this).removeClass('too_narrow_fix');
          }
       };
    }
    

    Here's the CSS it applies:

    .too_narrow_fix {
       left: -14.5em !important;
       top: .5em  !important;
    }