PDA

View Full Version : event listener for browser font size change


percepts
08-20-2006, 04:13 PM
The problem:

I have an XHTML STRICT page which has some event listeners attached for onload and resize. I'm doing a bit of Javascript DHTML on these events. When a user changes the browser font size, the javascipt function needs to run. Although the TOPMENU DIV gets resized when the font changes size, its not a page resize so the function doesn't get run. I fixed this in IE6 by using a second function which is run onload and sets an event on the div object in the page after its been defined.

Problem is this doesn't work in Firefox.

Mozilla DOM reference says there is no resize event on a DIV so is there a work around to make it work in FIREFOX? i.e. can I force a resize event to happen on a div in firefox or is there some other event I can trap when a user changes the browser font size?

here's my js code: topmenu is what I'm trying to trap the resize event from.

this code is loaded in the head of the page.

function maindiv(){
estartup=document.getElementById("startup");
econtain=document.getElementById("contain");
emain=document.getElementById("main");
etopmenu=document.getElementById("topmenu");
emaincontent=document.getElementById("maincontent");
nopx = document.childNodes ? 'px' : 0;
contw = document.body.clientWidth - 80;
conth = document.body.clientHeight - 80;
if (contw < 0) { contw = 0;}
if (conth < 0) { conth = 0;}
econtain.style.width = contw+nopx;
econtain.style.height = conth+nopx;
if (conth >= 100 + etopmenu.clientHeight) {
emain.style.height = (conth - etopmenu.clientHeight - 100 )+nopx;
}
if (contw >= 172) {
emaincontent.style.width = (contw - 172 )+nopx;
}
estartup.style.visibility = 'hidden';
}


function fsize() {
etm=document.getElementById("topmenu");
if (typeof window.addEventListener != 'undefined')
{
etm.addEventListener("resize", maindiv, false);
}
else if (typeof document.addEventListener != 'undefined')
{
etm.addEventListener("resize", maindiv, false);
}
else if (typeof window.attachEvent != 'undefined')
{
etm.attachEvent("onresize", maindiv); }
else
{
window.alert('Failed to attach an Event Listener\n\n Please Report');
}
}

if (typeof window.addEventListener != 'undefined')
{
window.addEventListener("load", maindiv, false);
window.addEventListener("load", fsize, false);
window.addEventListener("resize", maindiv, false);
}
else if (typeof document.addEventListener != 'undefined')
{
document.addEventListener("load", maindiv, false);
document.addEventListener("load", fsize, false);
document.addEventListener("resize", maindiv, false);
}
else if (typeof window.attachEvent != 'undefined')
{
window.attachEvent("onload", maindiv);
window.attachEvent("onload", fsize);
window.attachEvent("onresize", maindiv);
}
else
{
window.alert('Failed to attach an Event Listener\n\n Please Report');
}

Any clues?

thanks

jkd
08-20-2006, 05:25 PM
Mozilla has "overflow" and "underflow" events. I'm not sure if they are exposed beyond XUL box primitives, but it is worth a try nonetheless.

Kor
08-21-2006, 10:42 AM
It is not a direct answer to your question, but wouldn't be easier to use CSS for a liquid design instead of an intricate javascript code?

percepts
08-21-2006, 02:04 PM
I thought I was in a javscript forum:confused:

The problem is not intricate Javascript. The problem is the limitations of the Firefox implementation of the DOM which doesn't fire an on resize event for a div.

Don't make the mistake of assuming that "Standards" are always well conceived.

If you think that code is intricate, take a look AJAX or some of the cms javascript wysiwyg editors.

infact I wanted the code to make the page more fluid without capitualising to the "You will write it this way" ethic of the emerging standards.

brothercake
08-21-2006, 03:49 PM
No, the problem is that IE is misleading you by offering a non-standard event which no other browser makes available.

Anyway ...

What you can do is create a special test div with a known, scaleable width - such as 10em - and position out of the way so it's not seen (position:absolute;left:-10000px).

You can then watch that element on a timer, and when it changes size you know that a text resize has occured.

jkd
08-21-2006, 04:32 PM
No, the problem is that IE is misleading you by offering a non-standard event which no other browser makes available.

Anyway ...

What you can do is create a special test div with a known, scaleable width - such as 10em - and position out of the way so it's not seen (position:absolute;left:-10000px).

You can then watch that element on a timer, and when it changes size you know that a text resize has occured.

Oh, tricksy. :)

Firefox also supports a watch() method, so might be able to do something like:


document.getElementById("textSizeWatch").watch("offsetWidth", function(prop, oldValue, new Value) {
// do something
});


And have it be a little less... flaky? (Polling makes me nervous). Though, it seems Opera doesn't have the watch() method, so... not a great fix.

brothercake
08-21-2006, 04:52 PM
And have it be a little less... flaky? (Polling makes me nervous). Though, it seems Opera doesn't have the watch() method, so... not a great fix.
Sure, polling makes me nervous too, but without a universal watch() method I don't see the alternative ..?

jkd
08-21-2006, 05:52 PM
Sure, polling makes me nervous too, but without a universal watch() method I don't see the alternative ..?

Opera does a page zoom instead of a text zoom, so perhaps Opera it outside the realm of consideration for this problem?

e.g.:
IE can do it via a resize event
Firefox can do it via watch() or possibly onoverflow/onunderflow
Opera doesn't have this scenario
Safari ???

If a solution could be found for Safari, I would consider it adequate. I looked through the WebKit source code, there are no events of interest to facilitate this, though in the interest of compatibility it might fire resize events (I don't know).

Also, both Firefox and Safari normalize computed style measurements to pixel values, so you wouldn't need a hidden div, just a poll on:

document.defaultView.getComputedStyle(document.body, "").getPropertyValue("font-size")

percepts
08-21-2006, 10:23 PM
tried the watch on the div I want to monitor. Watched the offsetHeight which is changed whe the fontsize changes. Can't get it to work.

anyone see what I'm doing wrong?

function fsize() {
window.alert('font size change which causes div offsetHeight change');
}
function fntchange() {
document.getElementById('topmenu').offsetHeight.watch("offsetHeight", function (id, oldval, newval){fsize();});
}

if (typeof window.addEventListener != 'undefined')
{
window.addEventListener("load", fntchange, false);
}

methinks this is only going to work on javascript variables and I can't set that unless I have an event to capture.

or do I need to set a timer to update the javascript variable once in a while?

percepts
08-21-2006, 11:49 PM
sorted!

var lastSize;
if( window.getComputedStyle ) { lastSize = window.getComputedStyle (document.documentElement,"").fontSize;
setInterval(function () {
var sz = window.getComputedStyle(document.documentElement,"").fontSize;
if( sz != lastSize ) {
// do your stuff
lastSize = sz;
}
},500);
}else{
// do your stuff for !window.getComputedStyle (IE)
}

thanks for help

jkd
08-22-2006, 07:01 PM
Use document.defaultView.getComputedStyle instead of window.getComputedStyle. It won't make a difference in Firefox or Opera, but it otherwise won't work in Safari.

percepts
08-23-2006, 04:10 AM
thanks for the pointer. Have changed it but can't test in safari cos I don't have a mac. I'll maybe ask if someone can try it on a mac when its ready to go live.