To scroll to a given selector i have used two approaches but i don’t know which one is better .
// app/modifiers/scroll-to.js
import Modifier from 'ember-modifier';
import { registerDestructor } from '@ember/destroyable';
function cleanup(instance) {
let { element, event, handler } = instance;
if (element && event && handler) {
element.removeEventListener(event, handler);
instance.element = null;
instance.event = null;
instance.handler = null;
}
}
export default class scrollToModifier extends Modifier {
element = null;
event = null;
handler = null;
modify(element, [event, selector, yOffset]) {
this.addEventListener(element, event, selector, yOffset);
registerDestructor(this, cleanup);
}
scrollTo(element, selector, yOffset) {
let doc = element.getRootNode();
const el = doc.querySelector(selector);
// const y = el.getBoundingClientRect().top + window.pageYOffset -parseInt(yOffset);
// window.scrollTo({ top: y, behavior: 'smooth' });
el.style.scrollMargin = `${parseInt(yOffset)}px`;
el.scrollIntoView(true);
}
addEventListener = (element, event, selector, yOffset) => {
this.element = element;
this.event = event;
this.handler = this.scrollTo;
element.addEventListener(event, () => {
this.handler(element, selector, yOffset);
});
};
}
The second one using a modifier inside a component which i find more easy to use , but i am not sure which one is better in term of performance .
// app/components/link-to-scroll.js
import Component from '@glimmer/component';
import { modifier } from 'ember-modifier';
import { action } from '@ember/object';
export default class LinkToScrollComponent extends Component {
// TODO: check Passive touch listener scroll
scrollToModifier = modifier((element, [args]) => {
let doc = element.getRootNode();
const el = doc.querySelector(args.selector);
const y = el.getBoundingClientRect().top + window.pageYOffset -parseInt(args.yOffset);
window.scrollTo({ top: y, behavior: 'smooth' });
});
@action
scrollTo(selector, yOffset, event) {
event.preventDefault();
this.scrollToModifier(event.target, [{ selector, yOffset }]);
}
}
{{!-- app/components/link-to-scroll.hbs --}}
<a
{{on 'click' (fn this.scrollTo @selector @yOffset)}}
href={{@selector}}
...attributes
>
{{yield}}
</a>
thank you.