admin管理员组文章数量:1203409
I'm wondering if anyone has an easy solution for this. I'm trying to detect if any part of a HTML
element finds itself outside of the viewport. I've tried utilizing the following code:
$.fn.isOnScreen = function(){
var win = $(window);
var viewport = {
top : win.scrollTop(),
left : win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
Brought to you by Steven
I can only get this to work when the entire element is not viewable anymore, but I just need to know if part of the element is outside of the viewport.
When the element is outside of the viewport, then I'm putting a different class on it, so that it will shift to the left instead so that it is viewable again.
Something like:
if(elementIsPartiallyOutsideViewport) {
ele.addClass('move-left');
}
Any ideas?
I'm wondering if anyone has an easy solution for this. I'm trying to detect if any part of a HTML
element finds itself outside of the viewport. I've tried utilizing the following code:
$.fn.isOnScreen = function(){
var win = $(window);
var viewport = {
top : win.scrollTop(),
left : win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
Brought to you by Steven
I can only get this to work when the entire element is not viewable anymore, but I just need to know if part of the element is outside of the viewport.
When the element is outside of the viewport, then I'm putting a different class on it, so that it will shift to the left instead so that it is viewable again.
Something like:
if(elementIsPartiallyOutsideViewport) {
ele.addClass('move-left');
}
Any ideas?
Share Improve this question edited Feb 10, 2014 at 22:24 Romes asked Feb 10, 2014 at 21:45 RomesRomes 3,1185 gold badges39 silver badges52 bronze badges 2- how do you want the function to work? find the element outside the viewport and return it or you give the element as param and want the return a boolean value? – Zafar Commented Feb 10, 2014 at 22:18
- Something to the effect of: if(elementPartiallyOusideViewport) { ele.addClass('move-left') } if that makes sense to you... – Romes Commented Feb 10, 2014 at 22:22
2 Answers
Reset to default 22Most of the browsers already support getBoundingClientRect()
method. So you can try the following code.
function isElementInViewport (el) {
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
You simply pass the element to the function and get false
if element is not inside the viewport.
Usage.
if (!isElementInViewport(el)) {
el.addClass('move-left');
}
Edit
Just an addition. You can get more info about getBoundingClientRect()
function and the browser support in here
There is a solution with an Intersection Observer. An advantage of the solution is position-relative calculations are not required.
jQuery plugin code snippet: (plugin.js)
(function ($) {
class IntersectionDetector {
async isElementPartiallyOutOfViewport(element) {
return new Promise((resolve) => {
const callback = this.handleOutOfViewportObservation.bind(this, resolve);
const options = {
root: null,
threshold: 0,
}
const observer = new IntersectionObserver(callback, options);
observer.observe(element);
})
}
handleOutOfViewportObservation(resolve, [entry], observer) {
const element = entry.target;
observer.unobserve(element);
observer.disconnect();
const ratios = new Map();
ratios.set('inViewportCompletelyRatio', 1);
ratios.set('outOfViewportCompletelyRatio', 0);
ratios.set('actualRatio', entry.intersectionRatio);
const precision = Math.pow(10, 2);
for (const [name, prevRatio] of ratios) {
const nextRatio = precision * prevRatio;
ratios.set(name, nextRatio);
}
const actualRatio = ratios.get('actualRatio');
const inViewportCompletelyRatio = ratios.get('inViewportCompletelyRatio');
const outOfViewportCompletelyRatio = ratios.get('outOfViewportCompletelyRatio');
const isOutOfViewportPartially =
(actualRatio > outOfViewportCompletelyRatio) &&
(actualRatio < inViewportCompletelyRatio);
resolve(isOutOfViewportPartially);
}
}
$.fn.isOnScreen = async function () {
const elements = this;
const promises = elements.map(async (index, element) => {
const detector = new IntersectionDetector();
return await detector.isElementPartiallyOutOfViewport(element);
});
const results = await Promise.all(promises);
return results.every(result => result);
};
}(jQuery));
Usage example: (main.js)
jQuery(async function ($) {
const isOnScreen = await $('#element-to-check').isOnScreen();
console.log(isOnScreen);
});
Explanation:
- jQuery operates nodes collection, thus a better option is to check every node in a collection. If every node in the collection is partially visible the function returns true.
- The observer has specified a root argument equal to null, which means the element's intersection is being detected relative to a browser window.
- The solution uses precision. Potentially, JavaScript can cause a mistake while processing floating point numbers. The idea is to compare integer parts of numbers instead of floats to avoid the incorrect result. For instance, there is a good answer to this issue: https://stackoverflow.com/a/50780164/11173494
The code tested for:
- jQuery 3.6.*
- Chrome 103.0.* / Firefox 108.0
本文标签: javascriptHow to detect if DOM element is partially out of the viewportStack Overflow
版权声明:本文标题:javascript - How to detect if DOM element is partially out of the viewport - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738665176a2105657.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论