Skip to content

Instantly share code, notes, and snippets.

@joeldbirch
Created April 12, 2013 12:22
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save joeldbirch/5371649 to your computer and use it in GitHub Desktop.
Save joeldbirch/5371649 to your computer and use it in GitHub Desktop.
Updated version of Supposition. This version is compatible with Superfish 1.6+. See this ancient page for description, example and caveats: http://users.tpg.com.au/j_birch/plugins/superfish/supposition-test/
/*
* Supposition v0.3a - an optional enhancer for Superfish jQuery menu widget
*
* Copyright (c) 2013 Joel Birch - based on work by Jesse Klaasse - credit goes largely to him.
* Special thanks to Karl Swedberg for valuable input.
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
;(function($){
$.fn.supposition = function(){
var $w = $(window), /*do this once instead of every onBeforeShow call*/
_offset = function(dir) {
return window[dir == 'y' ? 'pageYOffset' : 'pageXOffset']
|| document.documentElement && document.documentElement[dir=='y' ? 'scrollTop' : 'scrollLeft']
|| document.body[dir=='y' ? 'scrollTop' : 'scrollLeft'];
},
onInit = function(){
/* I haven't touched this bit - needs work as there are still z-index issues */
$topNav = $('li',this);
var cZ=parseInt($topNav.css('z-index')) + $topNav.length;
$topNav.each(function() {
$(this).css({zIndex:--cZ});
});
},
onHide = function(){
this.css({marginTop:'',marginLeft:''});
},
onBeforeShow = function(){
this.each(function(){
var $u = $(this);
$u.css('display','block');
var menuWidth = $u.width(),
parentWidth = $u.parents('ul').width(),
totalRight = $w.width() + _offset('x'),
menuRight = $u.offset().left + menuWidth;
if (menuRight > totalRight) {
$u.css('margin-left', ($u.parents('ul').length == 1 ? totalRight - menuRight : -(menuWidth + parentWidth)) + 'px');
}
var windowHeight = $w.height(),
offsetTop = $u.offset().top,
menuHeight = $u.height(),
baseline = windowHeight + _offset('y');
var expandUp = (offsetTop + menuHeight > baseline);
if (expandUp) {
$u.css('margin-top',baseline - (menuHeight + offsetTop));
}
$u.css('display','none');
});
};
return this.each(function() {
var $this = $(this),
o = $this.data('sf-options'); /* get this menu's options */
/* if callbacks already set, store them */
var _onInit = o.onInit,
_onBeforeShow = o.onBeforeShow,
_onHide = o.onHide;
$.extend($this.data('sf-options'),{
onInit: function() {
onInit.call(this); /* fire our Supposition callback */
_onInit.call(this); /* fire stored callbacks */
},
onBeforeShow: function() {
onBeforeShow.call(this); /* fire our Supposition callback */
_onBeforeShow.call(this); /* fire stored callbacks */
},
onHide: function() {
onHide.call(this); /* fire our Supposition callback */
_onHide.call(this); /* fire stored callbacks */
}
});
});
};
})(jQuery);
@carasmo
Copy link

carasmo commented Nov 25, 2015

Never mind. It was a wordpress issue. Works great!

@imfaisalkh
Copy link

@cemelmaci Commenting out this line $u.css('display','none'); solves the flickering issue, but it also disables any animaion on the menu.

@moorthidaniel
Copy link

this plugin helped me to display sub menu items in the left side, if there is not enough screen space on the right
check out this post https://stackoverflow.com/a/47286812/202503

@namkazt
Copy link

namkazt commented Jan 16, 2020

for anyone that have issue with flashing and animation, replace onBeforeShow this only check for sub-menu and no need to set display to block to check.

onBeforeShow = function () {
                this.each(function () {
                    var $u = $(this);
                    var menuWidth = $u.width(),
                        parentWidth = $u.parents('ul').width(),
                        totalRight = $w.width() + _offset('x'),
                        menuRight = $u.offset().left + menuWidth;
                    if ($u.parents('li').hasClass('menu-has-children')) {
                        menuRight = $u.parents('ul').offset().left + menuWidth + $u.parents('ul').width()
                    }
                    if (menuRight > totalRight) {
                        $u.css('margin-left', ($u.parents('ul').length == 1 ? totalRight - menuRight : -(menuWidth + parentWidth)) + 'px');
                    }

                    var windowHeight = $w.height(),
                        offsetTop = $u.offset().top,
                        menuHeight = $u.height(),
                        baseline = windowHeight + _offset('y');
                    var expandUp = (offsetTop + menuHeight > baseline);
                    if (expandUp) {
                        $u.css('margin-top', baseline - (menuHeight + offsetTop));
                    }
                });
            };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment