Answer the question
In order to leave comments, you need to log in
Vue. What is the best way to implement the visibility of an element on the screen?
Good day!
There is a HomePage.vue page, which has several DOM elements that should be displayed when they appear in the screen's viewport.
There is a simple visibility check function
function isVisible(el) {
let elTop = el.offsetTop;
let rect = el.getBoundingClientRect();
return !(elTop <= rect.top || rect.bottom <= 0);
}
let onscreen = {
bind(el, options) {
let className = options.value;
let deleteClass = options.arg === "delete";
window.addEventListener("scroll", () => {
if (isVisible(el)) {
if (deleteClass) {
el.classList.remove(className)
} else {
el.classList.add(className)
}
} else {
if (deleteClass) {
el.classList.add(className)
} else {
el.classList.remove(className)
}
}
});
},
unbind() {
// ???
}
};
Answer the question
In order to leave comments, you need to log in
But how to remove this wiretapping later in unbind?
bind(el, options) {
const handler = () => { ... };
window.addEventListener('scroll', handler);
el.scrollHandler = handler;
},
unbind(el) {
window.removeEventListener('scroll', el.scrollHandler);
},
const map = new Map();
window.addEventListener('scroll', function(e) {
[...map.entries()].forEach(([ el, { className, deleteClass } ]) => {
...
});
});
bind(el, options) {
map.set(el, {
className: options.value,
deleteClass: options.arg === 'delete',
});
},
unbind(el) {
map.delete(el);
},
Change the variables yourself so that everything works as it should.
And so the usual removeEventListener, in order to remove it, you must pass the same callback as with addEventListener
let onscreen = {
bind(el, options) {
let className = options.value;
let deleteClass = options.arg === "delete";
window.addEventListener("scroll", this.action);
},
unbind() {
window.removeEventListener("scroll", this.action);
},
action() {
if (isVisible(el)) {
if (deleteClass) {
el.classList.remove(className)
} else {
el.classList.add(className)
}
} else {
if (deleteClass) {
el.classList.add(className)
} else {
el.classList.remove(className)
}
}
}
};
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question