Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

David Mark's Javascript Tip Du Jour - Volume #1 - Tip #1234 - How to Measure Element Dimensions

282 views
Skip to first unread message

David Mark

unread,
Nov 10, 2011, 9:09:29 AM11/10/11
to
How to Measure Element Dimensions

Typically these functions fall into three categories: call them
getOuterDimensions, getInnerDimensions, and getCssDimensions. The
first two refer to the size outside and inside the border respectively
and the last the CSS dimensions (per the box model).

The first two have just one rendition each. With simplified feature
detection*:-

if (document.documentElement && typeof
document.documentElement.offsetWidth == 'number') {
var getOuterDimensions = function(el) {
return [el.offsetHeight, el.offsetWidth];
};
}


if (document.documentElement && typeof
document.documentElement.clientWidth == 'number') {
var getInnerDimensions = function(el) {
return [el.clientHeight, el.clientWidth];
};
}

Those never change. They work even in IE 4. Due to the host feature
detection and conditional creation of these functions, applications
that do proper API feature detection will degrade gracefully in IE 3.
Of course, if the application's script has a try-catch, the
degradation path for IE 4 and under is a parse error.

As for getCssDimensions, a GP solution may (and often does) use
getComputedStyle, but unfortunately that method has been notoriously
buggy over the years and the older versions of IE (under 9) don't
support it at all. You could try to string together a bunch of hacks
to emulate getComputedStyle with IE's various proprietary objects, but
it's a fool's errand.

Here is a relatively slow solution that works for all box models in
"all browsers":-

http://www.cinsoft.net/size.html

As with virtually everything in cross-browser scripting, defining a
specific context is the key to creating a reliable function.

What if the design decision was made to measure only elements with the
border-box box model? Then you could do this:-

var getCssDimensions = getOuterDimensions;

Unfortunately, that is an inappropriate solution for most contexts as
many browsers do not support that box model. For example, IE 5-8 will
do it only in quirks mode (which is always best avoided).

What if the design decision was made to measure only elements with the
content-box box model *and* without padding? Then you could do this:-

var getCssDimensions = getInnerDimensions;

This is an excellent (and relatively fast) solution as the default for
virtually every element in virtually every modern browser is content-
box. When designing an application's widgets, simply take care to only
measure elements without padding. It's not hard to do and the payoff
is a fast, concise and cross-browser solution. Just make sure to
document the context as the documentation is as much a part of the
rendition as the code.

How *Not* to Measure Element Dimensions

And what of the jQuery height/width functions? They don't work at all
for border-box. They also rely on getComputedStyle (or a long-winded,
over-complicated simulation). It's the worst of both worlds; also
confusing, relatively slow, poorly documented, failure-prone and
subject to change at any time on a whim. That's what *defines* jQuery
(and the like). In its favor... uh, lots of Web developers use it to
churn out horrible Websites.

To borrow a term from the jQuery fanboy resistance/marketing
department: does this sound like FUD to you? I think you should
certainly be afraid of such doubtful material as jQuery, at least
until you understand the employed techniques well enough to avoid it
for rational reasons. Fear of the unknown can be healthy and most
jQuery users have no idea what it does.

http://en.wikipedia.org/wiki/Cargo_cult_programming

* Use isHostObjectProperty (or the like) to detect
document.documentElement

http://www.cinsoft.net/
http://www.twitter.com/cinsoft
http://jsperf.com/browse/david-mark

J.R.

unread,
Nov 10, 2011, 1:57:35 PM11/10/11
to
On 10/11/2011 12:09, David Mark wrote:
> How to Measure Element Dimensions
>
> Typically these functions fall into three categories: call them
> getOuterDimensions, getInnerDimensions, and getCssDimensions. The
> first two refer to the size outside and inside the border respectively
> and the last the CSS dimensions (per the box model).
>
> The first two have just one rendition each. With simplified feature
> detection*:-
>
> if (document.documentElement&& typeof
> document.documentElement.offsetWidth == 'number') {
> var getOuterDimensions = function(el) {
> return [el.offsetHeight, el.offsetWidth];
> };
> }
>
>
> if (document.documentElement&& typeof
> document.documentElement.clientWidth == 'number') {
> var getInnerDimensions = function(el) {
> return [el.clientHeight, el.clientWidth];
> };
> }
>

I've learned that you've posted a simplified version of the code
available on "My Library". So I think it's necessary to remark that in
IE the HTML element (document.documentElement) is used for the
viewport in "standards mode" (also known as "strict mode") and the body
(document.body) is used in "quirks mode" (HTML is not rendered -
document is displayed as it was displayed in previous versions of IE).

Therefore document.documentElement.clientHeight (in strict mode) may
output a slightly different value from document.body.clientHeight (in
quirks mode).

I've also noticed that you have taken care of those differences at
<http://www.cinsoft.net/viewport.asp>.

--
Joao Rodrigues (J.R.)

Ant

unread,
Nov 10, 2011, 2:47:35 PM11/10/11
to
"David Mark" wrote:

> http://en.wikipedia.org/wiki/Cargo_cult_programming

"Cargo cult programming is a style of computer programming that is
characterized by the ritual inclusion of code or program structures
that serve no real purpose".

Why would anyone do that? In my 30+ years of programming I've never
heard of such a thing. Maybe it's a modern phenomenon like jQuery or
"social networking" that the young 'uns like to engage in. Probably I
should get out more (now that I've retired I can).


David Mark

unread,
Nov 10, 2011, 2:54:39 PM11/10/11
to
On Nov 10, 1:57 pm, "J.R." <groups_j...@yahoo.com.br> wrote:
> On 10/11/2011 12:09, David Mark wrote:
>
>
>
>
>
>
>
>
>
> > How to Measure Element Dimensions
>
> > Typically these functions fall into three categories: call them
> > getOuterDimensions, getInnerDimensions, and getCssDimensions. The
> > first two refer to the size outside and inside the border respectively
> > and the last the CSS dimensions (per the box model).
>
> > The first two have just one rendition each. With simplified feature
> > detection*:-
>
> > if (document.documentElement&&  typeof
> > document.documentElement.offsetWidth == 'number') {
> >    var getOuterDimensions = function(el) {
> >      return [el.offsetHeight, el.offsetWidth];
> >    };
> > }
>
> > if (document.documentElement&&  typeof
> > document.documentElement.clientWidth == 'number') {
> >    var getInnerDimensions = function(el) {
> >      return [el.clientHeight, el.clientWidth];
> >    };
> > }
>
> I've learned that you've posted a simplified version of the code
> available on "My Library". So I think it's necessary to remark that in
> IE the HTML element (document.documentElement) is used for the
> viewport in "standards mode" (also known as "strict mode") and the body
> (document.body) is used in "quirks mode" (HTML is not rendered -
> document is displayed as it was displayed in previous versions of IE).

Which code? The Viewport primer?

>
> Therefore document.documentElement.clientHeight (in strict mode) may
> output a slightly different value from document.body.clientHeight (in
> quirks mode).

Yes, they may. For example, if the body has a margin.

>
> I've also noticed that you have taken care of those differences at
> <http://www.cinsoft.net/viewport.asp>.

Right.

Just checked MSDN and the offending "community content" entry that I
had noted a while back is gone. Basically it warned against using the
clientHeight property because it was "broken" (i.e. returned different
values in different rendering modes). :)

David Mark

unread,
Nov 10, 2011, 4:07:57 PM11/10/11
to
On Nov 10, 2:47 pm, "Ant" <n...@home.today> wrote:
> "David Mark" wrote:
> >http://en.wikipedia.org/wiki/Cargo_cult_programming
>
> "Cargo cult programming is a style of computer programming that is
>  characterized by the ritual inclusion of code or program structures
>  that serve no real purpose".
>
> Why would anyone do that?

Only possible reason is that they don't know they are doing it. ;)

> In my 30+ years of programming I've never
> heard of such a thing.

Well, as a theory it goes way back. In reality, it's a recent (and
troubling) phenomenon.

> Maybe it's a modern phenomenon like jQuery or
> "social networking" that the young 'uns like to engage in.

Yes, exactly like jQuery and on more than one level. The jQuery
project itself is certainly a cargo cult effort. It's locked in a
design from 2005 that was just as inappropriate for browser scripting
then as now. And yes, many of their "innovations" over the years have
been the result of copying patterns without really understanding what
they were doing.

jQuery 1.3 was their attempt to replicate my shiny feature testing
patterns with JS equivalent of bamboo and vines. More recently there
was the attr/prop overhaul. After years of telling them two things:-

1. Your attr method makes no sense and is causing a lot of confusion
2. Here's some realistic prop and attr examples, but it's not the
exact solution for your needs

...they went ahead and split their most low-level DOM API to attr/
removeAttr and prop/removeProp (almost but not entirely like my
examples and almost entirely unlike previous jQuery versions). So
eventually #1 got through, but #2 only partially.

http://www.cinsoft.net/attributes.html

They also kinda-sorta rolled back those changes in a later version.
The details are unclear at this time and will likely remain so. :(

But for those who cry out that I am not helping them (which is ironic
as I'm one of the few people who ever tried to help them with this
mess). For the umpteenth time, the solution to their "attr" problem
is simple. First you have to define what "attr" is supposed to do.
To this date, the documentation has never been close to right about
any of its half-dozen incarnations. In an HTML* DOM, the "attr"
method gets/sets property values by attribute name. In an XML DOM, it
gets/sets attribute values by attribute name. That "overloading" is
unfortunate, but jQuery is stuck with it at this point.

1. Fix the attr method so that it is at least consistent in the "core
browsers"
2. Deprecate removeAttr (it's just confusing as it doesn't go with
attr).
3. As companion to form control value getter/setter, add a "checker"
for checkbox/radio buttons

The jQuery users don't need a pure attribute getter/setter; and, as
predicted, they don't want one. Same for removing attributes (or God
forbid properties). The underlying query engine is another story. To
support legacy IE versions (and compatibility modes), it must have
such a function, but never has (and apparently never will). Probably
doesn't matter as I expect them to stop "caring" about legacy IE any
day now.

I think I've posted more than my share of attribute/property-related
examples over the years, so step 1 should not be a problem for anyone
inclined to fix the silly thing. The other two take almost no thought
or effort at all.

Finally, jQuery users include it in documents as a rule, regardless of
context or other considerations and often doing more harm than good.
That's also cargo cult behavior.

* Would hold true in an XHTML DOM as well if jQuery worked in an XHTML
DOM

Matt McDonald

unread,
Nov 10, 2011, 4:12:12 PM11/10/11
to
On 11-11-10 12:47 PM, Ant wrote:
> Why would anyone do that? In my 30+ years of programming I've never
> heard of such a thing. Maybe it's a modern phenomenon like jQuery or
> "social networking" that the young 'uns like to engage in. Probably I
> should get out more (now that I've retired I can).

As a "young 'un", I can tell you that it's a phenomenon
propped up by the "best practices" methodology.

"best practices" (sounds terrible when you read it aloud)
is an arguably dogmatic set of beliefs and observations
pertaining to a particular programming topic. The crux of
"best practices" is that it's how "popular" programmers
(in that particular field) operate. For example,
"HTML 5 Boilerplate" is a massive set of server
configurations, CSS file(s) ("normalizing", they call it),
JavaScript files (including jQuery & modernizr, neither of which
have any particular use to me), and other assorted bits.

The belief is that when one is to build an "HTML 5" website
(fallacy alert: appeal to popularity) that one must utilize
"HTML 5 Boilerplate". Why? Simply because the "popular" developers
are using it. Supposedly, it also has countless hours of research
behind it. Anyone who has read this group for an extended period
of time knows that "research" isn't always indicative of code
quality (hat tip to jQuery, YUI, Dojo, et al).

Since HTML 5 *still* doesn't have sufficient support (hopes
are with IE 10) to be considered "implemented", one has to
wonder just how a massive amalgam of resources can make websites
"just work". At least in this case, users have a decision to trash
what they consider unnecessary (unlike jQuery).

For the majority of users, this is simply overkill.
Ritualistically including code hinders the learning process
involved with programming. There's little potential to improve
one's knowledge of a topic by slapping on a copy-pasted
solution, especially if it's poorly written (which is common).

The biggest blow is marketing. Take a gander at
"HTML 5 Boilerplate"'s website (won't link). It's chock full of
over-the-top marketing speak. The first time I read it, I was
heavily offended by the textual content. I seriously pondered
if it was written by a prepubescent.

Web development is in vogue. People want to create "cool"
projects, but are dismayed by the amount of effort and research
required to create something meaningful. The solution? Abdicate
responsibility to those who have already "done the research".
That's why "frameworks" and "libraries" have sprung up like
weeds in the past half-decade or so.

It is by this type of behavior that "cargo cult programming"
is characterized. My opinion is that it's one of the prime evils
currently in web development (along with overconfidence).

Gene Wirchenko

unread,
Nov 10, 2011, 4:17:49 PM11/10/11
to
It is not new, but it is much more likely when people do not
understand the details. Sometimes, it is something that works, but it
is not known why. Such a thing then tends to be dragged along into
other areas where it may not be relevant.

Sincerely,

Gene Wirchenko

Evertjan.

unread,
Nov 10, 2011, 5:43:32 PM11/10/11
to
Ant wrote on 10 nov 2011 in comp.lang.javascript:

> "David Mark" wrote:
>
>> http://en.wikipedia.org/wiki/Cargo_cult_programming
>
> "Cargo cult programming is a style of computer programming that is
> characterized by the ritual inclusion of code or program structures
> that serve no real purpose".

If it is ".. seems to serve .." it is a perfect definition of DNA.

> Why would anyone do that? In my 30+ years of programming I've never
> heard of such a thing. Maybe it's a modern phenomenon like jQuery or
> "social networking" that the young 'uns like to engage in. Probably I
> should get out more (now that I've retired I can).


--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Richard Cornford

unread,
Nov 10, 2011, 7:36:57 PM11/10/11
to
Ant wrote:
> "David Mark" wrote:
>
>> http://en.wikipedia.org/wiki/Cargo_cult_programming
>
> "Cargo cult programming is a style of computer programming that is
> characterized by the ritual inclusion of code or program structures
> that serve no real purpose".
>
> Why would anyone do that?

There are lots of reasons why someone would do that. A better question
is would someone who understood what they were doing ever do that?

> In my 30+ years of programming I've never
> heard of such a thing.

Welcome to the low entry cost world of browser scripting.

So, an illustration, but which one? Try this, go to
<URL: http://www.google.com/codesearch >
and in the search box at the top of the page enter the following line:-

typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|') lang:javascript

- and do the search. It gets 4,000+ results (including from a
cross-section of 'popular' libraries) along the lines of:-

if ( typeof a != "array" )

- so what does that do? Well in javascript (as clearly stated in the
language specification (ECMA 262)) the - typeof - operator applied to
any primitive value, native or built-in object (which includes all of
javascript's arrays) may not ever result in the string value "array"
(the entire list of possibilities does not include the sting "array").
Host object (the objects provided by the browser) may result in any
string value, but to date the only value that has ever been observed to
result from applying the - typeof - operator to a host object that is
not in the list of possible values that applies to normal javascript
objects is the string 'unknown'. That is - typeof a - will _always_ not
equal "array", and the example code above is the equivalent of - if
(true) -, which is pointless, but there it sits regardless.

Why is it there? Because someone wrote it and it didn't make anything
any worse. Why was it repeated in numerous other scripts? Because other
people mistook it for an example of code written by someone who knew
what they were doing, and so for a valid/meaningful/useful test.

> Maybe it's a modern phenomenon like jQuery or
> "social networking" that the young 'uns like to engage in.
> Probably I should get out more (now that I've retired I can).


With javascript this phenomenon is about as old as the language, though
the form seems to change a little over time.

Richard.

Gene Wirchenko

unread,
Nov 10, 2011, 10:14:21 PM11/10/11
to
On Fri, 11 Nov 2011 00:36:57 -0000, "Richard Cornford"
<Ric...@litotes.demon.co.uk> wrote:

[snip]

>So, an illustration, but which one? Try this, go to
><URL: http://www.google.com/codesearch >
>and in the search box at the top of the page enter the following line:-
>
>typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|') lang:javascript
>
>- and do the search. It gets 4,000+ results (including from a

I got 5500.

>cross-section of 'popular' libraries) along the lines of:-
>
>if ( typeof a != "array" )
>
>- so what does that do? Well in javascript (as clearly stated in the
[snip]
>objects is the string 'unknown'. That is - typeof a - will _always_ not
>equal "array", and the example code above is the equivalent of - if
>(true) -, which is pointless, but there it sits regardless.
>
>Why is it there? Because someone wrote it and it didn't make anything
>any worse. Why was it repeated in numerous other scripts? Because other

Also, later programmers might not know and think, "I do not know
what it does, but removing it might break the code." Another
possibility is that it might be thought to work that way with old
versions of the language.

At the point I am in JavaScript, I would not catch the error. I
might eventually since any code that I do not understand tends to
stick my attention. But I might not have time to get to it.

>people mistook it for an example of code written by someone who knew
>what they were doing, and so for a valid/meaningful/useful test.

A beautiful example of ugliness.

[snip]

Sincerely,

Gene Wirchenko

Richard Cornford

unread,
Nov 11, 2011, 4:59:56 AM11/11/11
to
Gene Wirchenko wrote:
> Cornford wrote:
> [snip]
>> So, an illustration, but which one? Try this, go to
>> <URL: http://www.google.com/codesearch >
>> and in the search box at the top of the page enter the following
>> line:-
>>
>>typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|')
>>lang:javascript
>>
>> - and do the search. It gets 4,000+ results (including from a
>
> I got 5500.

Yes, it varies (it's Google). But there are a few examples that the
regular expression picks up that not necessarily examples of this
mistake. e.g. The results of calls to functions that have "tyepof" at
the end of their name being compared with the string 'array', where you
don't know whether the function called uses the - typeof - operator at
all.

>> cross-section of 'popular' libraries) along the lines of:-
>>
>> if ( typeof a != "array" )
>>
>> - so what does that do? Well in javascript (as clearly stated
>> in the
> [snip]
>> objects is the string 'unknown'. That is - typeof a - will
>> _always_ not equal "array", and the example code above is the
>> equivalent of - if (true) -, which is pointless, but there it
>> sits regardless.
>>
>> Why is it there? Because someone wrote it and it didn't make
>> anything any worse. Why was it repeated in numerous other
>> scripts? Because other
>
> Also, later programmers might not know and think, "I do not
> know what it does, but removing it might break the code."

That is a reason for not removing that structure from code where it
appears. It could not explain how the structure moves from project to
project, and without that it could not qualify as cargo cult
programming. (It is not a mystical incantation if it is not re-chanted
in the face of the next unknown)

> Another possibility is that it might be thought to work that
> way with old versions of the language.

Possibly, but it would be possible to check the older specs and observe
that it should never have 'worked'. Older versions of browsers would be
a better excuse, but not when it is found in code that is only designed
to be supported by a known sub-set of 'current' browsers, as is the case
with the 'popular' libraries that have featured this code.

> At the point I am in JavaScript, I would not catch the
> error. I might eventually since any code that I do not
> understand tends to stick my attention.

But at this point would you be publishing your code for use by the
general (web-programming) public, claiming its inherent superiority to
alternatives, pronouncing it as a demonstration of your abilities, and
writing/selling javascript programming books off the back of it?

> But I might not have time to get to it.

Yes, mistakes are often time consuming and inconvenient to reverse.
That suggests limiting the scope of your early work, and learning from
the mistakes before propagating the code to the rest of the world.

>> people mistook it for an example of code written by someone who knew
>> what they were doing, and so for a valid/meaningful/useful test.
>
> A beautiful example of ugliness.

I don't know about "ugliness". Code-wise it is very similar to much that
is justified, correct and sensible, which is probably one factor in
preventing it from standing out as something that should have been
questioned.

Richard.

Hans-Georg Michna

unread,
Nov 11, 2011, 8:39:53 AM11/11/11
to
On Thu, 10 Nov 2011 19:14:21 -0800, Gene Wirchenko wrote:

>On Fri, 11 Nov 2011 00:36:57 -0000, "Richard Cornford"
><Ric...@litotes.demon.co.uk> wrote:

>[snip]

>>So, an illustration, but which one? Try this, go to
>><URL: http://www.google.com/codesearch >
>>and in the search box at the top of the page enter the following line:-
>>
>>typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|') lang:javascript
>>
>>- and do the search. It gets 4,000+ results (including from a

> I got 5500.

It's growing! It's growing!

(:-)

Hans-Georg

David Mark

unread,
Nov 11, 2011, 10:26:02 AM11/11/11
to
Yes, these things are all about marketing, which is ironic considering
that they are the first ones to cry (and I do mean cry) carpetbagger
at the first sign of criticism. How many times have I heard "you are
just jealous of our library" or "you are just trashing our library to
promote yours" out of the mouths of (seemingly) petulant tweens? Of
course, many of them turn out to be adults whose brains have been
destroyed by too many television commercials. They'll take warm,
glossy ad copy over cold, dull facts any day. Anybody trying to
"sell" them with reasoned arguments is just trying to make them look
stupid. They'd apparently much rather be made fools of daily by
disingenuous marketers. ;)

The face of Javascript libraries is a pinched, frustrated visage,
spewing hatred and PKB insinuations at all who dare to question
"established" best practices. From the history of these things, it's
clear they are very frustrated; but when their users join in blaming
the "self-promoting" messenger, you know you are dealing with a cult.

>
> Web development is in vogue. People want to create "cool"
> projects, but are dismayed by the amount of effort and research
> required to create something meaningful. The solution? Abdicate
> responsibility to those who have already "done the research".
> That's why "frameworks" and "libraries" have sprung up like
> weeds in the past half-decade or so.

Yes, and when it comes to JS, they all look alike to me (probably
because they are constantly copying each other). Bad is bad, no
matter how "cool" these things may seem to overwhelmed beginners.
Unfortunately, it is relatively easy to write scripts that seem to
work in the developers' array of browsers/configurations. This leads
to the next stage, which is overconfidence.

>
> It is by this type of behavior that "cargo cult programming"
> is characterized. My opinion is that it's one of the prime evils
> currently in web development (along with overconfidence).

My thoughts exactly.

Gene Wirchenko

unread,
Nov 11, 2011, 2:04:24 PM11/11/11
to
On Fri, 11 Nov 2011 09:59:56 -0000, "Richard Cornford"
<Ric...@litotes.demon.co.uk> wrote:

>Gene Wirchenko wrote:

[snip]

>> Another possibility is that it might be thought to work that
>> way with old versions of the language.
>
>Possibly, but it would be possible to check the older specs and observe
>that it should never have 'worked'. Older versions of browsers would be
>a better excuse, but not when it is found in code that is only designed
>to be supported by a known sub-set of 'current' browsers, as is the case
>with the 'popular' libraries that have featured this code.

Is it worth the time? It can be rather time-consuming to track
such things down. Cost-benefit analysis may lead to "Meh. Why
bother?"

>> At the point I am in JavaScript, I would not catch the
>> error. I might eventually since any code that I do not
>> understand tends to stick my attention.
>
>But at this point would you be publishing your code for use by the
>general (web-programming) public, claiming its inherent superiority to
>alternatives, pronouncing it as a demonstration of your abilities, and
>writing/selling javascript programming books off the back of it?

No. Even if I had very polished code, I might not even do it
even then.

>> But I might not have time to get to it.
>
>Yes, mistakes are often time consuming and inconvenient to reverse.
>That suggests limiting the scope of your early work, and learning from
>the mistakes before propagating the code to the rest of the world.

Oh, sure. Bring logic into it!

>>> people mistook it for an example of code written by someone who knew
>>> what they were doing, and so for a valid/meaningful/useful test.
>>
>> A beautiful example of ugliness.
>
>I don't know about "ugliness". Code-wise it is very similar to much that
>is justified, correct and sensible, which is probably one factor in
>preventing it from standing out as something that should have been
>questioned.

Extra verbiage that does nothing useful is ugly by my sense of
aesthetics.

Yes to your second sentence. A favourite quote of mine: "There
are two ways of constructing a software design: One way is to make it
so simple that there are obviously no deficiencies, and the other way
is to make it so complicated that there are no obvious deficiencies.
The first method is far more difficult." -- C.A.R. Hoare

Sincerely,

Gene Wirchenko

Dr J R Stockton

unread,
Nov 11, 2011, 4:33:45 PM11/11/11
to
In comp.lang.javascript message <bd12b66f-33f5-43d2-8e22-6f81b42c3d8b@n1
4g2000vbn.googlegroups.com>, Thu, 10 Nov 2011 06:09:29, David Mark
<dmark....@gmail.com> posted:

>How to Measure Element Dimensions

It could be useful if there were, linked from within each posted Tip, a
Web Index of Tips, linking to Web copies.

One Tip might be the answer to "I have an on-screen element, of known
size, with an on[dbl]click method; how do I obtain the co-ordinates of a
[double-]click with respect to a given position in the element itself?"

The aforementioned index page could have a feedback form, partly for
suggesting topics for tips and possible answers. The latter, when
imperfect, would provide fodder for further Tips, of course.

In what appears to be the cinsoft home page, "By" should be "To".

Consider a page, <http://www.cinsoft.net/position.html>, which has been
found by a serendipitous Google search for "starting point for a move
animation" or otherwise. It recommends
o = getElementPositionStyles(el);
- and that does not work. The necessary further information is not
clearly provided; indeed, the page seems to have no <a href="...">Home
Page</a>.

--
(c) John Stockton, nr London UK. replyYYWW merlyn demon co uk Turnpike 6.05.
Web <http://www.uwasa.fi/~ts/http/tsfaq.html> -> Timo Salmi: Usenet Q&A.
Web <http://www.merlyn.demon.co.uk/news-use.htm> : about usage of News.
No Encoding. Quotes precede replies. Snip well. Write clearly. Mail no News.

Hans-Georg Michna

unread,
Nov 12, 2011, 4:38:48 AM11/12/11
to
On Fri, 11 Nov 2011 00:36:57 -0000, Richard Cornford wrote:

>Welcome to the low entry cost world of browser scripting.
>
>So, an illustration, but which one? Try this, go to
><URL: http://www.google.com/codesearch >
>and in the search box at the top of the page enter the following line:-
>
>typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|') lang:javascript
>
>- and do the search. It gets 4,000+ results (including from a
>cross-section of 'popular' libraries) along the lines of:-

Nice! I just got 19,000+ hits. Strange that it varies so much.

Anyway, do you have more examples? These would be good demos of
the general ignorance towards correct JavaScript programming.
Good for demos.

Hans-Georg

Richard Cornford

unread,
Nov 12, 2011, 2:19:45 PM11/12/11
to
Hans-Georg Michna wrote:
> On Fri, 11 Nov 2011 00:36:57 -0000, Richard Cornford wrote:
>
>>Welcome to the low entry cost world of browser scripting.
>>
>>So, an illustration, but which one? Try this, go to
>><URL: http://www.google.com/codesearch >
>>and in the search box at the top of the page enter the following
>>line:-
>>
>>typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|')
>>lang:javascript
>>
>>- and do the search. It gets 4,000+ results (including from
>> a cross-section of 'popular' libraries) along the lines of:-
>
> Nice! I just got 19,000+ hits. Strange that it varies so much.

Google don't have the best of records when it comes to programming
adding up, so varying result counts shouldn't be too unexpected. On the
other hand, back in 2009 when I last posted about using Google's code
search to look for this code (using the same regular expression) the
number of hits were coming up at around 2,000. So it does appear that
this particular cargo cult programming example is still propagating
(even if the worst offenders have since learnt enough to drop it).

> Anyway, do you have more examples? These would be good demos of
> the general ignorance towards correct JavaScript programming.
> Good for demos.

The other example that is common enough, and sufficiently distinct, that
Google's code search will turn up examples would be found with the
search expression:-

<scr("|')\+("|')ipt lang:javascript

- of which a representative example (from an old dojo version, and
re-wrapped for posting) is:-

document.write(
"<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>"
);

The cargo-cult programming structure is the first (left-most) string
concatenation operation. The final (right-most) string concatenation
operation has some justification in some contexts. Its use in those
contexts demonstrates a shallow understanding of the reasons for its use
(as there are more efficient, shorter and more formally correct
alternatives), and it was almost certainly that shallow understanding
that inspired the real cargo-cult structure to the left. However, One
context where the final (right-most) concatenation is purposeless is
when it is found in an imported JS file, which is of course where
Google's code search is finding it. So that too is pushing cargo-cult
programming in the contexts where it is being found above.

Richard.

Eric Bednarz

unread,
Nov 12, 2011, 3:07:22 PM11/12/11
to
"Richard Cornford" <Ric...@litotes.demon.co.uk> writes:

> document.write(
> "<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>"
> );
>
> The cargo-cult programming structure is the first (left-most) string
> concatenation operation. The final (right-most) string concatenation
> operation has some justification in some contexts. Its use in those
> contexts demonstrates a shallow understanding of the reasons for its
> use (as there are more efficient, shorter and more formally correct
> alternatives), and it was almost certainly that shallow understanding
> that inspired the real cargo-cult structure to the left. However, One
> context where the final (right-most) concatenation is purposeless is
> when it is found in an imported JS file, which is of course where
> Google's code search is finding it. So that too is pushing cargo-cult
> programming in the contexts where it is being found above.

I’m getting the impression that you think that the purpose of splitting
and concatenating the generic identifier is somehow related to escaping
the ETAGO delimiter (‘</’), while it is much more likely to be related
to Norton ‘Internet Security’ inserting it’s dreaded SymError function
after the first instance of anything that looks like the start tag of a
script element (and ususally messing things up in the process).

RobG

unread,
Nov 12, 2011, 5:29:54 PM11/12/11
to
One that is specific to jQuery is the use, usually within a listener, of
the expression:

$(this).val()

Searching at Google code search with:

\$\(this\)\.val\(\) lang:javascript

returns over 5,000 hits.


--
Rob

Thomas 'PointedEars' Lahn

unread,
Nov 12, 2011, 6:42:52 PM11/12/11
to
Suppose that was the case, then it would be a Bad Idea to work around that.
Either it is a bug in Norton InSecurity, then working around it will help to
keep it forever, having everyone to jump forever through the hoops that
Symantec's incompetent, greedy developers once set up. Or it is a feature,
then one would ignore the user's wishes, which is always a bad idea.


PointedEars
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300...@news.demon.co.uk> (2004)

J.R.

unread,
Nov 12, 2011, 9:06:50 PM11/12/11
to
On 10/11/2011 12:09, David Mark wrote:

> if (document.documentElement&& typeof
> document.documentElement.clientWidth == 'number') {
> var getInnerDimensions = function(el) {
> return [el.clientHeight, el.clientWidth];
> };
> }
>

Considering an element having scrollbars, we might use:

return [el.scrollTop + el.clientHeight,
el.scrollLeft + el.clientWidth];

Note: scrollWidth/scrollHeight are buggy in IE6-8 and Opera 10. So, we'd
need to compare (scrollTop + clientHeight) to scrollHeight too. In IE8,
scrollWidth is 5 pixels off. See
<http://www.quirksmode.org/dom/w3c_cssom.html>

--
Joao Rodrigues (J.R.)

Thomas 'PointedEars' Lahn

unread,
Nov 12, 2011, 10:31:57 PM11/12/11
to
J.R. wrote:

> On 10/11/2011 12:09, David Mark wrote:
>> if (document.documentElement&& typeof
>> document.documentElement.clientWidth == 'number') {
>> var getInnerDimensions = function(el) {
>> return [el.clientHeight, el.clientWidth];
>> };
>> }
>>
>
> Considering an element having scrollbars, we might use:
>
> return [el.scrollTop + el.clientHeight,
> el.scrollLeft + el.clientWidth];

Please explain what the scroll position has to do with the element
dimensions.

> Note: scrollWidth/scrollHeight are buggy in IE6-8 and Opera 10
>
> So, we'd need to compare (scrollTop + clientHeight) to scrollHeight too.
> In IE8, scrollWidth is 5 pixels off. See
> <http://www.quirksmode.org/dom/w3c_cssom.html>

That states that *scrollHeight* is buggy in IE *5.5* to 7, and that
scrollWidth is _correct_ in those versions. It also states that scrollWidth
is 5 pixel off in IE 8, and that "Opera gives odd, incorrect values." Quite
different from what you stated.


PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann

Jukka K. Korpela

unread,
Nov 13, 2011, 3:38:11 AM11/13/11
to
2011-11-12 11:38, Hans-Georg Michna wrote:

>> typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|') lang:javascript
>>
>> - and do the search. It gets 4,000+ results (including from a
>> cross-section of 'popular' libraries) along the lines of:-
>
> Nice! I just got 19,000+ hits. Strange that it varies so much.

And I got alternatingly 2,900 or 2,667.

It's not that strange that it varies. The common Google search is known
to give varying results depending on Google server used (e.g.
www.google.com vs. www.google.de), language settings, Google
customization options, cookies (carrying e.g. information about past
searches), browser and the request headers it sends, and possibly phase
of the moon. There is most probably intentional randomization, too, due
to Google testing new functionality or just carrying out A/B testing or
something similar.

Google code search may have any of these causes of variation, and maybe
some more too.

Moreover, the figures that Google tells us are, well, just figures it
tells us. They probably reflect some internal hit counts. But if you try
scan through the results, clicking on the last of the results page
number in the list at the bottom, you may observe that the hit count
drops at some point. In my test in this case, page 19 said
"Results 181 - 190 of 2,665"
but clicking on "Next" led to
"Your search - typeof\s*\(?\s*[\S]+\s*\)?\s*(!|=)==?\s*("|')array("|')
lang:javascript - did not match any documents."

In the common Google search, it seems that at some point, Google set an
upper limit of 999 on the number of hits it actually shows to the user.
That is, when the user proceeds from one hit page to the next, or takes
a shortcut via the page number links, Google stops showing results at
some point, apparently so that in no circumstances can you go past
result 999. So the count that it initially gives can be just about
anything. I don't think it's completely arbitrary, but it surely isn't a
reliable count of anything.

--
Yucca, http://www.cs.tut.fi/~jkorpela/

Richard Cornford

unread,
Nov 13, 2011, 9:33:28 AM11/13/11
to
Eric Bednarz wrote:
> Richard Cornford writes:
>
>> document.write(
>> "<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>"
>> );
>>
>> The cargo-cult programming structure is the first (left-most)
>> string concatenation operation. The final (right-most) string
>> concatenation operation has some justification in some contexts.
>> Its use in those contexts demonstrates a shallow understanding
>> of the reasons for its use (as there are more efficient, shorter
>> and more formally correct alternatives), and it was almost
>> certainly that shallow understanding that inspired the real
>> cargo-cult structure to the left. However, One context where
>> the final (right-most) concatenation is purposeless is when it
>> is found in an imported JS file, which is of course where
>> Google's code search is finding it. So that too is pushing
>> cargo-cult programming in the contexts where it is being found
>> above.
>
> I’m getting the impression that you think that the purpose of
> splitting and concatenating the generic identifier is somehow
> related to escaping the ETAGO delimiter (‘</’),

"Somehow related" seems applicable.

> while it is much more likely to be related to Norton ‘Internet
> Security’ inserting it’s dreaded SymError function after the
> first instance of anything that looks like the start tag of a
> script element (and ususally messing things up in the process).

In a cause and effect relationship I would expect the cause to pre-date
the effect. This concatenation 'trick' was common when I started working
with javascript in 2001. The odds are that it pre-dates Norton 'internet
security' and my observations of Norton's inserted scripts have been
that it has been varying over time. So it seems more likely that
observing this common practice allowed the incompetent scripters at
Norton to justify not parsing the HTML they modify, and so the pertinent
cause and effect relationship here could be the other way around (though
"Post hoc ergo propter hoc" is a logical fallacy, so maybe not).

I also don't think that the mindset where people are scripting only for
the default configurations of the most recent versions of 4 or 5 known
browsers will tend to leave then thinking about the possible actions of
'security' proxies (or being willing to take action to accommodate them
if they did).

In any event, HTML mark-up modification is still not relevant to the
contents of an imported javascript.

Richard.

J.R.

unread,
Nov 13, 2011, 10:44:54 AM11/13/11
to
On 13/11/2011 01:31, Thomas 'PointedEars' Lahn wrote:
> J.R. wrote:
>
>> On 10/11/2011 12:09, David Mark wrote:
>>> if (document.documentElement&& typeof
>>> document.documentElement.clientWidth == 'number') {
>>> var getInnerDimensions = function(el) {
>>> return [el.clientHeight, el.clientWidth];
>>> };
>>> }
>>>
>>
>> Considering an element having scrollbars, we might use:
>>
>> return [el.scrollTop + el.clientHeight,
>> el.scrollLeft + el.clientWidth];
>
> Please explain what the scroll position has to do with the element
> dimensions.

The clientWidth and clientHeight properties return the width and height
of the content field, excluding borders and *scrollbars* (when visible),
but including padding. If the element's content overflows then the
browser might show scrollbars depending on the overflow CSS property. In
the latter case, clientWidth and clientHeight won't retrieve the
measurement of the hidden parts of the element's content.

A better approach would be using scrollWidth and scrollHeight, but these
properties are "buggy" in IE and Opera, according to
<http://www.quirksmode.org/dom/w3c_cssom.html#elementview>. The irony
here is that scrollWidth and scrollHeight were introduced by Microsoft
in their MSIE's DHTML object model...

Therefore, if we want a "getInnerDimensions" function to return the
correct dimensions for the element's content we will need to add the
scrollTop and scrollLeft values to the clientHeight and clientWidth
values respectively, otherwise we would not get the correct inner
dimensions if the element is scrolled all the way down or to the right.

But what if the element doesn't have scrollbars? No problem, because
scrollTop and scrollLeft will return zero.

>> Note: scrollWidth/scrollHeight are buggy in IE6-8 and Opera 10
>>
>> So, we'd need to compare (scrollTop + clientHeight) to scrollHeight too.
>> In IE8, scrollWidth is 5 pixels off. See
>> <http://www.quirksmode.org/dom/w3c_cssom.html>
>
> That states that *scrollHeight* is buggy in IE *5.5* to 7, and that
> scrollWidth is _correct_ in those versions. It also states that scrollWidth
> is 5 pixel off in IE 8, and that "Opera gives odd, incorrect values." Quite
> different from what you stated.

I don't think it is *quite* different, perhaps a *little* different...
In fact, it is better to avoid scrollWidth/scrollHeight whenever we need
a cross-browser code.

--
Joao Rodrigues (J.R.)

Thomas 'PointedEars' Lahn

unread,
Nov 13, 2011, 12:35:02 PM11/13/11
to
J.R. wrote:

> Thomas 'PointedEars' Lahn wrote:
>> J.R. wrote:
>>> On 10/11/2011 12:09, David Mark wrote:
>>>> if (document.documentElement&& typeof
>>>> document.documentElement.clientWidth == 'number') {
>>>> var getInnerDimensions = function(el) {
>>>> return [el.clientHeight, el.clientWidth];
>>>> };
>>>> }
>>>
>>> Considering an element having scrollbars, we might use:
>>>
>>> return [el.scrollTop + el.clientHeight,
>>> el.scrollLeft + el.clientWidth];
>>
>> Please explain what the scroll position has to do with the element
>> dimensions.
>
> […]
> A better approach would be using scrollWidth and scrollHeight, but these
> properties are "buggy" in IE and Opera, according to
> <http://www.quirksmode.org/dom/w3c_cssom.html#elementview>. The irony
> here is that scrollWidth and scrollHeight were introduced by Microsoft
> in their MSIE's DHTML object model...
>
> Therefore, if we want a "getInnerDimensions" function to return the
> correct dimensions for the element's content we will need to add the
> scrollTop and scrollLeft values to the clientHeight and clientWidth
> values respectively, otherwise we would not get the correct inner
> dimensions if the element is scrolled all the way down or to the right.
>
> But what if the element doesn't have scrollbars? No problem, because
> scrollTop and scrollLeft will return zero.

And if I scroll down or right a scrollable element its content becomes
higher/wider?

>>> Note: scrollWidth/scrollHeight are buggy in IE6-8 and Opera 10
>>>
>>> So, we'd need to compare (scrollTop + clientHeight) to scrollHeight too.
>>> In IE8, scrollWidth is 5 pixels off. See
>>> <http://www.quirksmode.org/dom/w3c_cssom.html>
>>
>> That states that *scrollHeight* is buggy in IE *5.5* to 7, and that
>> scrollWidth is _correct_ in those versions. It also states that
>> scrollWidth
>> is 5 pixel off in IE 8, and that "Opera gives odd, incorrect values."
>> Quite different from what you stated.
>
> I don't think it is *quite* different, perhaps a *little* different...
> In fact, it is better to avoid scrollWidth/scrollHeight whenever we need
> a cross-browser code.

It is better to be aware of it and use *sensible* workarounds if necessary.
This is actually one case where property inference (window.opera) is useful
and acceptable; IE should be dealt with using Conditional Comments instead.

Hans-Georg Michna

unread,
Nov 13, 2011, 2:22:28 PM11/13/11
to
On Sat, 12 Nov 2011 19:19:45 -0000, Richard Cornford wrote:

><scr("|')\+("|')ipt lang:javascript
>
>- of which a representative example (from an old dojo version, and
>re-wrapped for posting) is:-
>
>document.write(
> "<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>"
>);

Thanks again! Nice examples.

Hans-Georg

Hans-Georg Michna

unread,
Nov 13, 2011, 2:25:42 PM11/13/11
to
On Sun, 13 Nov 2011 08:29:54 +1000, RobG wrote:

>On 12/11/11 7:38 PM, Hans-Georg Michna wrote:

>>[...]
>> Anyway, do you have more examples? These would be good demos of
>> the general ignorance towards correct JavaScript programming.
>> Good for demos.

>One that is specific to jQuery is the use, usually within a listener, of
>the expression:
>
> $(this).val()
>
>Searching at Google code search with:
>
> \$\(this\)\.val\(\) lang:javascript
>
>returns over 5,000 hits.

Please help my vague memories of jQuery. What is it that .val()
does? Or do you mean that the $(...) is simply superfluous?

Hans-Georg

J.R.

unread,
Nov 13, 2011, 7:00:38 PM11/13/11
to
No, but you can't retrieve the width / height of a scrollable element's
content with just clientHeight and clientWidth properties.


>>>> Note: scrollWidth/scrollHeight are buggy in IE6-8 and Opera 10
>>>>
>>>> So, we'd need to compare (scrollTop + clientHeight) to scrollHeight too.
>>>> In IE8, scrollWidth is 5 pixels off. See
>>>> <http://www.quirksmode.org/dom/w3c_cssom.html>
>>>
>>> That states that *scrollHeight* is buggy in IE *5.5* to 7, and that
>>> scrollWidth is _correct_ in those versions. It also states that
>>> scrollWidth
>>> is 5 pixel off in IE 8, and that "Opera gives odd, incorrect values."
>>> Quite different from what you stated.
>>
>> I don't think it is *quite* different, perhaps a *little* different...
>> In fact, it is better to avoid scrollWidth/scrollHeight whenever we need
>> a cross-browser code.
>
> It is better to be aware of it and use *sensible* workarounds if necessary.
> This is actually one case where property inference (window.opera) is useful
> and acceptable; IE should be dealt with using Conditional Comments instead.
>

ACK.

--
Joao Rodrigues (J.R.)

RobG

unread,
Nov 14, 2011, 2:05:49 AM11/14/11
to
On Nov 14, 5:25 am, Hans-Georg Michna <hans-
It can be replaced with the very much faster (and less to type):

this.value;

$(this) "wraps" the target in a jQuery object (quite expensive in
performance terms).

The val() method does some fixing of issues with select elements and
option values, but they are well known and can be dealt with in the
markup.



--
Rob

Thomas 'PointedEars' Lahn

unread,
Nov 14, 2011, 6:40:21 AM11/14/11
to
(Apparently I have to be blunt.) Difficulties with using scrollWidth and
scrollHeight /notwithstanding/:

Your approach is *junk*. Because *again*, the *content* of the element
(scrollWidth/scrollHeight) does _not_ become wider or higher when I scroll
it right or down, so you MUST NOT add scrollTop or scrollLeft:

Not scrolled

scrollLeft
->.<-
.
. scrollWidth
.<------------------>.
. .
. clientWidth .
.<----------->. . |
. . . v
,---------------.- --.- - - - - - - - - - scrollTop
| |^| : ^ ^
| |#| : | clientHeight |
| | | : v |
|_____________|v| _ _:_ _ | scrollHeight
|<# >| | : |
:---------------' : |
: : |
: : v
'-- -- -- -- -- -- --'- - - - - - - - - -

Scrolled right and down

scrollLeft
->. .<-
. .
.-- -- -- -- -- -- --.- - - - - - - - - - - - --
: . : ^ ^
: . : | scrollTop |
: . : v |
: ,---------------.- - - - | scrollHeight
: | |^| ^ |
: | | | | clientHeight |
: | |#| v v
:__ __ |_____________|v|_ _ _ _ _ _ _ _ _ _ _ __
' |< #>| |
' '---------------'
' ' '
' ' '
' ' '
' '<----------->'
' clientWidth '
' '
'<------------------>'
scrollWidth


See also: <http://msdn.microsoft.com/en-us/library/ms530302(VS.85).aspx>

Tim Down

unread,
Nov 14, 2011, 6:41:18 AM11/14/11
to
It also messes around with new lines and strips out CR carriage return
characters in the value in attempt to normalize browser behaviour.
However, this seems less than helpful to me: I can see no practical
advantage to it and it causes properties such as selectionStart and
selectionEnd to be unreliable as character indexes within a value
returned by val().

Tim

J.R.

unread,
Nov 14, 2011, 8:52:41 AM11/14/11
to
You really don't seem to understand that a part of the content of a
scrollable element may be hidden because it's wider and/or taller than
the element's box. And that invisible part of the content cannot be
measured with just element.clientHeight and element.clientWidth
properties. If you want to get the element's content dimensions (not the
box dimensions), you MUST USE (el.scrollTop + el.clientHeight) and
(el.scrollLeft + el.clientWidth).

--
Joao Rodrigues (J.R.)
Message has been deleted

Thomas 'PointedEars' Lahn

unread,
Nov 14, 2011, 9:40:11 AM11/14/11
to
J.R. wrote:

> On 14/11/2011 09:40, Thomas 'PointedEars' Lahn wrote:
>> J.R. wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> J.R. wrote:
>>>>> Thomas 'PointedEars' Lahn wrote:
>>>>>> J.R. wrote:
>>>>>>> On 10/11/2011 12:09, David Mark wrote:
>>>>>>>> if (document.documentElement&& typeof
>>>>>>>> document.documentElement.clientWidth == 'number') {
>>>>>>>> var getInnerDimensions = function(el) {
>>>>>>>> return [el.clientHeight, el.clientWidth];
>>>>>>>> };
>>>>>>>> }
>>>>>>>
>>>>>>> Considering an element having scrollbars, we might use:
>>>>>>>
>>>>>>> return [el.scrollTop + el.clientHeight,
>>>>>>> el.scrollLeft + el.clientWidth];
>>>>>>
>>>>>> Please explain what the scroll position has to do with the element
>>>>>> dimensions.
>> […]
>> Your approach is *junk*. Because *again*, the *content* of the element
>> (scrollWidth/scrollHeight) does _not_ become wider or higher when I
>> scroll it right or down, so you MUST NOT add scrollTop or scrollLeft:
>>
>> [ASCII-Art: Element measures without and with scrolling]
>>
>> See also:<http://msdn.microsoft.com/en-us/library/ms530302(VS.85).aspx>
>
> You really don't seem to understand that a part of the content of a
> scrollable element may be hidden because it's wider and/or taller than
> the element's box.

No, *I* really do. And −1 for full-quoting and still failing to understand
what took me quite some time to get painted right:

scrollWidth != clientWidth + scrollLeft
scrollHeight != clientHeight + scrollTop

> And that invisible part of the content cannot be
> measured with just element.clientHeight and element.clientWidth
> properties. If you want to get the element's content dimensions (not the
> box dimensions), you MUST USE (el.scrollTop + el.clientHeight) and
> (el.scrollLeft + el.clientWidth).

No, you MUST NOT use that because *inner dimensions* (i. e., that of the
element's *content*) computed this way will vary depending on the element's
scroll position, which is not measuring the inner dimensions *at all*.


Score adjusted

PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

Hans-Georg Michna

unread,
Nov 15, 2011, 10:52:02 AM11/15/11
to
On Sun, 13 Nov 2011 23:05:49 -0800 (PST), RobG wrote:

>It can be replaced with the very much faster (and less to type):
>
> this.value;
>
>$(this) "wraps" the target in a jQuery object (quite expensive in
>performance terms).
>
>The val() method does some fixing of issues with select elements and
>option values, but they are well known and can be dealt with in the
>markup.

Thanks! Another interesting example.

Hans-Georg

RobG

unread,
Nov 16, 2011, 7:18:35 PM11/16/11
to
Looking at the documentation for .val[1] (which is included under
"attributes"), the example uses $(this).val(), adding weight to its
categorisation as "cargo cult programming".

The documentation also says that .val returns "String, Number, Array",
which suggests that it returns String, Number or Array objects. It
will return an array in only one case: the values of a multiple
select. Allowing for sloppy documentation and that they really meant
that it might also return string or number primitives, I can't see any
case where it should return a number.

1. <URL: http://api.jquery.com/val/ >


--
Rob

Eric Bednarz

unread,
Nov 17, 2011, 5:16:38 AM11/17/11
to
Thomas 'PointedEars' Lahn <Point...@web.de> writes:

> This is actually one case where property inference (window.opera) is useful
> and acceptable; […]

var opera = 'Der Ring des Nibelungen';

On the other hand, Opera has a proper way of dealing with
(version-)detection (unless the opera object is shadowed, and I’d rather
have a false negative than a false positive; but surely YMWD), e.g.:

var OPERA = (function (global) {
var dom_window = global.window,
opera,
version,
subversion,
build;
if ('object' == typeof dom_window.opera) {
opera = dom_window.opera;
// the version method was introduced in Opera 8
if (('function' == typeof opera.version) &&
('function' == typeof opera.buildNumber)
) {
version = opera.version();
subversion = version.split('.');
// The return value of the version method has
// three parts up to Opera 9.27 (including the
// build number) and two since 9.50
version = [subversion[0], subversion[1]].join('.');
build = opera.buildNumber();
return {
major: +subversion[0],
minor: +subversion[1],
build: +build,
number: +version,
string: [version, build].join('.')
};
}
}
return null;
}(this));

In this group it is probably not safe not to say the obvious, practical
applications would be less verbose and have a more practical return
value. :-)

--
λ

Thomas 'PointedEars' Lahn

unread,
Nov 17, 2011, 3:06:51 PM11/17/11
to
Eric Bednarz wrote:

> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>> This is actually one case where property inference (window.opera) is
>> useful and acceptable; […]
>
> var opera = 'Der Ring des Nibelungen';

Don't be ridiculous. Oh wait, it's you.

> On the other hand, Opera has a proper way of dealing with
> (version-)detection (unless the opera object is shadowed, and I’d rather
> have a false negative than a false positive; but surely YMWD), e.g.:
>
> var OPERA = (function (global) {
> var dom_window = global.window,

AISB.

> opera,
> version,
> subversion,
> build;
> if ('object' == typeof dom_window.opera) {

You have overlooked the case of dom_window.opera === null. Also, it is a
host object, so all bets (other than it would have to be a true-value to be
useful) are off.

> opera = dom_window.opera;
> // the version method was introduced in Opera 8
> if (('function' == typeof opera.version) &&
> ('function' == typeof opera.buildNumber)

You have overlooked the case where a host object's method would not yield
`function', which might be the case with Opera's DOM implementation.


PointedEars
--
When all you know is jQuery, every problem looks $(olvable).

Eric Bednarz

unread,
Nov 17, 2011, 4:13:56 PM11/17/11
to
Thomas 'PointedEars' Lahn <Point...@web.de> writes:

> Eric Bednarz wrote:
>
>> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>>> This is actually one case where property inference (window.opera) is
>>> useful and acceptable; […]
>>
>> var opera = 'Der Ring des Nibelungen';
>
> Don't be ridiculous.

That reminds me. You know what Wagner said after deciding to write his
magnus opus around Wotan’s world dominance plot instead of yours?

“Score adjusted.”

> Oh wait, it's you.

Says the one who is constantly beating reality with a big hammer until
it fits into his views.

>> if ('object' == typeof dom_window.opera) {
>
> You have overlooked the case of dom_window.opera === null.

That’s a fair point.

> Also, it is a
> host object, so all bets (other than it would have to be a true-value to be
> useful) are off.

Cases where it isn’t Opera’s host object are not really interesting.

>> opera = dom_window.opera;
>> // the version method was introduced in Opera 8
>> if (('function' == typeof opera.version) &&
>> ('function' == typeof opera.buildNumber)
>
> You have overlooked the case where a host object's method would not yield
> `function', which might be the case with Opera's DOM implementation.

See above. The only thing I have overlooked is the case where it is
pointless to reply.

Eric Bednarz

unread,
Nov 17, 2011, 5:14:57 PM11/17/11
to
"Richard Cornford" <Ric...@litotes.demon.co.uk> writes:

> Eric Bednarz wrote:
>> Richard Cornford writes:
>>
>>> document.write(
>>> "<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>"
>>> );
>>>
>>> The cargo-cult programming structure is the first (left-most)
>>> string concatenation operation. The final (right-most) string
>>> concatenation operation has some justification in some contexts.
>>> Its use in those contexts demonstrates a shallow understanding
>>> of the reasons for its use (as there are more efficient, shorter
>>> and more formally correct alternatives), and it was almost
>>> certainly that shallow understanding that inspired the real
>>> cargo-cult structure to the left. However, One context where
>>> the final (right-most) concatenation is purposeless is when it
>>> is found in an imported JS file, which is of course where
>>> Google's code search is finding it. So that too is pushing
>>> cargo-cult programming in the contexts where it is being found
>>> above.
>>
>> I’m getting the impression that you think that the purpose of
>> splitting and concatenating the generic identifier is somehow
>> related to escaping the ETAGO delimiter (‘</’),
>
> "Somehow related" seems applicable.

Well, I don’t understand what you mean by “some justification in some
contexts”. In the context of a CDATA content model it doesn’t make any
sense at all because CDATA ends with ETAGO foolowed by a name start
character. So that habit wouldn’t have made it valid HTML (4) either.

>> while it is much more likely to be related to Norton ‘Internet
>> Security’ inserting it’s dreaded SymError function after the
>> first instance of anything that looks like the start tag of a
>> script element (and ususally messing things up in the process).
>
> In a cause and effect relationship I would expect the cause to
> pre-date the effect. This concatenation 'trick' was common when I
> started working with javascript in 2001.

Well, I’m unlikely to ever catch up with that head start. :-)

References I’ve seen connecting this practice with NIS were from around
2004 to 2006, as far as I can remember.

> The odds are that it
> pre-dates Norton 'internet security'

But why? Were there *practical* problems that are not related to
validation?

> and my observations of Norton's
> inserted scripts have been that it has been varying over time.

That’s inherent with cat and mouse games. For a while it seems to have
been possible to prevent NIS from modifying the first script element in
the HTML source by preceding it with an HTML comment containing script
markup (this kind of thing is pretty hard to verify now, but it sounds
plausible; ad-hoc parsing is usually broken and gets fixed feature by
feature later).

> I also don't think that the mindset where people are scripting only
> for the default configurations of the most recent versions of 4 or 5
> known browsers will tend to leave then thinking about the possible
> actions of 'security' proxies (or being willing to take action to
> accommodate them if they did).

It doesn’t create much overhead, and might have been a best practice
that is so good that nobody checks what it is for ;-)

On the other hand, it’s really not easy to know which cargo cult bits
are redundant or not, and why. Somewhere around 2007 I removed HTML
comments out of script elements in the course of a redesign of a
website. I got kicked royally for that because the client had some
really crappy HTML to PDF conversion software that included the script
content after that.

> In any event, HTML mark-up modification is still not relevant to the
> contents of an imported javascript.

But it is supposed to have been *only* about external script, the
premise being that NIS was looking for the first occurance of something
that looks like a start tag of a script element, which isn’t a problem
in a HTML context.

Frobernik

unread,
Nov 17, 2011, 5:43:30 PM11/17/11
to
On 10/11/2011 21:12, Matt McDonald wrote:
> On 11-11-10 12:47 PM, Ant wrote:
> "HTML 5 Boilerplate" is a massive set of server
> configurations, CSS file(s) ("normalizing", they call it),
> JavaScript files (including jQuery & modernizr, neither of which
> have any particular use to me), and other assorted bits.

"normalizing" is just a set of resets in the real world made for so
called "web apps" - because nothing says futuristic like a splash screen
or a spinning dial

> The biggest blow is marketing. Take a gander at
> "HTML 5 Boilerplate"'s website (won't link). It's chock full of
> over-the-top marketing speak. The first time I read it, I was
> heavily offended by the textual content. I seriously pondered
> if it was written by a prepubescent.

Well there are people (apart from the punters on here) fighting
modernizer, jQuery and other junk (will link)

http://nefariousdesigns.co.uk/archive/2011/05/sniff-my-browser-the-modernizr-inadequacy/

Frobernik

Richard Cornford

unread,
Nov 17, 2011, 6:55:53 PM11/17/11
to
Do you really not know this? Unexpected but never mind. Real world
browsers (as you know) use tag-soup parsers instead of (formal) HTML
parsers, so they tend not to care about ETAGO terminating CDATA.
However, even tag soup parsers need to delimit the sequence of
characters they are going to send to the javascript engine, and they do
that by looking for the (case insensitive) character sequence </script>.
They assume an open script element is terminated by the next occurrence
of that sequence that they find, even if that sequence is actually
supposed to be part of the javascript source code. To avoid the
javascript source placed inside a script element from being prematurely
terminated it is normal to break up any </script> charter sequences
within that source code. And one of the techniques for braking that
sequence up has been the final concatenation "trick" illustrated above.

In source code that appears within script tags in HTML page the
recommended practice is to break up the </script> sequence by putting a
backslash (escape) character just before the forward slash to give
<\/script>. This addresses the practical problem of preventing the
mark-up parser from mistaking it for the closing script tag and more
efficiently than the concatenation "trick" because the escape sequence
is handled during the tokenization of the javascript source code so
there is no runtime overhead (and it is shorter and probably quicker to
tokenise than the concatenation code). Plus this also happens to deal
with the ETAGO, if mark-up validity is something that is valued.

>>> while it is much more likely to be related to Norton ‘Internet
>>> Security’ inserting it’s dreaded SymError function after the
>>> first instance of anything that looks like the start tag of a
>>> script element (and ususally messing things up in the process).
>>
>> In a cause and effect relationship I would expect the cause to
>> pre-date the effect. This concatenation 'trick' was common when
>> I started working with javascript in 2001.
>
> Well, I’m unlikely to ever catch up with that head start. :-)
>
> References I’ve seen connecting this practice with NIS were
> from around 2004 to 2006, as far as I can remember.
>
>> The odds are that it
>> pre-dates Norton 'internet security'
>
> But why? Were there *practical* problems that are not related to
> validation?

Yes, as described above.

>> and my observations of Norton's
>> inserted scripts have been that it has been varying over time.
>
> That’s inherent with cat and mouse games. For a while it seems
> to have been possible to prevent NIS from modifying the first
> script element in the HTML source by preceding it with an HTML
> comment containing script markup (this kind of thing is pretty
> hard to verify now, but it sounds plausible; ad-hoc parsing is
> usually broken and gets fixed feature by feature later).

Yep, it is a fools errand to try to do anything to compensate.

>> I also don't think that the mindset where people are scripting
>> only for the default configurations of the most recent versions
>> of 4 or 5 known browsers will tend to leave then thinking about
>> the possible actions of 'security' proxies (or being willing to
>> take action to accommodate them if they did).
>
> It doesn’t create much overhead, and might have been a best
> practice that is so good that nobody checks what it is for ;-)

It has been a recommended practice, intended for an HTML context. And it
certainly is harmless.

> On the other hand, it’s really not easy to know which cargo cult
> bits are redundant or not, and why.

An examination of the reasoning that justifies them is frequently
enough. With the absence of any stated justification being a pretty good
clue on its own.

> Somewhere around 2007 I
> removed HTML comments out of script elements in the course of
> a redesign of a website. I got kicked royally for that because
> the client had some really crappy HTML to PDF conversion software
> that included the script content after that.

But you would have learnt that sooner if you had never included them in
the first place, and they were redundant in their original role by 2001.
Then you would only have had to add them once (or possibly the client
would have got a better converter to start with).

>> In any event, HTML mark-up modification is still not relevant to
>> the contents of an imported javascript.
>
> But it is supposed to have been *only* about external script, the
> premise being that NIS was looking for the first occurance of
> something that looks like a start tag of a script element, which
> isn’t a problem in a HTML context.

You are going to have to explain that better as I don't see the point
you are making there.

Richard.

David Mark

unread,
Dec 2, 2011, 6:00:57 PM12/2/11
to
On Nov 11, 4:33 pm, Dr J R Stockton <reply1...@merlyn.demon.co.uk>
wrote:
> In comp.lang.javascript message <bd12b66f-33f5-43d2-8e22-6f81b42c3d8b@n1
> 4g2000vbn.googlegroups.com>, Thu, 10 Nov 2011 06:09:29, David Mark
> <dmark.cins...@gmail.com> posted:
>
> >How to Measure Element Dimensions
>
> It could be useful if there were, linked from within each posted Tip, a
> Web Index of Tips, linking to Web copies.
>
> One Tip might be the answer to "I have an on-screen element, of known
> size, with an on[dbl]click method; how do I obtain the co-ordinates of a
> [double-]click with respect to a given position in the element itself?"
>
> The aforementioned index page could have a feedback form, partly for
> suggesting topics for tips and possible answers.  The latter, when
> imperfect, would provide fodder for further Tips, of course.

I suppose.


>
> In what appears to be the cinsoft home page, "By" should be "To".
>

Huh?


> Consider a page, <http://www.cinsoft.net/position.html>, which has been
> found by a serendipitous Google search for "starting point for a move
> animation" or otherwise.  It recommends
>         o = getElementPositionStyles(el);
> - and that does not work

It's necessary to have the included script.


 The necessary further information is not
> clearly provided; indeed, the page seems to have no <a href="...">Home
> Page</a>.


Wrong. It's the logo and likely has alt text. Leads to library page.
Site untouched for years; primers not even part of main site or
library. Just a dumping ground for examples that came up here.




Thanks! Buy the book when it comes out. No UK release date yet.

David Mark

unread,
Dec 2, 2011, 6:10:14 PM12/2/11
to
On Nov 12, 9:06 pm, "J.R." <groups_j...@yahoo.com.br> wrote:
> On 10/11/2011 12:09, David Mark wrote:
>
> > if (document.documentElement&&  typeof
> > document.documentElement.clientWidth == 'number') {
> >    var getInnerDimensions = function(el) {
> >      return [el.clientHeight, el.clientWidth];
> >    };
> > }
>
> Considering an element having scrollbars, we might use:
>
>    return [el.scrollTop + el.clientHeight,
>            el.scrollLeft + el.clientWidth];


I don't follow. Use for what?

>
> Note: scrollWidth/scrollHeight are buggy in IE6-8 and Opera 10. So, we'd
> need to compare (scrollTop + clientHeight) to scrollHeight too. In IE8,
> scrollWidth is 5 pixels off. See
> <http://www.quirksmode.org/dom/w3c_cssom.html>

Not buggy, at least not in contexts I use. Who uses scrollWidth? And
thanks, but I am not interested PPK's notes on subject. Usually vague
and/or confused.


>
> --
> Joao Rodrigues (J.R.)

David Mark

unread,
Dec 2, 2011, 6:54:36 PM12/2/11
to
On Nov 14, 2:05 am, RobG <rg...@iinet.net.au> wrote:
> On Nov 14, 5:25 am, Hans-Georg Michna <hans-
>
>
>
>
>
>
>
>
>
> georgNoEmailPle...@michna.com> wrote:
> > On Sun, 13 Nov 2011 08:29:54 +1000,RobGwrote:
> > >On 12/11/11 7:38 PM, Hans-Georg Michna wrote:
> > >>[...]
> > >> Anyway, do you have more examples? These would be good demos of
> > >> the general ignorance towards correctJavaScriptprogramming.
> > >> Good for demos.
> > >One that is specific tojQueryis the use, usually within a listener, of
> > >the expression:
>
> > >   $(this).val()
>
> > >Searching atGooglecode search with:
>
> > >   \$\(this\)\.val\(\) lang:javascript
>
> > >returns over 5,000 hits.
>
> > Please help my vague memories ofjQuery. What is it that .val()
> > does? Or do you mean that the $(...) is simply superfluous?
>
> It can be replaced with the very much faster (and less to type):
>
>     this.value;

Well, not necessarily. A better (or worse, depending on view) example
of this cargo cult pattern would be:

$(this).attr('id');

Now, anything like that is clearly BS on many levels: performance,
reliability, etc. It's a major misunderstanding.

>
> $(this) "wraps" the target in ajQueryobject (quite expensive in
> performance terms).

Absolutely. But, in this case, the (rather unfortunately named) "val"
method may be useful. It's just unfortunate how jQuery works (create
a huge object, discard same), turning every line into an epic snarl of
function calls, created objects, etc.

But if there are more than text inputs (or selects in very specific
contexts) involved, a "getInputValue" function of some sort is in
order. God knows, I wouldn't trust jQuery's rendition.


This is indeed one viable rendition:-

function getInputValue(el) {
return el.value;
}

But you have to know when it is appropriate. The renditions get
larger as you accommodate checkboxes, radio buttons, etc. as typically
this type of function is interested in the value that will be
submitted to the server (if any). And, as mentioned, unless you set
down strict rules for selects, you can't use the above with them
either.

>
> The val() method does some fixing of issues with select elements and
> option values, but they are well known and can be dealt with in the
> markup.

Right. I suppose it tries; but wouldn't even waste the time reading
the code. I imagine it accounts for unchecked inputs and returns
array of strings for multi select as well. Pretty standard stuff that
hasn't changed... ever. Unlikely jQuery has put some must-have new
spin on form control serialization. I did see where somebody said the
docs state their "val" function may return a number. That I did not
expect. :)

David Mark

unread,
Dec 2, 2011, 7:03:15 PM12/2/11
to
On Nov 14, 6:41 am, Tim Down <timd...@gmail.com> wrote:
> On Nov 14, 7:05 am,RobG<rg...@iinet.net.au> wrote:
>
>
>
>
>
>
>
>
>
> > On Nov 14, 5:25 am, Hans-Georg Michna <hans-
> > georgNoEmailPle...@michna.com> wrote:
> > > On Sun, 13 Nov 2011 08:29:54 +1000,RobGwrote:
> > > >On 12/11/11 7:38 PM, Hans-Georg Michna wrote:
> > > >>[...]
> > > >> Anyway, do you have more examples? These would be good demos of
> > > >> the general ignorance towards correctJavaScriptprogramming.
> > > >> Good for demos.
> > > >One that is specific tojQueryis the use, usually within a listener, of
> > > >the expression:
>
> > > >   $(this).val()
>
> > > >Searching atGooglecode search with:
>
> > > >   \$\(this\)\.val\(\) lang:javascript
>
> > > >returns over 5,000 hits.
>
> > > Please help my vague memories ofjQuery. What is it that .val()
> > > does? Or do you mean that the $(...) is simply superfluous?
>
> > It can be replaced with the very much faster (and less to type):
>
> >     this.value;
>
> > $(this) "wraps" the target in ajQueryobject (quite expensive in
> > performance terms).
>
> > The val() method does some fixing of issues with select elements and
> > option values, but they are well known and can be dealt with in the
> > markup.
>
> It also messes around with new lines and strips out CR carriage return
> characters in the value in attempt to normalize browser behaviour.
> However, this seems less than helpful to me: I can see no practical
> advantage to it and it causes properties such as selectionStart and
> selectionEnd to be unreliable as character indexes within a value
> returned by val().
>

Yes, depending on needs, I'd say that's a considerable drawback or of
no benefit. Trying to do too much "normalization" is one of the
script's problems. As mentioned, it screws up height/width in similar
fashion, making them unusable in some contexts (e.g. border box
model).

Considering what a function will be used for is of primary concern for
a solid design. Unfortunately, when you've got thousands of users and
contributors, each with their own specific needs, it's hard to reach a
consensus on use cases. You end up with mush that sloshes back and
forth over the years as the code base is pulled and pushed by
competing concerns. Also see attr/removeAttr and the recently
introduced prop/removeProp.

David Mark

unread,
Dec 2, 2011, 7:08:01 PM12/2/11
to
On Nov 17, 5:43 pm, Frobernik <nos...@nospam.com> wrote:
> On 10/11/2011 21:12, Matt McDonald wrote:
>
> > On 11-11-10 12:47 PM, Ant wrote:
> > "HTML 5 Boilerplate" is a massive set of server
> > configurations, CSS file(s) ("normalizing", they call it),
> >JavaScriptfiles (includingjQuery& modernizr, neither of which
> > have any particular use to me), and other assorted bits.
>
> "normalizing" is just a set of resets in the real world made for so
> called "web apps" - because nothing says futuristic like a splash screen
> or a spinning dial
>
> > The biggest blow is marketing. Take a gander at
> > "HTML 5 Boilerplate"'s website (won't link). It's chock full of
> > over-the-top marketing speak. The first time I read it, I was
> > heavily offended by the textual content. I seriously pondered
> > if it was written by a prepubescent.
>
> Well there are people (apart from the punters on here) fighting
> modernizer,jQueryand other junk (will link)

I see you have almost *one million* posts on here. Punter. :)

And who is fighting what? Just throw them away.

>
> http://nefariousdesigns.co.uk/archive/2011/05/sniff-my-browser-the-mo...

I've seen it. Somebody doesn't like Modrnizer (sp?). I don't like it
either. Imagine, a monolithic feature detection script that
pigeonholes browsers according to some predetermined series of
"standard" tests. Adds a ton of classes too. No thanks!

David Mark

unread,
Dec 2, 2011, 6:19:01 PM12/2/11
to
On Nov 13, 10:44 am, "J.R." <groups_j...@yahoo.com.br> wrote:
> On 13/11/2011 01:31, Thomas 'PointedEars' Lahn wrote:
>
>
>
>
>
> > J.R. wrote:
>
> >> On 10/11/2011 12:09, David Mark wrote:
> >>> if (document.documentElement&&   typeof
> >>> document.documentElement.clientWidth == 'number') {
> >>>     var getInnerDimensions = function(el) {
> >>>       return [el.clientHeight, el.clientWidth];
> >>>     };
> >>> }
>
> >> Considering an element having scrollbars, we might use:
>
> >>     return [el.scrollTop + el.clientHeight,
> >>             el.scrollLeft + el.clientWidth];
>
> > Please explain what the scroll position has to do with the element
> > dimensions.
>
> The clientWidth and clientHeight properties return the width and height
> of the content field, excluding borders and *scrollbars* (when visible),
> but including padding. If the element's content overflows then the
> browser might show scrollbars depending on the overflow CSS property. In
> the latter case, clientWidth and clientHeight won't retrieve the
> measurement of the hidden parts of the element's content.


No problem there; overflowed content not supposed to count.

>
> A better approach would be using scrollWidth and scrollHeight, but these
> properties are "buggy" in IE and Opera, according to
> <http://www.quirksmode.org/dom/w3c_cssom.html#elementview>.

No. That's getScrollDimensions. And may well be susceptible to quirks
in some cases. Particularly the HTML element.

The irony
> here is that scrollWidth and scrollHeight were introduced by Microsoft
> in their MSIE's DHTML object model...

As were others. IE 4.


>
> Therefore, if we want a "getInnerDimensions" function to return the
> correct dimensions for the element's content we will need to add the
> scrollTop and scrollLeft values to the clientHeight and clientWidth
> values respectively, otherwise we would not get the correct inner
> dimensions if the element is scrolled all the way down or to the right.


No.

David Mark

unread,
Dec 2, 2011, 9:04:22 PM12/2/11
to
Should amend and sorry for quoting sig. Was on phone browser. Glad
to get out without losing the message in a crash. :(

Can think of one recent case where I compared scrollWidth to
clientWidth; it was the usual case of expanding an overflow:auto
container to exactly fit the width of the content. Had no problems
whatsoever; tested in almost every version of IE, as well as several
versions of the usual standards-based suspects. From time frame, it
seems to me that Opera 10 would have been on that list. But I know
there weren't issues with IE in my context. Version 8 was primary IE
browser at the time and tested back to 5.5 in IETester or some such.

It wouldn't shock me if in some version in some rendering mode (e.g.
quirks) or some compatibility mode of IE, and with some particular
styling and structure, there is a bug with the scrollWidth property.
But AFAIK, it never bit me. :)

ISTM that the "drag and scroll" example on the Build Test page would
be a good place to start to determine if IE 8 or Opera 10's
implementation of scrollWidth/Height is off in some way. If they are
off, there's no way that example will work properly (unless it just
happens to avoid the bugs by coincidence of particular styling or
other variables).

And if there are such quirks with those properties, they should be
trivial to feature test. ;)

David Mark

unread,
Dec 2, 2011, 9:38:05 PM12/2/11
to
On Nov 11, 4:33 pm, Dr J R Stockton <reply1...@merlyn.demon.co.uk>
wrote:
>
> One Tip might be the answer to "I have an on-screen element, of known
> size, with an on[dbl]click method; how do I obtain the co-ordinates of a
> [double-]click with respect to a given position in the element itself?"
>

Tricky. :)

Your best bet is to see the tip of the day related to coordinates.
From that you should be able to get the coordinates of the element
relative to the viewport (or "window" as I think I referred to it in
that post). So you will need the mouse coordinates relative to the
viewport. Ironically enough, it's trivial to find those in the old IE
versions that lacked pageX/Y properties. But for everything else, you
have to have to subtract the scroll position as pageX/Y are relative
to the document. Depending on context, getting the scroll position is
either trivial (one-liner) or fairly complex. Frustratingly, it's IE
(all versions AFAIK) that needs most of the extra code in this case.
You also have to consider other factors like whether you will need
this to work in quirks mode (hopefully not)


It looks like:-

// No quirks mode, frames or other windows (just the one running the
script)

var getScrollPosition;

if ('number' == typeof window.pageXOffset) {

// Many "standards-based" browsers feature this non-standard
property
// No ambiguity about what this window property means

getScrollPosition = function() {
return [window.pageXOffset, window.pageYOffset];
};
} else if (document.documentElement && 'number' == typeof
document.documentElement.scrollTop) {

// Proprietary IE properties, copied widely by others; often 0,0 in
mobile browsers,
// Ambiguous as many mobiles represent an un-scrolled document (i.e.
scrollHeight == clientHeight), regardless of which portion of document
is viewable

getScrollPosition = function() {
return [document.documentElement.scrollLeft,
document.documentElement.scrollTop];
};
}

As usual, simplified feature detection (use isHost* functions) and
untested. Paste at your own risk.

One other thing, I wouldn't trust that you can get the mouse position
in a click or dblclick listener. Not sure what the standard
recommendation is, but I know I never retrieve the position from
anything but mousedown/move/up. ISTM that, at least traditionally,
that's all you can expect to work reliably. And by "work", I mean
across most browsers released this century. There's no way anything
like this can be considered cross-browser. There's at least a couple
of other pairs of properties where at least some mobiles insist on
stashing their "scroll" position (offsetLeft/Top comes to mind). So
there's at least one more prong and not based on any sort of logic,
just observation.

Needless to say, getting the "viewport" scroll position is something
to avoid whenever possible (most of the time). But as soon as you
start with the mouse position, at least for years to come, you
introduce that dependency.

Having said all of that, perhaps somebody out there who has actually
needed to tackle this problem has a cleaner, context-specific solution
that works in an acceptable subset of browsers. The big issue is that
there is no way to feature test the scroll position in advance, short
of actually setting the scroll position (which is clearly out of the
question).

J.R.

unread,
Dec 3, 2011, 4:50:27 PM12/3/11
to
window.pageYOffset is available as of IE9, FF3+, Safari 4+, Chrome 4+,
Opera 10+.

IE 8 and older browsers in standards-compliant mode (strict mode) would use:

if (document.documentElement && document.documentElement.scrollTop) {
return document.documentElement.scrollTop;
}

But IE in quirks mode (tested with IE8) would use:
if (document.body) {
return document.body.scrollTop;
}

--
Joao Rodrigues (J.R.)


> getScrollPosition = function() {
> return [window.pageXOffset, window.pageYOffset];
> };
> } else if (document.documentElement&& 'number' == typeof

David Mark

unread,
Dec 3, 2011, 6:50:08 PM12/3/11
to
I suspected MS might add those at some point, but never had cause to
confirm. Thanks.

>
> IE 8 and older browsers in standards-compliant mode (strict mode) would use:
>
> if (document.documentElement && document.documentElement.scrollTop) {
>    return document.documentElement.scrollTop;
>
> }
>
> But IE in quirks mode (tested with IE8) would use:
> if (document.body) {
>    return document.body.scrollTop;
>
> }

Something like that.

David Mark

unread,
Dec 3, 2011, 7:38:11 PM12/3/11
to
On Dec 3, 4:50 pm, "J.R." <groups_j...@yahoo.com.br> wrote:
> On 03/12/2011 00:38, David Mark wrote:
>
>
>
>
>
>
>
>
>
> > On Nov 11, 4:33 pm, Dr J R Stockton<reply1...@merlyn.demon.co.uk>
> > wrote:
>
> >> OneTipmight be the answer to "I have an on-screen element, of known
> >> size, with an on[dbl]click method; how do I obtain the co-ordinates of a
> >> [double-]click with respect to a given position in the element itself?"
>
> > Tricky.  :)
>
> > Your best bet is to see thetipof the day related to coordinates.
So let's finish this off. If you need it to work in IE 9 and
virtually every other browser made since the turn of the century:-

if ('number' == typeof window.pageXOffset) {
getScrollPosition = function() {
return [window.pageXOffset, window.pageYOffset];
};

// I suppose jQuery users would prefer gPtrPosRel2Win or some such
"concise" BS. :)

// Works for mouse or touch

getPointerPositionRelativeToViewport = function(e) {
return [e.pageX - window.pageXOffset, e.pageY -
window.pageYOffset]
};
}

Piece of cake (as this context usually is).

Now, what if you need IE 6-8 to join in the fun?

Put this script inside conditional comments (so the others don't
download it):-

// Last test is to exclude IE quirks mode and IE 5

if (document.documentElement && 'number' == typeof
document.documentElement.scrollLeft &&
document.documentElement.clientWidth) {
getScrollPosition = function() {

// Note: optimize by saving a reference to documentElement (saves
two dot operations)

return [document.documentElement.scrollLeft,
document.documentElement.scrollTop];
};

getPointerPositionRelativeToViewport = function(e) {

// Yes, we would use these in non-IE browsers too if history of
implementation
// wasn't atrocious. Perhaps in a few years...
// Regardless, you know for sure these work as advertised in
legacy IE versions

// NOTE: the HTML border "issue" is irrelevant as same offset for
element positions

return [e.clientX, e.clientY]
};
}

// Detect API features (never changes, regardless of specific
renditions used)
// Self-documenting (really, not like jQuery's claims)

if (getScrollPosition && getPointerPositionRelativeToViewport) {

var el = getElementById('johnstockton');

el.onmousedown = ...
el.ondblclick = ...


}

Will leave rest as an exercise. Hint: need to add
getElementRectangleRelativeToViewport (see
getElementPositionRelativeToViewport from previous tip). Also need
isPointInRectangle, which is trivial and browser agnostic (so no need
to make that function's creation conditional).

That solution should work in virtually every browser ever made.
Untested; no warranty implied.

Not to beat a dead horse, but would love to see this attempted with
jQuery, jQuery UI, jQuery Mobile or whatever. You are pretty much
screwed before you start with those things as the context is lost in a
mudslide of confused logic and bad inferences. Or perhaps I'm just
jealous or trying to steal their "business". :)

Is learning so distasteful as to justify dumping any old piece of junk
on your hapless users? Nothing loses customers faster than a half-
functioning UI. ;)

David Mark

unread,
Dec 3, 2011, 8:14:27 PM12/3/11
to
And actually, the way it ended up (with the two functions working
independently), don't even need getScrollPosition. Could have written
getPointerPositionRelativeToViewport to call the getScrollPosition
function, but that would just slow things down (and retrieving pointer
position needs to be as fast as possible). Better to render the two
functions as a unit (if the other one is needed at all).

if (getPointerPositionRelativeToViewport) {
var el = getElementById('johnstockton');
el.onmousedown = ...
el.ondblclick = ...
}

> Will leave rest as an exercise.  Hint: need to add
> getElementRectangleRelativeToViewport (see
> getElementPositionRelativeToViewport from previoustip).  Also need
> isPointInRectangle, which is trivial and browser agnostic (so no need
> to make that function's creation conditional).

And may not need the latter either; depends on what this is to be used
for (was envisioning a single canvas with regions delineated by
drawing). As always, YMMV.

Don't forget to buy the book when it comes out. It's got hundreds of
renditions like these, covering virtually every common browser
scripting task. Alternatively, you can download some context-less
blob of BS from the Web and pray it works for at least some of your
visitors for a while; then download another, and another... And
eventually those "best minds in the industry" (quote from a recent
blog post) will solve all of *your* problems perfectly (as if they
know you).

David Mark

unread,
Dec 3, 2011, 10:17:53 PM12/3/11
to
On Dec 3, 4:50 pm, "J.R." <groups_j...@yahoo.com.br> wrote:
BTW, it's certainly in every FF and Chrome. Likely Safari too. And
Opera as far back as I can remember.

Are these PPK numbers? :)

Hans-Georg Michna

unread,
Dec 4, 2011, 5:07:42 AM12/4/11
to
On Sat, 3 Dec 2011 17:14:27 -0800 (PST), David Mark wrote:

>... buy the book when it comes out.

Which book? Have I missed something?

Hans-Georg

David Mark

unread,
Dec 4, 2011, 5:45:02 AM12/4/11
to
On Dec 4, 5:07 am, Hans-Georg Michna <hans-
Not yet. :)

David Mark

unread,
Dec 4, 2011, 4:37:21 PM12/4/11
to
On Dec 3, 7:38 pm, David Mark <dmark.cins...@gmail.com> wrote:
A solution. This is the "good riddance to bad baggage" environment
context.

// This function fades away in IE 8- and compatibility modes

if ('number' == typeof window.pageXOffset) {

  // Works for mouse or touch

  getPointerPositionRelativeToViewport = function(e) {
    return [e.pageX - window.pageXOffset, e.pageY -
window.pageYOffset]
  };
}

/*
* Need these two API functions
* See position tip for first function
* Should need the normalized rendition that subtracts
documentElement.clientLeft/Top
* as comparing element position to pointer position results that
don't have the
* client-related quirk (i.e. getBoundingClientRect, clientX/Y not
involved)
* Quirk must be present or absent on both sides of the equation to be
factored out. ;)
*/

if (getElementPositionRelativeToViewport &&
getPointerPositionRelativeToViewport) {
  var el = getElementById('johnstockton');
var pointerPosition;

// NOTE: should only respond to one event type at a time

  el.onmousedown = el.ontouchstart = function(e) {
pointerPosition = getPointerPositionRelativeToViewport(e);
};

  el.onclick = function(e) {

/*
* Make sure a mousedown/touchstart preceded the click on this
element
* If another mousedown listener hid an element that was covering
* the "johnstockton" element, could get click without mousedown
*/

if (pointerPosition) {
var elementPosition =
getElementPositionRelativeToViewport(this);
window.alert([pointerPosition[0] - elementPosition[0],
pointerPosition[1] - elementPosition[1]]);

// One click per mousedown/touchstart

pointerPosition = null;
}
};
}

If wrapped in a function, be sure to set el to null (to break circular
references). As usual, no warranty, may not be appropriate for your
needs, etc.

As mentioned, you can add this to create a legacy IE rendition,
perhaps even putting it inside conditional comments, loading it only
for version 8 and under (which will also catch compatibility mode).

if (document.documentElement && 'number' == typeof
document.documentElement.scrollLeft && 'number' == typeof
document.documentElement.clientLeft &&
document.documentElement.clientWidth) {
  getPointerPositionRelativeToViewport = function(e) {
    return [e.clientX - document.documentElement.clientLeft,
e.clientY - document.documentElement.clientTop]
  };
}

Note that this is also a normalized rendition as the results will be
compared to the results of the normalized element position function
that accounts for IE's chrome HTML border. Quirk is absent on both
sides of the equation.

It should be mentioned that it is best not to put borders on the HTML
element, otherwise ambiguity is introduced in the relationship between
clientLeft/Top values (normally 0) and element coordinates. Certainly
HTML borders are not part of the Chrome in other browsers that copied
getBoundingClientRect, so it is unrealistic to assume they treated the
HTML borders the same. Last I heard somebody was trying to stamp a
standard on this mess (and good luck to them), but that will only make
a difference on paper.

IIRC, all works out even with HTML borders in other browsers, but why
tempt fate? Probably doesn't need mentioning that putting borders on
the HTML element is crazy anyway. This is the sort of non-issue that
public libraries love to tackle.

I spent hours putting margins and borders on the HTML (body in quirks
mode) element when testing My Library. I suppose I could justify the
waste of time as an academic exercise, but wouldn't recommend using
the results over functions like the above. As soon as you lose sight
of your context, extraneous complications start to appear. This
happens automatically in projects that involve collaboration with lots
of other developers, each likely thinking in the context of their
current (downstream) efforts.

Doesn't take long before the best hint you can give about the
functions is that they pass some tests in some recent versions of
Chrome, Safari, Opera, Firefox and some versions/modes of IE. Other
browsers, which is the what today's browsers will be tomorrow, are
anyone's guess. The oft-heard line: "we don't care about [browser x]"
is truly indicative of a careless, cavalier and ultimately futile
approach to browser scripting.

Unless you want to be on an endless treadmill, "keeping up" with five
(then seven, then nine...) browsers, you want cross-browser code,
which tests features and does *nothing* in environments that fail.
Therefore, during development and testing, it is necessary to load a
script in at least *one* browser that is not expected to pass the
tests (usually an old browser). The jQuery way of wearing blinders
and quoting recent browser version numbers as the starting point of
their caring is a perfectly ridiculous strategy, particularly as rapid
change in browser differences (which jQuery ostensibly buffers) is
what neophytes fear the most. If the library developers are that
focused on Chrome 4+, Opera 10+, etc., you have to wonder how they
managed to screw up Opera 9- or Chrome 3-; probably because they were
so focused on Opera 9+ and Chrome 3+ at the time. This sort of
nonsense has been going on since the late 90's. Just steer clear of
projects with five browser icons lined up to indicate their perceived
"compatibility". Think Dynamic Drive with three more icons. ;)

Nothing is guaranteed, but cross-browser code has the best shot at
lasting from one cycle of browser "innovation" to the next and to fade
away gracefully as today's browsers go the way of Netscape 6.

When you consider mobile users, most are using "other browsers"
today. The browser in Android devices is not Chrome. iOS devices do
not run the same Safari as found on desktops. Then there are the
mobile versions of Opera and Firefox and the new Windows phones, which
are clearly not exactly the same as their desktop counterparts. And,
other than fortune tellers, who knows what's next?

David Mark

unread,
Dec 4, 2011, 7:01:12 PM12/4/11
to
>  * See positiontipfor first function
>  * Should need the normalized rendition that subtracts
> documentElement.clientLeft/Top
>  * as comparing element position to pointer position results that
> don't have the
>  * client-related quirk (i.e. getBoundingClientRect, clientX/Y not
> involved)
>  * Quirk must be present or absent on both sides of the equation to be
> factored out. ;)
>  */
>
> if (getElementPositionRelativeToViewport &&
> getPointerPositionRelativeToViewport) {
>    var el = getElementById('johnstockton');
>    var pointerPosition;
>
>    // NOTE: should only respond to one event type at a time

Didn't make this very clear. I mean you will get dupes with touch
input (both touchstart and mousedown)

>
>    el.onmousedown = el.ontouchstart = function(e) {

Oops. Didn't use "addEvent" wrapper, so no "e" in IE.

if (!e) {
e = window.event;
}

Normally would use a wrapper and hopefully one that avoids the
circular reference issue as well. Follow the JSPerf link on original
post to find a couple of those. It's ugly to have such IE-isms in the
application code.

>      pointerPosition = getPointerPositionRelativeToViewport(e);
>    };
>
>    el.onclick = function(e) {

Don't actually need "e" here.

David Mark

unread,
Dec 4, 2011, 7:28:10 PM12/4/11
to
Kind of trailed off there, didn't I? :) See attachTouchListeners in
Touch add-on. If it gets touch events, it ignores corresponding mouse
events. Doesn't matter so much in this example where the mousedown
listener will just overwrite the previously stored array reference
with a reference to an identical array. ISTM that if "touch" objects
(or just one) present, one is to be used in lieu of the event object.

>
>
>
> >    el.onmousedown = el.ontouchstart = function(e) {
>
> Oops.  Didn't use "addEvent" wrapper, so no "e" in IE.
>
> if (!e) {
>   e = window.event;
>
> }

So here, if not using a function like attachTouchListeners, would need
to set e to reference a touch object. The touch object is passed to
getPointerPosition*, not the event object. When using that wrapper,
the event object is irrelevant as target and touch object passed to
listeners and returning false prevents the default behavior.

Should have probably left out the touch stuff from this example.
Sorry for any confusion. :)

David Mark

unread,
Dec 4, 2011, 9:56:42 PM12/4/11
to
Should also point out that the window.event substitution is unneeded
unless using legacy IE rendition. If not, "addEvent" wrapper adds
nothing to example. And as performance a non-issue,
attachTouchListeners (or ontouchstart) use unnecessary.

John G Harris

unread,
Dec 5, 2011, 9:39:43 AM12/5/11
to
On Sun, 4 Dec 2011 at 18:56:42, in comp.lang.javascript, David Mark
wrote:
>On Dec 4, 7:28 pm, David Mark <dmark.cins...@gmail.com> wrote:
>> On Dec 4, 7:01 pm, David Mark <dmark.cins...@gmail.com> wrote:
>>
>>
>>
>>
>>
>> > On Dec 4, 4:37 pm, David Mark <dmark.cins...@gmail.com> wrote:
>>
>> > > On Dec 3, 7:38 pm, David Mark <dmark.cins...@gmail.com> wrote:
>>
>> > > > On Dec 3, 4:50 pm, "J.R." <groups_j...@yahoo.com.br> wrote:
>>
>> > > > > On 03/12/2011 00:38, David Mark wrote:
>>
>> > > > > > On Nov 11, 4:33 pm, Dr J R Stockton<reply1...@merlyn.demon.co.uk>
>> > > > > > wrote:
>>
>> > > > > >> OneTipmight be the answer to "I have an on-screen element,
<snip>

Please please shorten your quoted text. My scroll wheel is getting red
hot.

John
--
John Harris

David Mark

unread,
Dec 5, 2011, 2:00:47 PM12/5/11
to
Yeah, I need to stop responding in mobile browser.


Frobernik

unread,
Dec 6, 2011, 4:18:00 PM12/6/11
to
On 03/12/2011 00:08, David Mark wrote:
> On Nov 17, 5:43 pm, Frobernik<nos...@nospam.com> wrote:
>> On 10/11/2011 21:12, Matt McDonald wrote:
>>> On 11-11-10 12:47 PM, Ant wrote:
>>> The biggest blow is marketing. Take a gander at
>>> "HTML 5 Boilerplate"'s website (won't link). It's chock full of
>>> over-the-top marketing speak. The first time I read it, I was
>>> heavily offended by the textual content. I seriously pondered
>>> if it was written by a prepubescent.
>>
>> Well there are people (apart from the punters on here) fighting
>> modernizer,jQueryand other junk (will link)
>
> I see you have almost *one million* posts on here. Punter. :)
>
> And who is fighting what? Just throw them away.

This should get Platinum Czar Punter post of 2011 I think!

If only it were that simple - most designers and a lot of developers
would rather copy and paste or be hypnotised by Googled bulls**t than
actually get familiar with the browser or even do some work :(

>> http://nefariousdesigns.co.uk/archive/2011/05/sniff-my-browser-the-mo...
> I've seen it. Somebody doesn't like Modrnizer (sp?). I don't like it
> either. Imagine, a monolithic feature detection script that
> pigeonholes browsers according to some predetermined series of
> "standard" tests. Adds a ton of classes too. No thanks!

Moronizers own website is ridiculous. The custom font typefacing has had
to be hidden until the page finishes loading (thats assuming the JS
finishes loading!) *face palm*

Frobernik

David Mark

unread,
Dec 6, 2011, 5:13:31 PM12/6/11
to
On Dec 6, 4:18 pm, Frobernik <nos...@nospam.com> wrote:
> On 03/12/2011 00:08, David Mark wrote:
>
> > On Nov 17, 5:43 pm, Frobernik<nos...@nospam.com>  wrote:
> >> On 10/11/2011 21:12, Matt McDonald wrote:
> >>> On 11-11-10 12:47 PM, Ant wrote:
> >>> The biggest blow is marketing. Take a gander at
> >>> "HTML 5 Boilerplate"'s website (won't link). It's chock full of
> >>> over-the-top marketing speak. The first time I read it, I was
> >>> heavily offended by the textual content. I seriously pondered
> >>> if it was written by a prepubescent.
>
> >> Well there are people (apart from the punters on here) fighting
> >> modernizer,jQueryand other junk (will link)
>
> > I see you have almost *one million* posts on here.  Punter.  :)
>
> > And who is fighting what?  Just throw them away.
>
> This should get Platinum Czar Punter post of 2011 I think!

That's very colorful, but don't understand a word of it. :)

>
> If only it were that simple - most designers and a lot of developers
> would rather copy and paste or be hypnotised by Googled bulls**t than
> actually get familiar with the browser or even do some work :(

Correct. But designers can get away with it as they only need their
proof of concept to work in one browser (the one they use to demo).
Trouble is that inexperienced and overconfident developers think they
can just test the mock-up in a few more browsers and throw it on the
client's server. This poor behavior is positively reinforced by
clients who just don't know any better.

>
> >>http://nefariousdesigns.co.uk/archive/2011/05/sniff-my-browser-the-mo...
> > I've seen it.  Somebody doesn't like Modrnizer (sp?).  I don't like it
> > either.  Imagine, a monolithic feature detection script that
> > pigeonholes browsers according to some predetermined series of
> > "standard" tests.  Adds a ton of classes too.  No thanks!
>
> Moronizers own website is ridiculous. The custom font typefacing has had
> to be hidden until the page finishes loading (thats assuming the JS
> finishes loading!) *face palm*

Yes, that sounds pretty backwards to me. I see lots of sites that
combine that thing with jQuery and jQuery plug-ins. An "HTML5
modernizer" combined with a bunch of old IE6/7 hacks? It's the Sybil
pattern. :)

As you mentioned, many developers just window shop for these silly
scripts like they were designers. They pile on all everything that
looks cool in their installed browsers and wait for the inevitable
call back when it all falls apart. Their ready excuse is that "nobody
is perfect"; but there is a large gulf between absolute perfection and
gross incompetence. ;)

Just had one of those clods dial in on Twitter. They said that
something was wrong with some of the old My Library examples on the
new Amazon "Silk" browser (Kindle Fire). Their juxtaposition was that
"jQuery UI works". :)

Of course, jQuery UI is completely inappropriate for mobile devices
(or anything else, really). I wouldn't find it surprising that
whatever jQuery demo they were peering at seemed to "work" in a
browser that the jQuery developers were peering at when they wrote the
thing. The question is whether it should be expected to work in
browsers unknown to the developers (e.g. future versions, new
browsers, new devices, etc.). History and good sense say no as such
projects are always about overreaching to "keep up" with current,
popular browsers, usually at the expense of others (the browsers the
developers claim not to "care" about).

And if jQuery UI works so well on mobile, why is there a jQuery
Mobile? Even more curious, how can anyone even say "jQuery Mobile"
with a straight face? I just saw a blog that mentioned they
"finalized" the thing recently, and it went on to list five or six
browsers (with specific version numbers, of course) that it
"supports". What do you guess it does in every other browser released
this century? Finalized?! For how many weeks? Seems these guys
never learn.

Developers should wake up and realize that relying on bored hobbyists
to ferret out and "fix" bugs, one browser version at a time, is
futile. They should be learning to *avoid* bugs, not trying to find
them. They sure as hell shouldn't be sending out teams of neophytes
to find (and often misinterpret) issues.

Many developers think browsers are far buggier than they are, simply
because they have spent years watching projects like jQuery stumble,
bumble, fumble, etc. This reinforces their perceived need for
jQuery. After all, if the "best minds in the industry" are having
such a time of it... It's a self-perpetuating cycle. jQuery makes it
look really difficult and designers/developers assume such frustration
is par for the course.
0 new messages