DOM event flow

S

Spartanicus

How do I prevent this from executing twice when the window is resized:

window.onresize = function () {
alert('foo');
}

It has to work in Opera, what IE does is of no consequence.
 
N

Neredbojias

How do I prevent this from executing twice when the window is resized:

window.onresize = function () {
alert('foo');
}

It has to work in Opera, what IE does is of no consequence.


onresize=new Function("alert('foo');onresize='';");
 
T

Toby Inkster

Spartanicus said:
How do I prevent this from executing twice when the window is resized:

window.onresize = function () {
alert('foo');
}

function nullfunc () { var x = 1; }
function myOnResize ()
{
alert('foo');
window.onresize = nullfunc;
window.setTimeout('window.onresize = myOnResize;', 1000)
}

or something to that effect.
 
T

Toby Inkster

Toby said:
function nullfunc () { var x = 1; }
function myOnResize ()
{
alert('foo');
window.onresize = nullfunc;
window.setTimeout('window.onresize = myOnResize;', 1000)
}

Missed out "window.onresize = myOnResize;" at the very end.
 
M

Michael Winter

How do I prevent this from executing twice when the window is resized:

window.onresize = function () {
alert('foo');
}

The event is only dispatched to the body element once in Opera, so you
could add the listener there instead.

As the body property of the document object will initially be null, you
have three options:

1. <body onresize="/* ... */">

2. <body>
<script type="text/javascript">
document.body.onresize = function() {
/* ... */
};
</script>

3. <head>
<script type="text/javascript">
this.onload = function() {
document.body.onresize = function() {
/* ... */
};
};
It has to work in Opera, what IE does is of no consequence.

All versions of Opera that dispatch the resize event (from 7.0, onwards)
will act as intended.

Just in case you care: IE will still fire multiple times, and Firefox
only supports the first option (it doesn't dispatch the event to the
body element at all).

Mike
 
M

Michael Winter

On 24/05/2006 08:19, Toby Inkster wrote:

[snip]
function nullfunc () { var x = 1; }

Out of curiosity, why the pointless variable declaration and assignment?
Function bodies can be empty.

[snip]

Mike
 
S

Spartanicus

Michael Winter said:
The event is only dispatched to the body element once in Opera, so you
could add the listener there instead.

As the body property of the document object will initially be null, you
have three options:

1. <body onresize="/* ... */">

2. <body>
<script type="text/javascript">
document.body.onresize = function() {
/* ... */
};
</script>

3. <head>
<script type="text/javascript">
this.onload = function() {
document.body.onresize = function() {
/* ... */
};
};
</script>

Thanks, I used #3.

In trying to take it one step further I'd like the function to execute
only when the window width changes. First I should illustrate what I'm
trying to do.

Opera has a preliminary implementation of CSS3 media queries, this
allows dissolving a multi column layout for narrower window widths.
Currently the CSS media query isn't reevaluated on a window resize, it
requires a reload, so I'm using JS to do that:

http://homepage.ntlworld.com/spartanicus/css_layout.htm

Ideally I'd like the reload only to occur if the viewport width changes.
After a glance in a JS book and not hindered by a proper understanding
of JS & the DOM I tried:

<script type="text/javascript">
window.innerWidth.onresize = function() {
location.reload(false);
};
</script>

But no go, any idea if this refinement is possible?
 
M

Michael Winter

In trying to take it one step further I'd like the function to
execute only when the window width changes.

The code only needs slight modification:

this.onload = function() {
var width = document.body.clientWidth;

document.body.onresize = function() {
if (document.body.clientWidth != width)
location.reload();
};
};
First I should illustrate what I'm trying to do.

Opera has a preliminary implementation of CSS3 media queries, this
allows dissolving a multi column layout for narrower window widths.
Currently the CSS media query isn't reevaluated on a window resize,
it requires a reload [...]

Has that been reported to Opera? I don't know if the query /must/ be
re-evaluated, but it certainly should be.

[snip]
After a glance in a JS book

Based upon informed third-party opinion, most books on scripting are
rubbish, unfortunately. I've never read any myself, but the other
regulars in c.l.javascript can just about recommend "JavaScript: The
Definitive Guide, 4th Edition"[1] (and some may only consider that the
least bad, rather than good).
and not hindered by a proper understanding of JS & the DOM
:)

I tried:

<script type="text/javascript">
window.innerWidth.onresize = function() {
location.reload(false);
};

[snip]

Even if that onresize property persisted (see below), the innerWidth
property is not an element, it would not receive events, and so the
function would never be executed.

<off-topic>
The innerWidth property of the global object is simply a number (where
implemented) and has no members, nor can it be assigned any.

To illustrate the latter point, consider:

var number = 10;

number.property = 'value';
alert(typeof number.property);

The alert will contain 'undefined', not 'string'. The reason is that
only objects have properties. Though one may use methods with
primitives, what goes on behind the scenes is a little complex than it
may otherwise appear. For example,

var message = 'Hello %s!';

alert(message.replace('%s', 'World'));

message is a string primitive, but the code would still display 'Hello
World!'. What is actually happening is that in using dot notation, the
left-hand operand is implicitly converted to an object, similar to:

Object(message).replace(...)

which is equivalent (in this instance) to:

(new String(message)).replace(...)

The same thing occurs when trying to create a property on a primitive,
but because the implicitly created object is only temporary, the new
property disappears along with the object itself.

In the code you posted, a Number object will be created using the
innerWidth property, and a reference to a function object will be
assigned to a new property, onresize. However, because there are no
references to it, this Number object will be marked for garbage
collection, and the function object will soon follow suit.
</>

Hope that helps,
Mike


[1] Recommended books, c.l.javascript FAQ
<http://www.jibbering.com/faq/#FAQ3_1>
 
S

Spartanicus

Michael Winter said:
The code only needs slight modification:

this.onload = function() {
var width = document.body.clientWidth;

document.body.onresize = function() {
if (document.body.clientWidth != width)
location.reload();
};
};

This works when the viewport width is changed up or down by dragging the
right viewport border, but not when a non maximised MDI window is
maximised using the window button, it does work when an MDI window is
"unmaximized". It works when I close Opera's side panel, but not when I
open the panel.
Opera has a preliminary implementation of CSS3 media queries, this
allows dissolving a multi column layout for narrower window widths.
Currently the CSS media query isn't reevaluated on a window resize,
it requires a reload [...]

Has that been reported to Opera? I don't know if the query /must/ be
re-evaluated, but it certainly should be.

I'm not aware of a spec requirement to reevaluate the CSS media query
upon a window resize, nor am I convinced that it should be.
After a glance in a JS book

Based upon informed third-party opinion, most books on scripting are
rubbish, unfortunately. I've never read any myself, but the other
regulars in c.l.javascript can just about recommend "JavaScript: The
Definitive Guide, 4th Edition"[1] (and some may only consider that the
least bad, rather than good).

Being aware of that recommendation it was the first book I looked at,
but it didn't work for me at all. Like most JS books it assumes previous
programming experience, but more importantly, imo it is didactically
poor. "Professional JavaScript for Web Developers" by Nicholas C. Zakas
(Wrox) worked better for me despite the fact that it too assumes
programming experience.

But the main obstacle for me to learn JavaScript is my dislike for what
is typically done with it (I have it disabled by default in my browser),
the rare good uses I see for it, which results in only an occasional
desire to use it.
 
M

Michael Winter

[snip]
this.onload = function() {
var width = document.body.clientWidth;

document.body.onresize = function() {
if (document.body.clientWidth != width)
location.reload();
};
};

This works when the viewport width is changed up or down by dragging the
right viewport border, but not when a non maximised MDI window is
maximised using the window button, it does work when an MDI window is
"unmaximized". It works when I close Opera's side panel, but not when I
open the panel.

Are you absolutely certain of that? I'll admit that I didn't test it
because I forgot that Opera has independent child windows (I always have
them maximised, including pop-ups), but both 7.03 and 8.54 (I didn't
check intervening versions) fire in response to all of those actions,
here. I don't have v9.

[snip]
I'm not aware of a spec requirement to reevaluate the CSS media query
upon a window resize, nor am I convinced that it should be.

If a set of rules are applied only because certain circumstances dictate
that they should be, it would seem logical to reconsider the application
of those rules if the circumstances change. It doesn't make a great deal
of sense to continue to apply rules to a document that is in a viewport
say 50em wide, if it's now 30em wide and some other rule set is more
appropriate.

[snip]
But the main obstacle for me to learn JavaScript is my dislike for what
is typically done with it (I have it disabled by default in my browser),
the rare good uses I see for it, which results in only an occasional
desire to use it.

I can appreciate that, and I most definitely agree that a lot of its use
is poor, and often unnecessary or inappropriate. But, I don't think it
should stand in your way of learning the language.

If you're in no hurry, you might be content to read and post to
c.l.javascript. It is surely the best source of information you'll find
anywhere[1], but a solid understanding of the language will require
quite a lengthy period of involvement. It is deeper than some would like
to make out.

Mike


[1] There are, as ever, people that should be largely ignored
within the group, but they will become obvious fairly
quickly.
 
S

Spartanicus

Michael Winter said:
Are you absolutely certain of that? I'll admit that I didn't test it
because I forgot that Opera has independent child windows (I always have
them maximised, including pop-ups), but both 7.03 and 8.54 (I didn't
check intervening versions) fire in response to all of those actions,
here. I don't have v9.

I tried it with V7, V8 and V9, it behaves as I described on my system.
Here's a temporary copy containing the code, I don't think that I've
made mistakes in copying it:
http://homepage.ntlworld.com/spartanicus/temp.htm

I've replaced the reload with an alert dialog for testing.
If a set of rules are applied only because certain circumstances dictate
that they should be, it would seem logical to reconsider the application
of those rules if the circumstances change. It doesn't make a great deal
of sense to continue to apply rules to a document that is in a viewport
say 50em wide, if it's now 30em wide and some other rule set is more
appropriate.

But there are potentially a fair number of different things that media
queries could be used for, it could be neigh impossible for a browser to
determine what action to take depending on the significant number of
UI actions that a user may initiate. The author coding these functions
on the other hand knows what behaviour is needed, it seems reasonable to
me that the author should also implement the behaviour such as in this
case triggering a reload. After all, dynamic behaviour belongs in the
Javascript domain.
But the main obstacle for me to learn JavaScript is my dislike for what
is typically done with it (I have it disabled by default in my browser),
the rare good uses I see for it, which results in only an occasional
desire to use it.

I can appreciate that, and I most definitely agree that a lot of its use
is poor, and often unnecessary or inappropriate. But, I don't think it
should stand in your way of learning the language.

If you're in no hurry, you might be content to read and post to
c.l.javascript. It is surely the best source of information you'll find
anywhere[1]

I'd gladly agree with that, in the little time that I've spent in
c.l.javascript it was obvious to me that some of it's contributors are
highly skilled people.

The same is true for the areas that I do know something about. The
quality of information in virtually all books on these subjects is not
nearly as good as the information available from the best newsgroup
contributors.
 
M

Michael Winter

On 24/05/2006 18:46, Spartanicus wrote:

[snip]
http://homepage.ntlworld.com/spartanicus/temp.htm

I've replaced the reload with an alert dialog for testing.

That's the source of your problem. Without the reload, the width
variable is never changed. The specific instances where is appears to
fail are special cases because they switch between two exact sizes.

Consider opening the panel. When initially loading, the viewport width
will be 1000px wide, for example. Open the panel, and it's reduced to
say, 800px. At this point, the two widths will compare as unequal,
thereby reloading the document. This reload will set a different value
for the width variable, but as you prevent that, it will remain the
original value of 1000. When hiding the panel, the viewport will enlarge
to its original width of 1000px, so nothing will appear to have
happened. Include both the reload and the alert, and you'll see that
there are no problems.

If it were to important to update the width variable, whether or not the
document is reloaded, the if expression can be changed to:

(width != (width = document.body.clientWidth))

though it's not necessary, here. The change of operand order is
important: the width variable clearly needs to be evaluated before it's
assigned to on the right-hand side.

[snip]
But there are potentially a fair number of different things that
media queries could be used for, it could be neigh impossible for a
browser to determine what action to take depending on the significant
number of UI actions that a user may initiate.

That is a fair point, but how many of these properties will change in
response to specific actions? Resizing the viewport will only affect the
(min/max-) height and width properties. It needn't involve re-evaluating
the entire style sheet, though that is a possibility.

The most awkward to handle is font changes (family or size) as any query
containing an em or ex length value would need to be re-evaluated.
However, it's far from infeasible (though I'd understand why it wouldn't
be the first thing an implementer might concentrate on).
The author coding these functions on the other hand knows what
behaviour is needed, it seems reasonable to me that the author should
also implement the behaviour such as in this case triggering a
reload. After all, dynamic behaviour belongs in the Javascript
domain.

That is also true, but as you and I both know, client-side scripts
should be considered optional features. That notwithstanding, refreshing
the document isn't a particularly nice solution. For simple content,
it's not that big a deal, but it could play havoc with forms and the
like. It would be better for the UA to deal with it as it is the UA that
is providing the feature, not a script.

[snip]

Mike
 
T

Toby Inkster

Michael said:
Out of curiosity, why the pointless variable declaration and assignment?
Function bodies can be empty.

I lose track of what's allowed in what languages.
 
S

Spartanicus

Michael Winter said:
That's the source of your problem.

Indeed it is, thanks for the explanation.
That is a fair point, but how many of these properties will change in
response to specific actions? Resizing the viewport will only affect the
(min/max-) height and width properties. It needn't involve re-evaluating
the entire style sheet, though that is a possibility.

I don't see how re-evaluating all stylesheet rules could be avoided, the
CSS rule(s) to be applied as a result of re-evaluating a media query
could for example cause changes in the cascade.
That is also true, but as you and I both know, client-side scripts
should be considered optional features. That notwithstanding, refreshing
the document isn't a particularly nice solution. For simple content,
it's not that big a deal, but it could play havoc with forms and the
like. It would be better for the UA to deal with it as it is the UA that
is providing the feature, not a script.

Good point, I hadn't considered forms. Another drawback I just noticed
is that it reloads from the server, I thought that I could tell the
browser to reload from it's cache by using "false" as the argument (or
by omitting the argument), but no go.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top