Detecting when DOM node comes into view with Dojo

Working on a project that uses dojo, the need arose to have the ability to automatically be notified when a DOM node comes into view in the browser window. For example, the node may below the fold, and when the page is scrolled, and the node comes into view, the application is notified.

Searching around, I came across this useful post:


However, the code uses YUI, while I needed something that works with dojo (v1.4). Also, what Mr. Diaz provides does not deal with resize events that can cause a node to become visible, or the case when the node is already visible (before any scroll or resize occurs).

So I wrote up a mini-library to provide something that works with dojo. A couple of the utility functions can probably be replaced if using a later version of dojo, but since I needed something to work with dojo 1.4, I could not use newer convenience functions to access window dimensions (like dojo.window.getBox).

Basic usage:
ewh.nodeview.connect(domNode, func, cdata);

domNode is the DOM node that you want monitored.
func is the function that is called when domNode comes into view.
cdata is an arbitrary object to pass into func when it is called.

Note: Some may say that call-data can be attached to func itself and/or use dojo.hitch(), but I wanted to provide an interface that was friendly to those who may not be familiar with such techniques.

When func is called, it is passed an object. The object contains the following properties:
  • node: The DOM node.
  • cdata: Callback object.
  • event: Associated event object, which can be undefined.
The function is only ever called once. Once called, the internal event hooks are disconnected. If for whatever reason the caller needs to be notified again for the node, they can call the connect method again for it.

Source code:

1 comment:

  1. Really helpful thanks.
    This was working for me on the desktop and Android however when I tried on iPhone Safari the result from computeViewLoc was always smaller than the node position.y.
    Changed the function to var p = dojo.position(node, false) and it worked OK.
    Couldn't quite get my head around it but as long as it works!