Frontend Development 11 min read

Advanced JavaScript Methods: getBoundingClientRect, IntersectionObserver, createNodeIterator, getComputedStyle, requestAnimationFrame

This article introduces five lesser‑known but powerful JavaScript browser APIs—getBoundingClientRect, IntersectionObserver, createNodeIterator, getComputedStyle, and requestAnimationFrame—explaining their properties, typical application scenarios such as drag‑and‑drop, lazy loading, DOM traversal, style inspection, and animation timing, and providing ready‑to‑use code examples.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Advanced JavaScript Methods: getBoundingClientRect, IntersectionObserver, createNodeIterator, getComputedStyle, requestAnimationFrame

In JavaScript there are several lesser‑known but powerful browser APIs that can be extremely useful in front‑end development. This article introduces and demonstrates five such methods: getBoundingClientRect() , IntersectionObserver , createNodeIterator() , getComputedStyle() and requestAnimationFrame() . For each method we explain its purpose, key properties, typical use‑cases such as drag‑and‑drop, lazy loading, DOM traversal, style inspection and animation timing, and provide concrete code examples that can be copied directly into a project.

Preface

Some JavaScript methods are relatively obscure but very useful. They are not widely used because of compatibility issues, but they can play an important role in development.

getBoundingClientRect()

getBoundingClientRect() returns a DOMRect object containing the element’s size and its position relative to the viewport, including properties x , y , width , height , top , right , bottom and left .

const box = document.getElementById('box');
const rect = box.getBoundingClientRect();
console.log(rect.x);        // element left x coordinate
console.log(rect.y);        // element top y coordinate
console.log(rect.width);    // element width
console.log(rect.height);   // element height
console.log(rect.top);      // distance from top of viewport
console.log(rect.right);    // distance from left of viewport
console.log(rect.bottom);   // distance from top of viewport
console.log(rect.left);    // distance from left of viewport

Typical scenarios include drag‑and‑drop, positioning, responsive layout calculations and lazy‑loading images based on visibility.

Example of checking whether an element is in the viewport:

const box = document.getElementById('box');
window.onscroll = function () {
  console.log(checkInView(box));
};
function checkInView(dom) {
  const { top, left, bottom, right } = dom.getBoundingClientRect();
  return (
    top > 0 &&
    left > 0 &&
    bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
    right <= (window.innerWidth || document.documentElement.clientWidth)
  );
}

IntersectionObserver

IntersectionObserver is a constructor that observes the intersection of a target element with an ancestor element or the viewport. It receives a callback and an optional options object.

const observer = new IntersectionObserver(callback, options);
const callback = (entries, observer) => {
  // handle intersection changes
};
const options = {
  // optional configuration
};

Usage steps: create an observer, observe a target element, and handle intersection changes in the callback.

const target = document.querySelector('#targetElement');
observer.observe(target);
const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // element entered viewport
    } else {
      // element left viewport
    }
  });
};

Important entry properties: target , intersectionRatio , isIntersecting , intersectionRect . Common options: root , rootMargin , threshold .

Typical applications: lazy loading, infinite scrolling, ad visibility tracking, and detecting elements inside a container without causing reflow.

createNodeIterator()

createNodeIterator() creates a NodeIterator object for traversing a set of DOM nodes.

It is often a hidden interview question because it is rarely used in everyday code but appears in framework internals.

<body>
  <div id="app">
    <p>hello</p>
    <div class="title">标题</div>
    <div>
      <div class="content">内容</div>
    </div>
  </div>
</body>
<script>
  const body = document.getElementsByTagName('body')[0];
  const iterator = document.createNodeIterator(body);
  let node = iterator.nextNode();
  while (node) {
    console.log(node);
    if (node.nodeType !== 3) {
      node.setAttribute('data-index', 123);
    }
    node = iterator.nextNode();
  }
</script>

The script traverses all nodes under body and adds a data-index="123" attribute to each element.

getComputedStyle()

getComputedStyle() returns a CSSStyleDeclaration object containing the final computed CSS values for an element, optionally for a pseudo‑element.

<style>
  #box {
    width: 200px;
    height: 200px;
    background-color: cornflowerblue;
    position: relative;
  }
  #box::after {
    content: "";
    width: 50px;
    height: 50px;
    background: #000;
    position: absolute;
    top: 0;
    left: 0;
  }
</style>
const box = document.getElementById('box');
const style = window.getComputedStyle(box, 'after');
const height = style.getPropertyValue('height');
const width = style.getPropertyValue('width');
console.log(style);
console.log(width, height);

The output shows the computed width and height of the pseudo‑element #box::after .

requestAnimationFrame()

requestAnimationFrame() schedules a callback to run before the next browser repaint, typically at 60 fps, making it ideal for smooth animations compared to setInterval or setTimeout .

Example comparing requestAnimationFrame with setTimeout for moving two boxes:

let distance = 0;
let box = document.getElementById('box');
let box2 = document.getElementById('box2');
window.addEventListener('click', function () {
  function move() {
    box.style.transform = `translateX(${distance++}px)`;
    requestAnimationFrame(move);
  }
  requestAnimationFrame(move);
  function change() {
    box2.style.transform = `translateX(${distance++}px)`;
    setTimeout(change, 17);
  }
  setTimeout(change, 17);
});

The animation driven by requestAnimationFrame appears smoother than the one driven by setTimeout , which can exhibit jitter.

Conclusion

The article presented five advanced but not‑commonly used JavaScript methods that can greatly enhance front‑end development. Understanding and applying these APIs can help solve layout, visibility, traversal, style inspection, and animation challenges.

frontendJavaScriptWeb DevelopmentDOMBrowser APIs
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.