Languages
[Edit]
EN

JavaScript - check if element is visible on part of web page because of scrolling

7 points
Created by:
lena
624

In this article, we're going to have a look at how to check with JavaScript if element is visible on screen or not during scrolling in JavaScript.

This kind of script can be used to detect if image is in visible part of web page and sould be loaded to prevent unnecessary content loading.

 

Page scrolling example

In this section, presented solution shows how to check if element visibility if is located on page.

Presented script is universal because as container we can use window object or any element.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>

    body { height: 200px; }
    div { margin: 300px 0; border: 1px solid red; height: 100px; }

  </style>
  <script>
    
    // Calculates element's relative position.
    //
    function calculateOffset(element) {
        var result = 0;
        while (element) {
            var value = element.offsetTop;
            if (value) {
              	result += value;
            }
           	// jump to next relative, absolute or fixed parent element
            element = element.offsetParent;
        }
        return result;
    }
    
    // Calculates space between elements.
    //
    function calculateSpace(firstElement, secondElement) {
        var firstOffset = calculateOffset(firstElement);
        var secondOffset = calculateOffset(secondElement);
        return secondOffset - firstOffset;
    }

    // Creates element visibility detector.
    //
    function VisibilityDetector(container, element, onChange) {
        var destroyed = false;
        var enabled = false;
      	var visible = null;
        function onScroll() {
            var elementTop = calculateSpace(container, element);
            var elementHeight = element.offsetHeight;
            var scrollTop = container.scrollY || container.scrollTop || 0;
          	var containerHeight = container.innerHeight || container.clientHeight || 0;
            if (elementTop - containerHeight < scrollTop && scrollTop < elementTop + elementHeight) {
            	if (visible == true) {
                	return;
                }
              	visible = true;
              	onChange(visible);
            } else {
            	if (visible == false) {
					return;
				}
				visible = false;
				onChange(visible);
            }
        }
        this.enable = function() {
            if (destroyed) {
                throw new Error('Object has been destroyed.');
            }
            if (enabled) {
            	return;
            }
            enabled = true;
          	visible = null;
            container.addEventListener('scroll', onScroll, false);
            onScroll();
        };
        this.disable = function() {
            if (destroyed) {
                throw new Error('Object has been destroyed.');
            }
            if (enabled) {
                enabled = false;
                container.removeEventListener('scroll', onScroll, false);
            }
        };
        this.destroy = function() { // it is good to destroy object if is not needed
            if (destroyed) {
                return;
            }
            destroyed = true;
            enabled = false;
            container.removeEventListener('scroll', onScroll, false);
        };
    }
    
  </script>
</head>
<body>
  <p>Scroll example and check console.</p>
  <div id="element">Something here...</div>
  <script>

    // Usage example:
    
    var element = document.querySelector('#element');
    
    var detector = new VisibilityDetector(window, element, function(visible) {
	    console.clear();
        console.log('element visible = ' + visible);
    });

    detector.enable();

  </script>
</body>
</html>

 

Nested element scrolling example

In this section, presented solution shows how to check if element visibility if is located in another scollable element.

This is same script like above presented but used with element container.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>

    #container { border: 1px solid blue; height: 200px; overflow-y: auto; }
    #element { margin: 300px 0; border: 1px solid red; height: 100px; }

  </style>
  <script>
    
    // Calculates element's relative position.
    //
    function calculateOffset(element) {
        var result = 0;
        while (element) {
            var value = element.offsetTop;
            if (value) {
              	result += value;
            }
           	// jump to next relative, absolute or fixed parent element
            element = element.offsetParent;
        }
        return result;
    }
    
    // Calculates space between elements.
    //
    function calculateSpace(firstElement, secondElement) {
        var firstOffset = calculateOffset(firstElement);
        var secondOffset = calculateOffset(secondElement);
        return secondOffset - firstOffset;
    }

    // Creates element visibility detector.
    //
    function VisibilityDetector(container, element, onChange) {
        var destroyed = false;
        var enabled = false;
      	var visible = null;
        function onScroll() {
            var elementTop = calculateSpace(container, element);
            var elementHeight = element.offsetHeight;
          	var scrollTop = container.scrollY || container.scrollTop || 0;
            var containerHeight = container.innerHeight || container.clientHeight || 0;
            if (elementTop - containerHeight < scrollTop && scrollTop < elementTop + elementHeight) {
            	if (visible == true) {
                	return;
                }
              	visible = true;
              	onChange(visible);
            } else {
            	if (visible == false) {
					return;
				}
				visible = false;
				onChange(visible);
            }
        }
        this.enable = function() {
            if (destroyed) {
                throw new Error('Object has been destroyed.');
            }
            if (enabled) {
            	return;
            }
            enabled = true;
          	visible = null;
            container.addEventListener('scroll', onScroll, false);
            onScroll();
        };
        this.disable = function() {
            if (destroyed) {
                throw new Error('Object has been destroyed.');
            }
            if (enabled) {
                enabled = false;
                container.removeEventListener('scroll', onScroll, false);
            }
        };
        this.destroy = function() { // it is good to destroy object if is not needed
            if (destroyed) {
                return;
            }
            destroyed = true;
            enabled = false;
            container.removeEventListener('scroll', onScroll, false);
        };
    }
    
  </script>
</head>
<body>
  <p>Page text...</p>
  <div id="container">
    <p>Scroll example and check console.</p>
  	<div id="element">Something here...</div>
  </div>
  <p>Page text...</p>
  <script>

    // Usage example:
    
    var container = document.querySelector('#container');
    var element = document.querySelector('#element');
    
    var detector = new VisibilityDetector(container, element, function(visible) {
	    console.clear();
        console.log('element visible = ' + visible);
    });

    detector.enable();

  </script>
</body>
</html>

 

Alternative titles

  1. JavaScript - check if element is visible on scrolled page / inside container
  2. JavaScript - detect element visibility on scrolling
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join