SZMUNC/themes/tstyle/source/js/jquery.smint.js

199 lines
5.4 KiB
JavaScript
Raw Normal View History

2020-08-31 16:38:50 +00:00
/*
SMINT V1.0 by Robert McCracken
SMINT V2.0 by robert McCracken with some awesome help from Ryan Clarke (@clarkieryan) and mcpacosy (@mcpacosy)
SMINT V3.0 by robert McCracken with some awesome help from Ryan Clarke (@clarkieryan) and mcpacosy (@mcpacosy)
SMINT is my first dabble into jQuery plugins!
http://www.outyear.co.uk/smint/
If you like Smint, or have suggestions on how it could be improved, send me a tweet @rabmyself
*/
(function(){
$.fn.smint = function( options ) {
var settings = $.extend({
'scrollSpeed' : 500,
'mySelector' : 'div'
}, options);
// adding a class to users div
$(this).addClass('smint');
//Set the variables needed
var optionLocs = new Array(),
lastScrollTop = 0,
menuHeight = $(".smint").height(),
smint = $('.smint'),
smintA = $('.smint a'),
myOffset = smint.height();
if ( settings.scrollSpeed ) {
var scrollSpeed = settings.scrollSpeed
}
if ( settings.mySelector ) {
var mySelector = settings.mySelector
};
return smintA.each( function(index) {
var id = $(this).attr('href').split('#')[1];
if (!$(this).hasClass("extLink")) {
$(this).attr('id', id);
}
//Fill the menu
optionLocs.push(Array(
$(mySelector+"."+id).position().top-menuHeight,
$(mySelector+"."+id).height()+$(mySelector+"."+id).position().top, id)
);
///////////////////////////////////
// get initial top offset for the menu
var stickyTop = smint.offset().top;
// check position and make sticky if needed
var stickyMenu = function(direction){
// current distance top
var scrollTop = $(window).scrollTop()+myOffset;
// if we scroll more than the navigation, change its position to fixed and add class 'fxd', otherwise change it back to absolute and remove the class
if (scrollTop > stickyTop+myOffset) {
smint.css({ 'position': 'fixed', 'top':0,'left':0 }).addClass('fxd');
// add padding to the body to make up for the loss in heigt when the menu goes to a fixed position.
// When an item is fixed, its removed from the flow so its height doesnt impact the other items on the page
$('body').css('padding-top', menuHeight );
} else {
smint.css( 'position', 'relative').removeClass('fxd');
//remove the padding we added.
$('body').css('padding-top', '0' );
}
// Check if the position is inside then change the menu
// Courtesy of Ryan Clarke (@clarkieryan)
if(optionLocs[index][0] <= scrollTop && scrollTop <= optionLocs[index][1]){
if(direction == "up"){
$("#"+id).addClass("active");
$("#"+optionLocs[index+1][2]).removeClass("active");
} else if(index > 0) {
$("#"+id).addClass("active");
$("#"+optionLocs[index-1][2]).removeClass("active");
} else if(direction == undefined){
$("#"+id).addClass("active");
}
$.each(optionLocs, function(i){
if(id != optionLocs[i][2]){
$("#"+optionLocs[i][2]).removeClass("active");
}
});
}
};
// run functions
stickyMenu();
// run function every time you scroll
$(window).scroll(function() {
//Get the direction of scroll
var st = $(this).scrollTop()+myOffset;
if (st > lastScrollTop) {
direction = "down";
} else if (st < lastScrollTop ){
direction = "up";
}
lastScrollTop = st;
stickyMenu(direction);
// Check if at bottom of page, if so, add class to last <a> as sometimes the last div
// isnt long enough to scroll to the top of the page and trigger the active state.
if($(window).scrollTop() + $(window).height() == $(document).height()) {
smintA.removeClass('active')
$(".smint a:not('.extLink'):last").addClass('active')
} else {
smintA.last().removeClass('active')
}
});
///////////////////////////////////////
$(this).on('click', function(e){
// gets the height of the users div. This is used for off-setting the scroll so the menu doesnt overlap any content in the div they jst scrolled to
var myOffset = smint.height();
// stops hrefs making the page jump when clicked
e.preventDefault();
// get the hash of the button you just clicked
var hash = $(this).attr('href').split('#')[1];
var goTo = $(mySelector+'.'+ hash).offset().top-myOffset;
// Scroll the page to the desired position!
$("html, body").stop().animate({ scrollTop: goTo }, scrollSpeed);
// if the link has the '.extLink' class it will be ignored
// Courtesy of mcpacosy (@mcpacosy)
if ($(this).hasClass("extLink"))
{
return false;
}
});
//This lets yo use links in body text to scroll. Just add the class 'intLink' to your button and it will scroll
$('.intLink').on('click', function(e){
var myOffset = smint.height();
e.preventDefault();
var hash = $(this).attr('href').split('#')[1];
if (smint.hasClass('fxd')) {
var goTo = $(mySelector+'.'+ hash).position().top-myOffset;
} else {
var goTo = $(mySelector+'.'+ hash).position().top-myOffset*2;
}
$("html, body").stop().animate({ scrollTop: goTo }, scrollSpeed);
if ($(this).hasClass("extLink"))
{
return false;
}
});
});
};
$.fn.smint.defaults = { 'scrollSpeed': 500, 'mySelector': 'div'};
})(jQuery);