-
-
Save joeldbirch/5371649 to your computer and use it in GitHub Desktop.
/* | |
* 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); |
solid addition.
I have found that IE10+ has a problem maintaining the position of the re-positioned nav items when used with superfish (happening up to version 1.7.5 of superfish). For example, if the child nav item would normally appear outside the browser window when its parent is hovered over and is given a negative margin left of -200px by suppostion() to correct it, it will suddenly lose the -200px margin the moment a link inside the element is clicked and not navigate to the clicked link. It moves back to it's normal position. Surprisingly, IE9 doesn't seem to have this problem.
A Live example:
http://www.wileyrein.com - try clicking on a menu item under "diversity" when you make your browser window small enough that the dropdown menu has to be re-positioned and you will see what I mean.
https://www.taylorenglish.com/ Same thing on the "careers" drop down.
i think solition for flashing problem
52 $u.css('display','none'); to //$u.css('display','none');
thanks
This works in the sense that it moves the menu, but the hovered menus that have children have to be hovered twice since it doesn't open the link on the first click.
Never mind. It was a wordpress issue. Works great!
@cemelmaci Commenting out this line $u.css('display','none');
solves the flickering issue, but it also disables any animaion on the menu.
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
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));
}
});
};
Hello Matrym, i faced the same issue, then i got the solution. here is the code with latest script i used.
jQuery('ul.sf-menu').superfish({
animation : { opacity:'show' }, /also works with 'height' etc./
onInit : jQuery.fn.supposition.onInit,
onBeforeShow : jQuery.fn.supposition.onBeforeShow,
onHide : jQuery.fn.supposition.onHide
});
hope this will help you. important to use "fn"
thanks