Skip to content

Instantly share code, notes, and snippets.

@annelyse
Last active July 31, 2023 17:48
Show Gist options
  • Save annelyse/cfd7118f961856431bf8fabb2c23298d to your computer and use it in GitHub Desktop.
Save annelyse/cfd7118f961856431bf8fabb2c23298d to your computer and use it in GitHub Desktop.
export class stickyScrollElement {
/**
* Constructs a new sticky instance.
*
* @param stickyItem Element parent contenant le sticky
* @param limiteWrapper container dans lequel le sticky doit se déplacer
* @param stickyNav Navigation sticky qui faudrait enlever des calculs
*/
constructor(
stickyItem,
limiteWrapper,
stickyNav = false,
breakpoint = false,
margeSticky = 0
) {
this.selector = stickyItem;
this.limiteWrapper = limiteWrapper;
this.stickyNav = stickyNav;
this.breakpoint = breakpoint;
this.margeSticky = margeSticky;
this.limitInfos = false;
this.isMobile = false;
this.stickyHeight = 0;
this.stickyOffsetTop = 0;
if (document.readyState !== "loading") {
this.init();
}
}
/**
* Find elements
* Ajouter dans votre sélecteur, un element avec la class en sticky
* @return {void}
*/
findElements() {
this.el = document.querySelector(this.selector);
if (this.el == null) {
throw new Error("stickyItem n'a pas été trouvé");
}
if (this.stickyNav) {
this.stickyNav = document.querySelector(this.stickyNav);
}
// marge pour que l'élément ne soit pas collé au dessus
if (this.stickyNav) {
this.margeSticky = this.stickyNav.offsetHeight + this.margeSticky;
}
this.limitWrapper = document.querySelector(this.limiteWrapper);
if (this.el == null) {
throw new Error("limitWrapper n'a pas été trouvé");
}
}
/**
* Init functions
* @return {void}
*/
init() {
console.log("init");
this.findElements();
this.placeElement();
this.stickElement();
this.attachListeners();
}
/**
* Delete instance and remove styles
* @return {void}
*/
delete() {
// console.log('delete style sticky ');
this.el.removeAttribute("style");
console.log(this.el);
}
/**
* Attach listeners
* @return {void}
*/
attachListeners() {
window.addEventListener(
"resize",
function () {
this.resizeWidth();
}.bind(this)
);
window.addEventListener(
"scroll",
function () {
console.log("scroll");
this.stickElement();
}.bind(this)
);
}
/**
* On resize page
* @return {void}
*/
resizeWidth() {
this.width = window.innerWidth;
if (this.width < this.breakpoint) {
this.isMobile = true;
this.delete();
} else {
this.isMobile = false;
}
}
placeElement() {
const stickyItem = this.el;
if (stickyItem != null) {
this.stickyHeight = stickyItem.offsetHeight;
this.stickyOffsetTop =
stickyItem.getBoundingClientRect().top +
document.documentElement.scrollTop;
stickyItem.style.height = stickyItem.offsetHeight + "px";
stickyItem.style.width = stickyItem.offsetWidth + "px";
this.limitWrapper.style.position = "relative";
}
}
stickElement() {
if (!this.isMobile) {
const limitInfos = this.limitWrapper.getBoundingClientRect();
if (limitInfos.bottom - this.margeSticky - this.stickyHeight <= 0) {
// element arrivé en bas de son container
// console.log("absolute");
this.el.style.position = "absolute";
this.el.style.bottom = 0 + "px";
this.el.style.top = "inherit";
// stickyItem.style.left = 0 + 'px';
} else if (window.scrollY > this.stickyOffsetTop - this.margeSticky) {
// element en sticky
// console.log("sticky");
this.el.style.position = "fixed";
this.el.style.top = this.margeSticky + "px";
this.el.style.bottom = "inherit";
} else {
// element en haut de son container (position initial )
// console.log("initial");
this.el.style.position = "relative";
this.el.style.top = "inherit";
this.el.style.bottom = "inherit";
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment