For all those who do not know what the viewport is, it’s the portion of the document that is currently within view. This generally changes whenever you use the scrollbars. For example, if you were to scroll down on this webpage then the viewport would change. Likewise, if you were to resize the browser window, then the viewport size would also be changed. It’s still the same document that was originally loaded, but you can only look at a portion of the document at one time. This portion is called the viewport.
I haven’t really seen too much javascript code snippets written that focused on the viewport, which is a shame because I believe it could lead to a lot of very smooth looking javascript effects.
I went ahead and used a few functions that jQuery defines to help describe the viewport and I created a viewport object. In addition to jQuery this code also uses ASP .NET 3.5’s built in javascript library. If you would like to use this code but are not using the javascript library that ASP .NET provides, then you should only need to replace the functions Sys.UI.DomElement.getBounds(element) and Sys.UI.DomElement.setLocation(element, x, y) with javascript code that gets the x and y coordinates and sets a new x, y location for a given element (e.g. the popup). I can’t imagine that would be too hard to find.
Here’s the code:
————————————–
function ViewPortVars()
{ }
ViewPortVars.prototype =
{
X: function()
{
return $(window).scrollLeft();
},
Y: function()
{
return $(window).scrollTop();
},
Width: function()
{
return $(window).width();
},
Height: function()
{
return $(window).height();
},
UpperLeft: function()
{
return { X: this.X(), Y: this.Y() };
},
UpperRight: function()
{
return { X: this.X() + this.Width(), Y: this.Y() };
},
LowerLeft: function()
{
return { X: this.X(), Y: this.Y() + this.Height() };
},
LowerRight: function()
{
return { X: this.X() + this.Width(), Y: this.Y() + this.Height() };
},
ElementAreaOutsideViewPort: function(element)
{
var area = { Right: 0, Left: 0, Top: 0, Bottom: 0 };
if (element)
{
var bounds = Sys.UI.DomElement.getBounds(element);
if (bounds.height <= 0 || bounds.width <= 0 || bounds.x < 0 || bounds.y < 0)
return null;
if (bounds.x + $(element).width() > this.UpperRight().X)
area.Right = bounds.x + $(element).width() - this.UpperRight().X;
if (this.UpperLeft().X > bounds.x)
area.Left = this.UpperLeft().X - bounds.x
if (this.UpperLeft().Y > bounds.y)
area.Top = this.UpperLeft().Y - bounds.y;
if (bounds.y + $(element).height() > this.LowerLeft().Y)
area.Bottom = bounds.y + $(element).height() - this.LowerLeft().Y
}
if (area.Left > 0 || area.Right > 0 || area.Top > 0 || area.Bottom > 0)
return area;
else
return null;
},
IsOutsideViewPort: function(element)
{
return this.ElementAreaOutsideViewPort(element) != null;
},
PositionPopup: function(element)
{
if (element)
{
var outsideArea = viewport.ElementAreaOutsideViewPort(element);
if (outsideArea)
{
var bounds = Sys.UI.DomElement.getBounds(element);
var x = bounds.x;
var y = bounds.y;
var padding = 10;
if (outsideArea.Left > 0)
x = bounds.x + outsideArea.Left + padding;
else if (outsideArea.Right > 0)
x = bounds.x - outsideArea.Right - padding;
if (outsideArea.Top > 0)
y = bounds.y + outsideArea.Top + padding;
else if (outsideArea.Bottom > 0)
y = bounds.y - outsideArea.Bottom - padding;
Sys.UI.DomElement.setLocation(element, x, y);
}
}
}
}
var viewport = new ViewPortVars();
——————————
You’ll notice at the very end of the code block I instantiated a viewport object. The idea here is that if you put this code in it’s own file and referenced it at the top of the page, then if you needed to use any of these functions then you could just call the viewport object.
Now here’s an explanation of what each function does:
viewport.X()
Returns the X coordinate of the viewport in reference to the top left corner of the document. For example, if you scroll 200 pixals to the right then this function will return the number 200 when it’s called.
viewport.Y()
Returns the Y coordinate of the viewport in reference to the top left corner of the document. For example, if you scroll 400 pixals down, then this function will return 400 when it’s called.
viewport.Width()
Returns the current width of the viewport.
viewport.Height()
Returns the current height of the viewport.
viewport.UpperLeft()
Returns the X and Y coordinates of the upper left corner of the viewport. To call the X coordinate call viewport.UpperLeft().X and likewise for Y.
viewport.UpperRight()
Returns the X and Y coordinates of the upper right corner of the viewport. To call the X coordinate call viewport.UpperRight().X and likewise for Y.
viewport.LowerLeft()
Returns the X and Y coordinates of the lower left corner of the viewport. To call the X coordinate call viewport.LowerLeft().X and likewise for Y.
viewport.LowerRight()
Returns the X and Y coordinates of the lower right corner of the viewport. To call the X coordinate call viewport.LowerRight().X and likewise for Y.
viewport.ElementAreaOutsideViewPort(element)
This function returns an object with four properties: Right, Left, Top and Bottom. Each property refers to the amount of pixals that the element is occupying outside of the visible viewport. For example, if the element has 20 px off the right side of the screen such that you need to scroll at least 20 px to the right in order to bring the entire element into view then the Right property will be 20. If the rest of the element with exception to the right side is perfectly within view then all other properties will be 0. I made it return null if all properties were 0 just because it saved me some coding in certain projects.
Ex. var area = viewport.ElementAreaOutsideViewPort(element); var r = area.Right; //returns 20 in above example var l = area.Left; //returns 0 in above example var t = area.Top; //returns 0 in above example var b = area.Bottom; //returns 0 in above example
viewport.IsOutsideViewPort(element)
Returns true if there’s a little bit of the element outside of the viewport. Returns false if the element is completely within view. You could also write a similar function like IsElementWithinView(element) that would return just the opposite (true if the element is completely within view).
viewport.PositionPopup(element)
This function is actually the concept that lead me to writing this object. When you click a button or a link that displays a popup on the screen this function will determine whether or not the popup is completely within view and if not then it will nudge the popup into view. The element in this case is the popup. I should mention that this function assumes that the code work in this order:
1) The popup is displayed (e.g. “pops up”)
2) This function is called
Whether or not you use this object for a popup, it’s basic purpose is to describe the current state of the viewport and also to tell whether an element is within the viewport or out of view from the user.