Languages
[Edit]
EN

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

4 points
Created by:
Marcin
2544

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.

1. 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>
</head>
<body>
  <p>Scroll example and check console.</p>
  <div id="element">
      Something here...
  </div>
  <script>

    // calculates relative position of element
    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;
    }
    
    // element visibility state changed by scrolling detector
    function VisibilityDetector(container, element, onChange) {
        var enabled = false;
      	var visible = null;
      
        function onScroll() {
            var elementTop = calculateSpace(container, element);

            var containerHeight = container.innerHeight || container.clientHeight || 0;
            var elementHeight = element.offsetHeight;
          	var scrollTop = container.scrollY || container.scrollTop || 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 (enabled) {
            	return;
            }
            enabled = true;
          	visible = null;
            container.addEventListener('scroll', onScroll, false);
            onScroll();
        };
        this.disable = function() {
            if (enabled) {
                enabled = false;
                container.removeEventListener('scroll', onScroll, false);
            }
        };

        // it is good to destroy object if is not needed
        this.destroy = this.disable;
    }

    // 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>

2. 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>
</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>

    // calculates relative position of element
    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;
    }
    
    // element visibility state changed by scrolling detector
    function VisibilityDetector(container, element, onChange) {
        var enabled = false;
      	var visible = null;
      
        function onScroll() {
            var elementTop = calculateSpace(container, element);

            var containerHeight = container.innerHeight || container.clientHeight || 0;
            var elementHeight = element.offsetHeight;
          	var scrollTop = container.scrollY || container.scrollTop || 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 (enabled) {
            	return;
            }
            enabled = true;
          	visible = null;
            container.addEventListener('scroll', onScroll, false);
            onScroll();
        };
        this.disable = function() {
            if (enabled) {
                enabled = false;
                container.removeEventListener('scroll', onScroll, false);
            }
        };

        // it is good to destroy object if is not needed
        this.destroy = this.disable;
    }

    // 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>

 

Native Advertising
50 000 ad impressions - 449$
🚀
Get your tech brand or product in front of software developers.
For more information contact us:
Red dot
Dirask - friendly IT community for everyone.

❤️💻 🙂

Join