0

I am trying to achieve something like this example.

This single page website keeps current view while resizing. For example, if I am reading the section : #p_partnerships while resizing browser window it will still show the content of #p_partnerships.

I have modified some single page bootstrap template.

It works like a charm, but when I am resizing it, it does behave like any other scrollable page. I mean to get back to the section that was visible before resizing I have to click on some link and then on that section's link again. I don't care about mouse scroll effect from myprovence all I need is to keep the top of currently viewed section right below the navigation bar.

Here is some bits and pieces of what I've got:

In addition to jQuery ScrollTo, my template uses jQuery One Page Nav Plugin

;(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.$nav = this.$elem.find('a');
this.$win = $(window);
this.sections = {};
this.didScroll = false;
this.$doc = $(document);
this.docHeight = this.$doc.height();
};

// the plugin prototype
OnePageNav.prototype = {
defaults: {
currentClass: 'current',
changeHash: false,
easing: 'swing',
filter: '',
scrollSpeed: 750,
scrollOffset: 0,
scrollThreshold: 0.5,
begin: false,
end: false,
scrollChange: false
},

init: function() {
var self = this;

// Introduce defaults that can be extended either
// globally or using an object literal.
self.config = $.extend({}, self.defaults, self.options, self.metadata);

//Filter any links out of the nav
if(self.config.filter !== '') {
self.$nav = self.$nav.filter(self.config.filter);
}

//Handle clicks on the nav
self.$nav.on('click.onePageNav', $.proxy(self.handleClick, self));

//Get the section positions
self.getPositions();

//Handle scroll changes
self.bindInterval();

//Update the positions on resize too
self.$win.on('resize.onePageNav', $.proxy(self.getPositions, self));

eturn this;
},
adjustNav: function(self, $parent) {
self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
$parent.addClass(self.config.currentClass);
},

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').split('#')[1];
},

getPositions: function() {
var self = this;
var linkHref;
var topPos;
var $target;

self.$nav.each(function() {
linkHref = self.getHash($(this));
$target = $('#' + 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 newLoc = '#' + self.getHash($link);

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
$.scrollTo(newLoc, self.config.scrollSpeed, {
axis: 'y',
easing: self.config.easing,
offset: {
top: -self.config.scrollOffset
},
onAfter: function() {
//Do we need to change the hash?
if(self.config.changeHash) {
window.location.hash = 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);
}
}
}
},

unbindInterval: function() {
clearInterval(this.t);
this.$win.unbind('scroll.onePageNav');
}
};

OnePageNav.defaults = OnePageNav.prototype.defaults;


$.fn.onePageNav = function(options) {

return this.each(function() {
new OnePageNav(this, options).init();
});
};

})( jQuery, window , document );

In html document I have this bit:

<script>
$('#top-nav').onePageNav({
currentClass: 'active',
changeHash: true,
scrollSpeed: 1200
});

</script>

I've tried a piece of code suggested by Alexander but it does not work for me.

the first part:

<script>
function goToByScroll(id){
$('html, body').stop().animate({scrollTop: $(id).offset().top}, 2000);
}
</script>

does work with links like this

<a href="#" onClick="goToByScroll('#section-2')">

But this is the same thing that I already have.

I have experimented with something like this

$(window).on("resize", function () {
goToByScroll('#section-2')

It does scroll to top of the #section-two every time I resize the browser.

Need some solution to scroll to currently viewed section and not always to the same #section-2

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
user2820547
  • 1
  • 1
  • 3

1 Answers1

0

You need two things to make this work: A function that scrolls to a div, and a listener to know when someone has scrolled.

First, a jQuery function that can scroll to your divs. You can use something similar to this:

function goToByScroll(id){
  $('html, body').stop().animate({scrollTop: $(id).offset().top}, 2000);
}

See Jquery - scroll to div, or search Stackoverflow for more information. And then you need to know when you're scrolling. You can use jQuery for this, and then call the function goToByScroll()

var lastScrollTop = 0;
$(window).scroll(function(event){
  var st = $(this).scrollTop();
  if (st > lastScrollTop){
    // downscroll code
    goToByScroll(next_page_id);
  } else {
    // upscroll code
    goToByScroll(last_page_id);
  }
  lastScrollTop = st;
});

See How can I determine the direction of a jQuery scroll event? That should be enough to get you a good start. You'd just have to keep track of what page you're on, and what page is next if you scroll up or down.

Community
  • 1
  • 1
Alexander Mistakidis
  • 3,130
  • 2
  • 20
  • 23