Skip to content

Instantly share code, notes, and snippets.

@Mandorlo
Created March 4, 2020 07:35
Show Gist options
  • Save Mandorlo/a37e45d6c0f84f4f3dfa570aa84eac0a to your computer and use it in GitHub Desktop.
Save Mandorlo/a37e45d6c0f84f4f3dfa570aa84eac0a to your computer and use it in GitHub Desktop.
nice utility to amange scroll in a web page
/**
* This module allows to execute certain actions during scroll
* when a certain trigger is triggered
*
*/
function init_scroll(opt) {
let opt_default = {
scroll_container: 'html, body', // the element in which we want to scroll
triggers: {
"arrived_at_section": {
type: "section",
selector: ".section",
top_offset: 0
},
},
}
opt = Object.assign(opt_default, opt);
if (opt.scroll_container == 'window') opt.scroll_container = window;
let $ = jQuery;
let scrolling = false;
let events = {}
// load section triggers
let section_triggers = [];
for (let event_name in opt.triggers) {
if (opt.triggers[event_name].type != 'section') continue;
$(opt.triggers[event_name].selector).each(function() {
console.log('got section', $(this).text())
section_triggers.push({
event: event_name,
top: $(this).offset().top - opt.triggers[event_name].top_offset,
height: $(this).height(),
})
})
}
for (let i = 0; i < section_triggers.length-1; i++) {
section_triggers[i].height = section_triggers[i+1].top - section_triggers[i].top;
}
section_triggers[section_triggers.length-1].height = $(document).height() - section_triggers[section_triggers.length-1].top;
// respond to on scroll event to change section
let curr_section = {};
let w_height = $(window).height();
let marge = w_height / 10;
$(opt.scroll_container).scroll(function() {
if (scrolling) return;
let start = $(this).scrollTop();
let i = 0
for (let section of section_triggers) {
let mem_section = curr_section[section];
if (start > section.top - marge && start < section.top + section.height - marge && curr_section != i) {
curr_section[section] = i
}
if (mem_section != curr_section[section]) {
dispatch_event(section.event, [curr_section[section], section])
}
i++
}
})
function register_event(ev_name, fn) {
if (ev_name in events) events[ev_name].push(fn);
else events[ev_name] = [fn];
}
function dispatch_event(ev_name, args) {
if (!events[ev_name]) return;
for (let fn of events[ev_name]) {
fn(...args);
}
}
return {
on: register_event,
getScrolling: _ => scrolling,
setScrolling: v => scrolling = v && true,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment