Closed Seefahrer closed 5 years ago
You can use the CSS solution regardless of your design.
Unfortunately that does not work ... If a assign a classname ".section" to all of my content-sections, the css:
.section {
margin-top: -80px;
padding-top: 80px;
}
causes the blue background of sections with a blue background to protude into the sections before ... Ok, bottom line, it seems that I have to live with that, because all former questions relating to that issue were answered with: do it with css ...
That would be an outer wrapper. You would declare any background colors in a wrapper inside of that one.
You have of course much more forgotten about html, php, js, css than I will ever know, but I do not get it to work with CSS... But I meanwhile understand that I never will get an answer to any question related to a JS solution ...
Sorry, I just don't have the bandwidth to support questions about custom javascript
Dear Trevor, I really understand that you cannot work free of charge on every single customer request ... sorry that I bother you again ... But please let me ask one last question: I need your script always to scroll to a position 80 px below the upper edge of the screen. Under Safari that's not a problem, but Chrome, FF, Opera etc. just scroll to that 80px position, but then jump suddenly to 0px position. It seems, that there is some function in your script that adjusts always the topPos to "0" after the "scrollTo"-function. Could you pls assist me in preventing such behaviour? Many thanks in advance ... https://www.luetten-dieks-carlito.eu
That's exactly why the CSS solution exists to offset horizontal navigations http://davist11.github.io/jQuery-One-Page-Nav/top.html
Had a similar issue, came up with this, hope it helps:
$('header .link-move a').click(function(){ $('html, body').animate({ scrollTop: $( $.attr(this, 'href') ).offset().top - 80 }); return false; });
Added the class to which one needs the offset.
Hi @zfyre123 ... yours is not really solving the issue, but the modified script attached which accepts an offset via options. The blamed behaviour of browsers like Chrome or FF can be bypassed by a statement eg:
if(self.config.changeHash) {
if(history.pushState) {
history.pushState(null, null, pathName + newLoc);
}
else {
window.location.hash = pathName + newLoc;
}
}
Then the page scrolls smoothly exactly to the desired offset.
It further more makes the script applicable for multilanguage sites because it takes care of prepending locales in the browser address bar. Pls check it on my site: https://www.luetten-dieks-carlito.eu/en/#about-me etc. May be it helps someone else with the same problems. Now I'm totally satisfied with Trevor's script!
/*
* jQuery One Page Nav Plugin
* http://github.com/davist11/jQuery-One-Page-Nav
*
* Copyright (c) 2010 Trevor Davis (http://trevordavis.net)
* Dual licensed under the MIT and GPL licenses.
* Uses the same license as jQuery, see:
* http://jquery.org/license
*
* @version 3.0.0
*
* Example usage:
* $('#nav').onePageNav({
* currentClass: 'active',
* changeHash: false,
* scrollSpeed: 1000,
* scrollOffset: 80
* });
*/
;(function($, window, document, undefined){
// our plugin constructor
var OnePageNav = function(elem, options){
this.elem = elem;
this.$elem = $(elem);
this.options = options;
this.metadata = this.$elem.data('plugin-options');
this.$win = $(window);
this.sections = {};
this.didScroll = false;
this.$doc = $(document);
this.docHeight = this.$doc.height();
};
// get the locale prefix i.e. either 'en', 'de" or else
pathName = window.location.pathname;
// the plugin prototype
OnePageNav.prototype = {
defaults: {
navItems: 'a',
currentClass: 'active',
changeHash: false,
easing: 'swing',
filter: null,
scrollSpeed: 750,
scrollOffset: 0,
scrollThreshold: 0.5,
begin: false,
end: false,
scrollChange: false
},
init: function() {
// Introduce defaults that can be extended either
// globally or using an object literal.
this.config = $.extend({}, this.defaults, this.options, this.metadata);
this.$nav = this.$elem.find(this.config.navItems);
//Filter any links out of the nav
if(this.config.filter) {
this.$nav = this.$nav.filter(this.config.filter);
}
//Handle clicks on the nav
this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this));
//Get the section positions
this.getPositions();
//Handle scroll changes
this.bindInterval();
//Update the positions on resize too
this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this));
return this;
},
adjustNav: function(self, $parent) {
self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
$parent.addClass(self.config.currentClass);
var link= $parent[0].firstElementChild.hash;
if(self.config.changeHash) {
if(history.pushState) {
history.pushState(null, null, pathName + link);
}
else {
location.hash = pathName + link;
}
}
},
bindInterval: function() {
var self = this;
var docHeight;
self.$win.on('scroll.onePageNav', function() {
self.didScroll = true;
});
self.t = setInterval(function() {
docHeight = self.$doc.height();
//If it was scrolled
if(self.didScroll) {
self.didScroll = false;
self.scrollChange();
}
//If the document height changes
if(docHeight !== self.docHeight) {
self.docHeight = docHeight;
self.getPositions();
}
}, 250);
},
getHash: function($link) {
return $link.attr('href') ? $link.attr('href').split('#')[1] : '';
},
getPositions: function() {
var self = this;
var linkHref;
var topPos;
var $target;
self.$nav.each(function() {
linkHref = self.getHash($(this));
$target = linkHref ? $('#' + linkHref) : '';;
if($target.length) {
topPos = $target.offset().top;
self.sections[linkHref] = Math.round(topPos) - self.config.scrollOffset;
}
});
},
getSection: function(windowPos) {
var returnValue = null;
var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold);
for(var section in this.sections) {
if((this.sections[section] - windowHeight) < windowPos) {
returnValue = section;
}
}
return returnValue;
},
handleClick: function(e) {
var self = this;
var $link = $(e.currentTarget);
var $parent = $link.parent();
var hash = self.getHash($link);
var newLoc = '#' + hash;
if (!hash || self.isExternalLink($link) || $(newLoc).length === 0) {
return;
}
if(!$parent.hasClass(self.config.currentClass)) {
//Start callback
if(self.config.begin) {
self.config.begin();
}
//Change the highlighted nav item
self.adjustNav(self, $parent);
//Removing the auto-adjust on scroll
self.unbindInterval();
//Scroll to the correct position
self.scrollTo(newLoc, function() {
//Do we need to change the hash?
if(self.config.changeHash) {
if(history.pushState) {
history.pushState(null, null, pathName + newLoc);
}
else {
window.location.hash = pathName + newLoc;
}
}
//Add the auto-adjust on scroll back in
self.bindInterval();
//End callback
if(self.config.end) {
self.config.end();
}
});
}
e.preventDefault();
},
scrollChange: function() {
var windowTop = this.$win.scrollTop();
var position = this.getSection(windowTop);
var $parent;
//If the position is set
if(position !== null) {
$parent = this.$elem.find('a[href$="#' + position + '"]').parent();
//If it's not already the current section
if(!$parent.hasClass(this.config.currentClass)) {
//Change the highlighted nav item
this.adjustNav(this, $parent);
//If there is a scrollChange callback
if(this.config.scrollChange) {
this.config.scrollChange($parent);
}
}
}
},
scrollTo: function(target, callback) {
var offset = $(target).offset().top - this.config.scrollOffset;
$('html, body').animate({scrollTop: offset}, this.config.scrollSpeed, this.config.easing, callback);
},
unbindInterval: function() {
clearInterval(this.t);
this.$win.unbind('scroll.onePageNav');
},
isExternalLink: function($link) {
return window.location.host !== $link.get(0).host;
}
};
OnePageNav.defaults = OnePageNav.prototype.defaults;
$.fn.onePageNav = function(options) {
return this.each(function() {
new OnePageNav(this, options).init();
});
};
})( jQuery, window , document );
Hi, first of all I'm a real fan of your "onepagenav" plugin and I'm using it on my website: https://www.luetten-dieks-carlito.eu ... in conjunction with the "Contao 4.7.x" CMS.
Due to the layout of my site with alternating backgrounds, I cannot use your favoured CSS solution for an offset of the content section to navigate to. So, I tried to revoke your JS offset withdrawel by modifying yr script to:
Your script is loaded and initialized as a Contao-Template with fllwg declaration:
The modified version works so far as expected on Mac/Safari, on e.g. Firefox, Chrome, Opera I notice some strange behaviour: The script first scrolls as it should to the offset of the section to navigate to, but then jumps to Top-Position ... i.e. as if I'd given the offset=0 ... Do you have an explanation or workaraound for that?
As I'm using the "headroom.js" navigation, I furthermore would like to change the offset value dynamically depending on the scroll-direction, i.e. 80px for "up" ($("header-bar".height())because the header-bar will slide in, and "0" for "down" because the header-bar will disappear. This would be easy to accomplish with CSS but, as aforesaid, this approach will not work ...
Btw: Your "IOS-Hack" ist also necessary and does work in MacOS Mojave ...