Dimensiones del viewport y de la página
La información mostrada en esta página ha sido verificada en
Firefox 3.0.1, IE7 y Safari 3.1.2
Antes de empezar: document.compatMode
La propiedad compatMode de document nos permite saber si
estamos trabajando en el modo "Quirks" o en el modo "Strict". Dicha propiedad puede tomar
los siguientes toma los siguientes valores:
|
En "strict mode" |
En "quirks mode" |
| document.compatMode |
CSS1Compat |
BackCompat |
Las referencias a esta propiedad pueden encontrarse en los siguientes enlaces:
http://developer.mozilla.org/En/DOM/Document.compatMode
http://www.opera.com/docs/specs/doctype
http://msdn.microsoft.com/en-us/library/ms533687(VS.85).aspx
Más documentación sobre los modos puede encontrarse en:
http://www.communitymx.com/content/article.cfm?cid=85FEE
http://www.ericmeyeroncss.com/bonus/render-mode.html
ViewportOut
En Firefox, Opera y Safari puede determinarse mediante:
window.innerWidth
window.innerHeight
Para IE7 en modo no estricto
document.documentElement.scrollWidth
document.documentElement.scrollHeight
document.documentElement.offsetWidth
document.documentElement.offsetHeight
document.body.offsetWidth
document.body.offsetHeight
Para IE7 en modo estricto no hay posibilidad directa.
Función
if (window.innerWidth !== undefined) {//ViewportOut
window.viewportOutSize = function(){return {w:window.innerWidth,h:window.innerHeight};}
}
else if (!compat) {//ViewportOut para IE7-Q
window.viewportOutSize = function(){return {w:html.scrollWidth,h:html.scrollHeight};}
}
else {//IE7-S : No tenemos ViewportOut (¿nos conformamos con ViewportIn?)
return null;
}
ViewportIn
En modo estricto
En Firefox, Safari y IE7
document.documentElement.clientWidth
document.documentElement.clientHeight
En Opera no es posible directamente:
document.documentElement.clientWidth
document.documentElement.clientHeight
Nos proporcionan las dimensiones del panel virtual (scroll panel)
document.body.clientWidth
document.body.clientHeight
Nos proporcionan las dimensiones del ViewportOut - 2*(body.margin+body.borderWidth)
En modo no estricto
En Firefox y Safari
document.body.clientWidth
document.body.clientHeight
En IE7: no directamente
document.body.clientWidth
document.body.clientHeight
Nos proporcionan las dimensiones del ViewportOut - 2*(body.borderWidth)
En Opera no es posible directamente:
document.documentElement.clientWidth
document.documentElement.clientHeight
Nos proporcionan ?????
document.body.clientWidth
document.body.clientHeight
Nos proporcionan las dimensiones del ViewportOut - 2*(body.margin+body.borderWidth)
Función
Supongamos que
var compat = (document.compatMode == 'CSS1Compat');
var html = document.documentElement;
var body = document.body;
if (compat) {
window.viewportInSize = function(){return {w:html.clientWidth,h:html.innerHeight};}
}
else {
window.viewportInSize = function(){return {w:body.clientWidth,h:body.clientHeight};}
}
Tendriamos los siguientes errores
Opera-Strict:
Nos proporciona las dimensiones del ScrollPane
Opera-Quirks:
Nos proporciona las dimensiones del ViewportOut - 2*(body.margin+body.borderWidth)
IE7-Quirks
Nos proporciona las dimensiones del ViewportOut - 2*(body.borderWidth)
Panel virtual (ScrollPane)
Llamaremos tamaño de la página a: body.margin+body.border+body.width
Tamaño de la página mayor que el viewportOut
En todos los navegadores y modos, exceptuando IE7 en modo no estricto:
document.documentElement.scrollWidth
document.documentElement.scrollHeight
El pagesize efectivo vendrá dado por
Math.max(document.documentElement.scrollWidth,viewportIn.width)
Sabemos que la implementación simple de viewportIn daría errores en Opera.
Veamos como quedaría:
Opera-Strict:
viewportIn simple nos proporciona las dimensiones del ScrollPane,
en consecuencia seguiriamos con el valor de scrollpane
Opera-Quirks:
viewportIn simple Nos proporciona las dimensiones del
ViewportOut - 2*(body.margin+body.borderWidth)
Parece que la opción más simple es utilizar el viewportOut
En IE7 en modo no estricto
document.documentElement.scrollWidth
document.documentElement.scrollHeight
nos proporcionan el viewportOut
Las dimensiones del body que se hayan especificado son despreciadas.
Se tiene una medida del body height computado mediante el body.scrollHeight
Por tanto para IE7-Q el pagesize efectivo vendrá dado por
Math.max(document.body.scrollWidth,viewportIn.width);
Tendiendo en cuenta que para IE7-Q
viewportIn.width == document.documentElement.scrollWidth
Llegamos a
Math.max(document.body.scrollWidth,document.documentElement.scrollWidth);
Módulo de cálculo 1
(function(){
var compat = (document.compatMode == 'CSS1Compat');
var html = document.documentElement;
var body = document.body;
if (window.innerWidth !== undefined) {//ViewportOut
window.viewportSize = function(){return {w:window.innerWidth,h:window.innerHeight};}
}
else if (!compat) {//ViewportOut para IE7-Q
window.viewportSize = function(){return {w:html.scrollWidth,h:html.scrollHeight};}
}
else {//IE7-S : No tenemos ViewportOut, nos conformamos con ViewportIn
window.viewportSize = function(){ return {w:html.clientWidth,h:html.clientHeight};}
}
if (compat) {
window.pageSize = function(){
var vps = viewportSize();
return {
w: Math.max(html.scrollWidth,vps.w);
h: Math.max(html.scrollHeight,vps.h);
};
}
}
else {
window.pageSize = function(){
return {
w: Math.max(html.scrollWidth, body.scrollWidth);
h: Math.max(html.scrollHeight,body.scrollHeight);
}
}
}
})();
Página menor que el viewport
En este caso el tamaño efectivo de página será el del viewport
Modulo 2
(function(){
...
if (compat) {
window.pageSize = function(){
var vps = viewportSize();
return {
w: Math.max(html.scrollWidth,vps.w);
h: Math.max(html.scrollHeight,vps.h);
};
}
}
else {
window.pageSize = function(){
return {
w: Math.max(html.scrollWidth, body.scrollWidth);
h: Math.max(html.scrollHeight,body.scrollHeight);
}
}
}
})();
Posición de los cursores de las barras de desplazamiento
Determinar la posición de los cursores de las barras de desplazamiento (es decir,
la posición del viewport respecto a la página) es un poco más complicado "por culpa" de Safari.
En Firefox, Opera e IE la posición viene dada por scrollLeft y scrollTop
como propiedades
de document.documentElement en modo estricto y sobre document.body en caso contrario.
Pero desgraciadamente en Safari (al menos en las versiones probadas)
document.documentElement.scrollLeft y document.documentElement.scrollTop
valen cero.
Existe otras propiedades que nos proporcionan la información que estamos buscando:
window.pageXOffset
y
window.pageYOffset, pero desgraciadamente dichas
propiedades no existen en IE. Tendremos que preparar una solución para este problema.
El módulo completo
(function(){
var ve = (document.compatMode == 'CSS1Compat') ?
document.documentElement: document.body;
window.viewportSize = function(){ return {w:ve.clientWidth,h:ve.clientHeight};}
window.pageSize = function(){ return {w:ve.scrollWidth,h:ve.scrollHeight};}
window.scrollPosition =
(window.pageXOffset !== undefined) ?
function(){return {x:window.pageXOffset, y:window.pageYOffset};}:
function(){return {x:ve.scrollLeft, y:ve.scrollTop};};
})();
Un pequeño y típico ejemplo
Pulsando sobre
aquí podremos ver un par de rectángulos
centrados en el viewport.
El código que se ejecuta es el siguiente:
function accion() {
var vs = viewportSize();
makeElement('DIV',
{
backgroundColor:'#ffe0e0',
position:'fixed',
width:'100px',
height:'40px',
left:((vs.w-100)/2)+'px',
top:((vs.h-40)/2)+'px'
},
document.body
);
var sp = scrollPosition();
makeElement('DIV',
{
backgroundColor:'#e0e0e0',
position:'absolute',
width:'80px',
height:'30px',
left:((vs.w-80)/2)+'px',
top:(sp.y+(vs.h-30)/2)+'px'
},
document.body
);
}