Skip to content

Commit

Permalink
Moves scrollOverflow code to separate handler object
Browse files Browse the repository at this point in the history
This update adds a new option called 'scrollOverflowHandler'
which consolidates all code related to scrollOverflow and
allows it to be swapped out with different functionality.

By default, it will use the existing jquery.slimScroll handling
of scroll overflow.

This should make it easier for users to either customize the
slimScroll handling or replace it with other code just as wrapping
content in a div with `overflow: scroll` or utilizing iscroll.js
as requested in issues alvarotrigo#506, alvarotrigo#612 and others.
  • Loading branch information
rmarscher committed Sep 9, 2015
1 parent bd0a18f commit f230294
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 63 deletions.
35 changes: 35 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true


[*]
# We recommend you to keep these unchanged
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

indent_style = space
indent_size = 4

[**.js]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true

[**.css]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true

[**.md]
indent_style = space
indent_size = 4
trim_trailing_whitespace = false
insert_final_newline = true

205 changes: 142 additions & 63 deletions jquery.fullPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@
var afterSectionLoadsId;
var afterSlideLoadsId;

var defaultScrollHandler;

$.fn.fullpage = function(options) {

// common jQuery objects
Expand Down Expand Up @@ -123,6 +125,7 @@
continuousVertical: false,
normalScrollElements: null,
scrollOverflow: false,
scrollOverflowHandler: defaultScrollHandler,
touchSensitivity: 5,
normalScrollElementTouchThreshold: 5,

Expand Down Expand Up @@ -781,7 +784,9 @@
function afterRenderActions(){
var section = $(SECTION_ACTIVE_SEL);

solveBugSlimScroll(section);
if(options.scrollOverflowHandler.afterRender){
options.scrollOverflowHandler.afterRender(section);
}
lazyLoad(section);
playMedia(section);

Expand All @@ -790,21 +795,6 @@
}


/**
* Solves a bug with slimScroll vendor library #1037, #553
*/
function solveBugSlimScroll(section){
var slides = section.find('SLIDES_WRAPPER');
var scrollableWrap = section.find(SCROLLABLE_SEL);

if(slides.length){
scrollableWrap = slides.find(SLIDE_ACTIVE_SEL);
}

scrollableWrap.mouseover();
}


var isScrolling = false;

//when scrolling...
Expand Down Expand Up @@ -902,19 +892,6 @@
}
}


/**
* Determines whether the active section or slide is scrollable through and scrolling bar
*/
function isScrollable(activeSection){
//if there are landscape slides, we check if the scrolling bar is in the current one or not
if(activeSection.find(SLIDES_WRAPPER_SEL).length){
return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL);
}

return activeSection.find(SCROLLABLE_SEL);
}

/**
* Determines the way of scrolling up or down:
* by 'automatically' scrolling a section or by using the default and normal scrolling.
Expand All @@ -935,7 +912,7 @@

if(scrollable.length > 0 ){
//is the scrollbar at the start/end of the scroll?
if(isScrolled(check, scrollable)){
if(options.scrollOverflowHandler.isScrolled(check, scrollable)){
scrollSection();
}else{
return true;
Expand Down Expand Up @@ -970,7 +947,7 @@
}

var activeSection = $(SECTION_ACTIVE_SEL);
var scrollable = isScrollable(activeSection);
var scrollable = options.scrollOverflowHandler.scrollable(activeSection);

if (canScroll && !slideMoving) { //if theres any #
var touchEvents = getEventsPage(e);
Expand Down Expand Up @@ -1108,7 +1085,7 @@
}

var activeSection = $(SECTION_ACTIVE_SEL);
var scrollable = isScrollable(activeSection);
var scrollable = options.scrollOverflowHandler.scrollable(activeSection);

//time difference between the last scroll and the current one
var timeDiff = curTime-prevTime;
Expand Down Expand Up @@ -1884,17 +1861,6 @@
}

/**
* Return a boolean depending on whether the scrollable element is at the end or at the start of the scrolling
* depending on the given type.
*/
function isScrolled(type, scrollable){
if(type === 'top'){
return !scrollable.scrollTop();
}else if(type === 'bottom'){
return scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight;
}
}

/**
* Retuns `up` or `down` depending on the scrolling movement to reach its destination
* from the current section.
Expand Down Expand Up @@ -1930,14 +1896,16 @@
//needed to make `scrollHeight` work under Opera 12
element.css('overflow', 'hidden');

var scrollOverflowHandler = options.scrollOverflowHandler;
var wrap = scrollOverflowHandler.wrapContent();
//in case element is a slide
var section = element.closest(SECTION_SEL);
var scrollable = element.find(SCROLLABLE_SEL);
var scrollable = scrollOverflowHandler.scrollable(element);
var contentHeight;

//if there was scroll, the contentHeight will be the one in the scrollable section
if(scrollable.length){
contentHeight = scrollable.get(0).scrollHeight;
contentHeight = scrollOverflowHandler.scrollHeight(element);
}else{
contentHeight = element.get(0).scrollHeight;
if(options.verticalCentered){
Expand All @@ -1951,40 +1919,27 @@
if ( contentHeight > scrollHeight) {
//was there already an scroll ? Updating it
if(scrollable.length){
scrollable.css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
scrollOverflowHandler.update(element, scrollHeight);
}
//creating the scrolling
else{
if(options.verticalCentered){
element.find(TABLE_CELL_SEL).wrapInner('<div class="' + SCROLLABLE + '" />');
element.find(TABLE_CELL_SEL).wrapInner(wrap);
}else{
element.wrapInner('<div class="' + SCROLLABLE + '" />');
element.wrapInner(wrap);
}

element.find(SCROLLABLE_SEL).slimScroll({
allowPageScroll: true,
height: scrollHeight + 'px',
size: '10px',
alwaysVisible: true
});
scrollOverflowHandler.create(element, scrollHeight);
}
}

//removing the scrolling when it is not necessary anymore
else{
removeSlimScroll(element);
scrollOverflowHandler.remove(element);
}

//undo
element.css('overflow', '');
}

function removeSlimScroll(element){
element.find(SCROLLABLE_SEL).children().first().unwrap().unwrap();
element.find(SLIMSCROLL_BAR_SEL).remove();
element.find(SLIMSCROLL_RAIL_SEL).remove();
}

function addTableClass(element){
element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />');
}
Expand Down Expand Up @@ -2550,4 +2505,128 @@
console && console[type] && console[type]('fullPage: ' + text);
}
};

/**
* An object to handle overflow scrolling.
* This uses jquery.slimScroll to accomplish overflow scrolling.
* It is possible to pass in an alternate scrollOverflowHandler
* to the fullpage.js option that implements the same functions
* as this handler.
*
* @type {Object}
*/
var slimScrollHandler = {
/**
* Optional function called after each render.
*
* Solves a bug with slimScroll vendor library #1037, #553
*
* @param {object} section jQuery object containing rendered section
*/
afterRender: function(section){
var slides = section.find('SLIDES_WRAPPER');
var scrollableWrap = section.find(SCROLLABLE_SEL);

if(slides.length){
scrollableWrap = slides.find(SLIDE_ACTIVE_SEL);
}

scrollableWrap.mouseover();
},

/**
* Called when overflow scrolling is needed for a section.
*
* @param {Object} element jQuery object containing current section
* @param {Number} scrollHeight Current window height in pixels
*/
create: function(element, scrollHeight){
element.find(SCROLLABLE_SEL).slimScroll({
allowPageScroll: true,
height: scrollHeight + 'px',
size: '10px',
alwaysVisible: true
});
},

/**
* Return a boolean depending on whether the scrollable element is a
* the end or at the start of the scrolling depending on the given type.
*
* @param {String} type Either 'top' or 'bottom'
* @param {Object} scrollable jQuery object for the scrollable element
* @return {Boolean}
*/
isScrolled: function(type, scrollable){
if(type === 'top'){
return !scrollable.scrollTop();
}else if(type === 'bottom'){
return scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight;
}
},

/**
* Returns the scrollable element for the given section.
* If there are landscape slides, will only return a scrollable element
* if it is in the active slide.
*
* @param {Object} activeSection jQuery object containing current section
* @return {Boolean}
*/
scrollable: function(activeSection){
// if there are landscape slides, we check if the scrolling bar is in the current one or not
if(activeSection.find(SLIDES_WRAPPER_SEL).length){
return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL);
}
return activeSection.find(SCROLLABLE_SEL);
},

/**
* Returns the scroll height of the wrapped content.
* If this is larger than the window height minus section padding,
* overflow scrolling is needed.
*
* @param {Object} element jQuery object containing current section
* @return {Number}
*/
scrollHeight: function(element){
return element.find(SCROLLABLE_SEL).get(0).scrollHeight;
},

/**
* Called when overflow scrolling is no longer needed for a section.
*
* @param {Object} element jQuery object containing current section
*/
remove: function(element){
element.find(SCROLLABLE_SEL).children().first().unwrap().unwrap();
element.find(SLIMSCROLL_BAR_SEL).remove();
element.find(SLIMSCROLL_RAIL_SEL).remove();
},

/**
* Called when overflow scrolling has already been setup but the
* window height has potentially changed.
*
* @param {Object} element jQuery object containing current section
* @param {Number} scrollHeight Current window height in pixels
*/
update: function(element, scrollHeight){
element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
},

/**
* Called to get any additional elements needed to wrap the section
* content in order to facilitate overflow scrolling.
*
* @return {String|Object} Can be a string containing HTML,
* a DOM element, or jQuery object.
*/
wrapContent: function(){
return '<div class="' + SCROLLABLE + '"></div>';
}
};

defaultScrollHandler = slimScrollHandler;

});

0 comments on commit f230294

Please sign in to comment.