JavaScript - Cross Browser Window Size And Centering

It seems all I talk about lately is extending JavaScript functionality. Well, I am going to talk about it again. Today we are going to look at some code that makes cross browser calculations of window size very easy.

I use Mootools a lot in my projects, mostly for it’s ajax capabilities and it’s FX classes. One thing that I was a bit disappointed and surprised to find was it’s Window.Size.js. It is full of great and easy methods but it requires an XHTML strict doctype to function correctly. Sometimes though it is not possible (or maybe not favorable) to use a strict doctype. Occassionaly I have to use a transitional doctype (usually to support old code) and in situations like this Mootools Window.Size fails to function correctly.

I thought surely it can’t be that hard to determine whether IE is in strict or quirks mode. As it turns out it wasn’t hard at all to tell the difference. So the functions I will be providing you are fully cross browser, strict or quirks mode compatible.

Window.Size.js

window.size = function()
{
	var w = 0;
	var h = 0;

	//IE
	if(!window.innerWidth)
	{
		//strict mode
		if(!(document.documentElement.clientWidth == 0))
		{
			w = document.documentElement.clientWidth;
			h = document.documentElement.clientHeight;
		}
		//quirks mode
		else
		{
			w = document.body.clientWidth;
			h = document.body.clientHeight;
		}
	}
	//w3c
	else
	{
		w = window.innerWidth;
		h = window.innerHeight;
	}
	return {width:w,height:h};
}

window.center = function()
{
	var hWnd = (arguments[0] != null) ? arguments[0] : {width:0,height:0};

	var _x = 0;
	var _y = 0;
	var offsetX = 0;
	var offsetY = 0;

	//IE
	if(!window.pageYOffset)
	{
		//strict mode
		if(!(document.documentElement.scrollTop == 0))
		{
			offsetY = document.documentElement.scrollTop;
			offsetX = document.documentElement.scrollLeft;
		}
		//quirks mode
		else
		{
			offsetY = document.body.scrollTop;
			offsetX = document.body.scrollLeft;
		}
	}
	//w3c
	else
	{
		offsetX = window.pageXOffset;
		offsetY = window.pageYOffset;
	}

	_x = ((this.size().width-hWnd.width)/2)+offsetX;
	_y = ((this.size().height-hWnd.height)/2)+offsetY;

	return{x:_x,y:_y};
}

Sample Page

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
	<title></title>
	<script type="text/javascript" src="Window.Size.js"></script>
	<script type="text/javascript">

		function showCenter(point)
		{
			var div = document.createElement("div");
			div.style.background = "#dedede";
			div.style.position = "absolute";
			div.style.top = point.y + "px";
			div.style.left = point.x + "px";
			div.style.width = "100px";
			div.style.height = "100px";
			document.body.appendChild(div);
		}

	</script>
</head>
<body>

	<div style="height:1200px"></div>
	<input type="button" value="Get Center" onclick="showCenter(window.center({width:100,height:100}))"/>

</body>
</html>

Enjoy

JavaScript - String Builder Plugin

In continuing with my theme of porting useful C# functionality to JavaScript I have desided to add C#’s StringBuilder class to JavaScript in the form of String.builder.

When simply concatenating strings the string builder class may not be of much use since a simple += will suffice but when you need to go deeper and manipulate that concatenated string then the string builder really shines.

The string builder class has 6 methods to work with.

Method Name Method Use
append(string) adds string to the end of the string
clear() clears the internal buffer
insert(index, string) inserts string into the given buffer index overriding the existing value
remove(string)
remove(index, length)
this method is overloaded
1 of 2: removes all occurances of string
2 of 2: removes stating at index and removes length number of indexes
replace(findThis, replaceWith) replaces all occurances of findThis with replaceWith
toString() returns the concatentated string

Below is the source code for this class and a simple example of it’s use.

JavaScript

if(!String.builder)
{
	String.builder = function()
	{
		var buffer = [];

		this.append = function(str)
		{
			buffer.push(str);
		}
		this.clear = function()
		{
			buffer = null;
			buffer = [];
		}
		this.insert = function(index, str)
		{
			if(buffer[index]){buffer[index] = str;}
			else{return false;}
		}
		this.replace = function(find, replace)
		{
			for(var i=0;i<buffer.length;i++)
			{
				var exp = new RegExp(find,'gm');
				buffer[i] = buffer[i].replace(exp,replace);
			}
		}
		this.remove = function()
		{
			if(typeof arguments[0] == "string")
			{
				for(var i=0;i<buffer.length;i++)
				{
					if(arguments[0] == buffer[i]){buffer.splice(i, 1);}
				}
			}
			else
			{
				var index = arguments[0];
				var length = (arguments.length > 1) ? arguments[1] : 1;
				buffer.splice(index,length);
			}
		}
		this.toString = function()
		{
			var str = "";
			for(var i=0;i<buffer.length;i++)
			{
				str += buffer[i];
			}
			return str;
		}
	}
}

HTML

<html>
<head>
	<title></title>
	<script src="StringBuilder.js"></script>
	<script>

		var sb = new String.builder();
		sb.append("hi");
		sb.append("there");
		sb.append(",");
		sb.append(" ");
		sb.append("how");
		sb.append("are");
		sb.append("you");
		sb.append("?");
		//sb.clear();
		//sb.insert(1," there");
		//sb.replace("how","how ");
		//sb.remove("how");
		//sb.remove(4,3);

		alert(sb.toString());

	</script>
</head>
<body>

</body>
</html>