var visibleY = function(el){var top = el.getBoundingClientRect().top, rect, el = el.parentNode;do {rect = el.getBoundingClientRect();if (top <= rect.bottom === false)return false;el = el.parentNode;} while (el != document.body);// Check it's within the document viewportreturn top <= document.documentElement.clientHeight;};
$.fn.inView = function(){if(!this.length)return false;var rect = this.get(0).getBoundingClientRect();
return (rect.top >= 0 &&rect.left >= 0 &&rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&rect.right <= (window.innerWidth || document.documentElement.clientWidth));
};
// Additional examples for other use cases// Is true false whether an array of elements are all in view$.fn.allInView = function(){var all = [];this.forEach(function(){all.push( $(this).inView() );});return all.indexOf(false) === -1;};
// Only the class elements in view$('.some-class').filter(function(){return $(this).inView();});
// Only the class elements not in view$('.some-class').filter(function(){return !$(this).inView();});
用法
$(window).on('scroll',function(){
if( $('footer').inView() ) {// Do cool stuff}});
这是我的代码(告诉我它是否不起作用;它已经在Internet Explorer 11,Firefox 40.0.3,Chrome版本45.0.2454.85 m,Opera 31.0.1889.174和Edge with Windows 10中进行了测试,[尚未Safari])…
// Scrolling handlers...window.onscroll = function(){var elements = document.getElementById('whatever').getElementsByClassName('whatever');for(var i = 0; i != elements.length; i++){if(elements[i].getBoundingClientRect().top <= window.innerHeight*0.75 &&elements[i].getBoundingClientRect().top > 0){console.log(elements[i].nodeName + ' ' +elements[i].className + ' ' +elements[i].id +' is in the viewport; proceed with whatever code you want to do here.');}};
// For checking element visibility from any sidesisVisible(element)
// For checking elements visibility in a parent you would like to checkvar parent = document; // Assuming you check if 'element' inside 'document'isVisible(element, parent)
// For checking elements visibility even if it's bigger than viewportisVisible(element, null, true) // Without parent choiceisVisible(element, parent, true) // With parent choice
function isVisible(element, parent, crossSearchAlgorithm) {var rect = element.getBoundingClientRect(),prect = (parent != undefined) ? parent.getBoundingClientRect() : element.parentNode.getBoundingClientRect(),csa = (crossSearchAlgorithm != undefined) ? crossSearchAlgorithm : false,efp = function (x, y) { return document.elementFromPoint(x, y) };// Return false if it's not in the viewportif (rect.right < prect.left || rect.bottom < prect.top || rect.left > prect.right || rect.top > prect.bottom) {return false;}var flag = false;// Return true if left to right any border pixel reachedfor (var x = rect.left; x < rect.right; x++) {if (element.contains(efp(rect.top, x)) || element.contains(efp(rect.bottom, x))) {flag = true;break;}}// Return true if top to bottom any border pixel reachedif (flag == false) {for (var y = rect.top; y < rect.bottom; y++) {if (element.contains(efp(rect.left, y)) || element.contains(efp(rect.right, y))) {flag = true;break;}}}if(csa) {// Another algorithm to check if element is centered and bigger than viewportif (flag == false) {var x = rect.left;var y = rect.top;// From top left to bottom rightwhile(x < rect.right || y < rect.bottom) {if (element.contains(efp(x,y))) {flag = true;break;}if(x < rect.right) { x++; }if(y < rect.bottom) { y++; }}if (flag == false) {x = rect.right;y = rect.top;// From top right to bottom leftwhile(x > rect.left || y < rect.bottom) {if (element.contains(efp(x,y))) {flag = true;break;}if(x > rect.left) { x--; }if(y < rect.bottom) { y++; }}}}}return flag;}
// Check multiple elements visibilitydocument.getElementById('container').addEventListener("scroll", function() {var elementList = document.getElementsByClassName("element");var console = document.getElementById('console');for (var i=0; i < elementList.length; i++) {// I did not define parent so it will be element's parent// and it will do crossSearchAlgorithmif (isVisible(elementList[i],null,true)) {console.innerHTML = "Element with id[" + elementList[i].id + "] is visible!";break;} else {console.innerHTML = "Element with id[" + elementList[i].id + "] is hidden!";}}});// Dynamically added elementsfor(var i=4; i <= 6; i++) {var newElement = document.createElement("div");newElement.id = "element" + i;newElement.classList.add("element");document.getElementById('container').appendChild(newElement);}
const el = document.querySelector('#el')const observer = new window.IntersectionObserver(([entry]) => {if (entry.isIntersecting) {console.log('ENTER')return}console.log('LEAVE')}, {root: null,threshold: 0.1, // set offset 0.1 means trigger if atleast 10% of element in viewport})
observer.observe(el);