As web developers we write a lot of code to detect changes in our web app and do manipulations based on those changes. Today, the web has lots of APIs for “observing” your web app for many types of changes and letting you perform actions based on them.
Here’s a quick round up-
1. Observing the DOM through event listeners
The most classic way to detect changes by using addEventListener
. This can be used to listen to native as well and custom events.
window.addEventListener('scroll', e => { ... }); // user scrolls the page.
el.addEventListener('focus', e => { ... }); // el is focused.
img.addEventListener('load', e => { ... }); // img is done loading.
el.addEventListener('custom-event', e => { ... }); // catch custom event fired on el.
2. Check for DOM tree modifications
The MutationObserver interface provides the ability to watch for changes being made to the DOM tree.
const target = document.querySelector('#div_id');
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
console.log(mutation.type);
});
});
const config = {
attributes: true,
childList: true,
characterData: true
}
observer.observe(target, config);
3. Check when an element comes into view
The Intersection Observer API provides an easy way to watch and register callbacks to trigger when elements on a page come into view.
const images = document.querySelectorAll('.animate');
observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
console.log('in the view');
} else {
console.log('out of view');
}
});
});
images.forEach(image => {
observer.observe(image);
});
Using this API we can trigger animations, lazy load images etc., when they come into view.
4. Check when the elements in DOM are re-sized
The ResizeObserver allows for elements to be notified when their size changes.
const myObserver = new ResizeObserver(entries => {
entries.forEach(entry => {
console.log('width', entry.contentRect.width);
console.log('height', entry.contentRect.height);
});
});
const el = document.querySelector('.some-element');
myObserver.observe(el);
With each entry, we get an object with properties - contentRect
and target
. The target is the DOM element itself, and contentRect is an object with the following properties: width
, height
, x
, y
, top
, bottom
, left
and right
.
5. Check if your web app is on full-screen mode
Using the Fullscreen API makes this possible.
var el = document.getElementById("myvideo");
if (el.requestFullscreen) {
el.requestFullscreen();
}
Not just detection of full-screen mode but this API also allows the turning off and on of full-screen mode.
6. Check if the tab is in focus
document.addEventListener('visibilitychange', e => {
if(document.hidden) {
// .... do something
} else {
// .... dome something else
}
});
I am still including this in the list even if this is not a new API but rather a technique. One use case can be to draw user attention back to the abandoned tab.
7. Check for device orientation changes
The Screen Orientation API makes this possible.
window.addEventListener('orientationchange', e => {
console.log(screen.orientation.angle, screen.orientatio.type)
});
We can also check to see if the current orientation matches to a particular orientation.
const media = window.matchMedia('(orientation: portrait)');
media.addListener(mql => console.log(mql.matches));
8. Check for network status and changes
The Network Information API provides information about user’s network connection. Using this information it’s possible to conditionally load images, videos, fonts and other resources.
navigator.connection.addEventListener('change', e => {
console.log(navigator.connection.effectiveType, navigator.connection.downlink);
});
Apart from properties effectiveType
and downlink
mentioned above, it also provides downlinkMax
, rtt
, saveData
, type
.
9. Check status of the device battery
This is possible using the Battery Status API.
navigator.getBattery().then(battery => {
console.log(
battery.level * 100 + '%',
battery.charging,
battery.chargingTime,
battery.dischargingTime
);
});
10. Check when your web app uses a deprecated API or hits a browser intervention
The Reporting API makes it possible
const observer = new ReportingObserver((reports, observer) => {
reports.map(report => {
console.log(report);
// ..... send report to analytics etc..
});
}, {buffered: true});
observer.observe();
I believe, currently, the ReportingObserver
has only been shipped in latest Chrome.
11. Check the performance of you web app
The [PerformanceObserver] (https://developers.google.com/web/updates/2016/06/performance-observer) interface is used to observe performance measurement events and be notified of new performance entries as they are recorded in the browser’s performance timeline.
const observer = new window.PerformanceObserver(list => {
list.getEntries().forEach(({name, startTime}) => {
console.log({name, startTime});
});
});
observer.observe({
entryTypes: [{'paint', 'resource', 'mark', 'measure'}]
});
It’s really amazing that the web has so many great APIs at our disposal. Using these we can create web apps with better performance and greater user experience.
Note: Always check the browser support before using the modern APIs.