EN
JavaScript - check if element is visible on part of web page because of scrolling
7 points
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.
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.
xxxxxxxxxx
1
2
<html>
3
<head>
4
<style>
5
6
body { height: 200px; }
7
div { margin: 300px 0; border: 1px solid red; height: 100px; }
8
9
</style>
10
<script>
11
12
// Calculates element's relative position.
13
//
14
function calculateOffset(element) {
15
var result = 0;
16
while (element) {
17
var value = element.offsetTop;
18
if (value) {
19
result += value;
20
}
21
// jump to next relative, absolute or fixed parent element
22
element = element.offsetParent;
23
}
24
return result;
25
}
26
27
// Calculates space between elements.
28
//
29
function calculateSpace(firstElement, secondElement) {
30
var firstOffset = calculateOffset(firstElement);
31
var secondOffset = calculateOffset(secondElement);
32
return secondOffset - firstOffset;
33
}
34
35
// Creates element visibility detector.
36
//
37
function VisibilityDetector(container, element, onChange) {
38
var destroyed = false;
39
var enabled = false;
40
var visible = null;
41
function onScroll() {
42
var elementTop = calculateSpace(container, element);
43
var elementHeight = element.offsetHeight;
44
var scrollTop = container.scrollY || container.scrollTop || 0;
45
var containerHeight = container.innerHeight || container.clientHeight || 0;
46
if (elementTop - containerHeight < scrollTop && scrollTop < elementTop + elementHeight) {
47
if (visible == true) {
48
return;
49
}
50
visible = true;
51
onChange(visible);
52
} else {
53
if (visible == false) {
54
return;
55
}
56
visible = false;
57
onChange(visible);
58
}
59
}
60
this.enable = function() {
61
if (destroyed) {
62
throw new Error('Object has been destroyed.');
63
}
64
if (enabled) {
65
return;
66
}
67
enabled = true;
68
visible = null;
69
container.addEventListener('scroll', onScroll, false);
70
onScroll();
71
};
72
this.disable = function() {
73
if (destroyed) {
74
throw new Error('Object has been destroyed.');
75
}
76
if (enabled) {
77
enabled = false;
78
container.removeEventListener('scroll', onScroll, false);
79
}
80
};
81
this.destroy = function() { // it is good to destroy object if is not needed
82
if (destroyed) {
83
return;
84
}
85
destroyed = true;
86
enabled = false;
87
container.removeEventListener('scroll', onScroll, false);
88
};
89
}
90
91
</script>
92
</head>
93
<body>
94
<p>Scroll example and check console.</p>
95
<div id="element">Something here...</div>
96
<script>
97
98
// Usage example:
99
100
var element = document.querySelector('#element');
101
102
var detector = new VisibilityDetector(window, element, function(visible) {
103
console.clear();
104
console.log('element visible = ' + visible);
105
});
106
107
detector.enable();
108
109
</script>
110
</body>
111
</html>
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.
xxxxxxxxxx
1
2
<html>
3
<head>
4
<style>
5
6
#container { border: 1px solid blue; height: 200px; overflow-y: auto; }
7
#element { margin: 300px 0; border: 1px solid red; height: 100px; }
8
9
</style>
10
<script>
11
12
// Calculates element's relative position.
13
//
14
function calculateOffset(element) {
15
var result = 0;
16
while (element) {
17
var value = element.offsetTop;
18
if (value) {
19
result += value;
20
}
21
// jump to next relative, absolute or fixed parent element
22
element = element.offsetParent;
23
}
24
return result;
25
}
26
27
// Calculates space between elements.
28
//
29
function calculateSpace(firstElement, secondElement) {
30
var firstOffset = calculateOffset(firstElement);
31
var secondOffset = calculateOffset(secondElement);
32
return secondOffset - firstOffset;
33
}
34
35
// Creates element visibility detector.
36
//
37
function VisibilityDetector(container, element, onChange) {
38
var destroyed = false;
39
var enabled = false;
40
var visible = null;
41
function onScroll() {
42
var elementTop = calculateSpace(container, element);
43
var elementHeight = element.offsetHeight;
44
var scrollTop = container.scrollY || container.scrollTop || 0;
45
var containerHeight = container.innerHeight || container.clientHeight || 0;
46
if (elementTop - containerHeight < scrollTop && scrollTop < elementTop + elementHeight) {
47
if (visible == true) {
48
return;
49
}
50
visible = true;
51
onChange(visible);
52
} else {
53
if (visible == false) {
54
return;
55
}
56
visible = false;
57
onChange(visible);
58
}
59
}
60
this.enable = function() {
61
if (destroyed) {
62
throw new Error('Object has been destroyed.');
63
}
64
if (enabled) {
65
return;
66
}
67
enabled = true;
68
visible = null;
69
container.addEventListener('scroll', onScroll, false);
70
onScroll();
71
};
72
this.disable = function() {
73
if (destroyed) {
74
throw new Error('Object has been destroyed.');
75
}
76
if (enabled) {
77
enabled = false;
78
container.removeEventListener('scroll', onScroll, false);
79
}
80
};
81
this.destroy = function() { // it is good to destroy object if is not needed
82
if (destroyed) {
83
return;
84
}
85
destroyed = true;
86
enabled = false;
87
container.removeEventListener('scroll', onScroll, false);
88
};
89
}
90
91
</script>
92
</head>
93
<body>
94
<p>Page text...</p>
95
<div id="container">
96
<p>Scroll example and check console.</p>
97
<div id="element">Something here...</div>
98
</div>
99
<p>Page text...</p>
100
<script>
101
102
// Usage example:
103
104
var container = document.querySelector('#container');
105
var element = document.querySelector('#element');
106
107
var detector = new VisibilityDetector(container, element, function(visible) {
108
console.clear();
109
console.log('element visible = ' + visible);
110
});
111
112
detector.enable();
113
114
</script>
115
</body>
116
</html>