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

Discussion in 'Javascript' started by David Mark, Nov 10, 2011.

  1. Thanks again! Nice examples.

    Hans-Georg
     
    Hans-Georg Michna, Nov 13, 2011
    #21
    1. Advertisements

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

    Hans-Georg
     
    Hans-Georg Michna, Nov 13, 2011
    #22
    1. Advertisements

  3. David Mark

    J.R. Guest

    No, but you can't retrieve the width / height of a scrollable element's
    content with just clientHeight and clientWidth properties.

    ACK.
     
    J.R., Nov 14, 2011
    #23
  4. David Mark

    RobG Guest

    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.
     
    RobG, Nov 14, 2011
    #24
  5. (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
    ->.<-
     
    Thomas 'PointedEars' Lahn, Nov 14, 2011
    #25
  6. David Mark

    Tim Down Guest

    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
     
    Tim Down, Nov 14, 2011
    #26
  7. David Mark

    J.R. Guest

    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).
     
    J.R., Nov 14, 2011
    #27
  8. 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
    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
     
    Thomas 'PointedEars' Lahn, Nov 14, 2011
    #28
  9. 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
    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
     
    Thomas 'PointedEars' Lahn, Nov 14, 2011
    #29
  10. Thanks! Another interesting example.

    Hans-Georg
     
    Hans-Georg Michna, Nov 15, 2011
    #30
  11. David Mark

    RobG Guest

    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/ >
     
    RobG, Nov 17, 2011
    #31
  12. David Mark

    Eric Bednarz Guest

    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. :)
     
    Eric Bednarz, Nov 17, 2011
    #32
  13. Don't be ridiculous. Oh wait, it's you.
    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.
    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
     
    Thomas 'PointedEars' Lahn, Nov 17, 2011
    #33
  14. David Mark

    Eric Bednarz Guest

    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.â€
    Says the one who is constantly beating reality with a big hammer until
    it fits into his views.
    That’s a fair point.
    Cases where it isn’t Opera’s host object are not really interesting.
    See above. The only thing I have overlooked is the case where it is
    pointless to reply.
     
    Eric Bednarz, Nov 17, 2011
    #34
  15. David Mark

    Eric Bednarz Guest

    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.
    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.
    But why? Were there *practical* problems that are not related to
    validation?
    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).
    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.
    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.
     
    Eric Bednarz, Nov 17, 2011
    #35
  16. David Mark

    Frobernik Guest

    "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
    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
     
    Frobernik, Nov 17, 2011
    #36
  17. David Mark

    David Mark Guest

    I suppose.

    It's necessary to have the included script.


     The necessary further information is not

    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, Dec 2, 2011
    #37
  18. David Mark

    David Mark Guest


    I don't follow. Use for what?
    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.
     
    David Mark, Dec 2, 2011
    #38
  19. David Mark

    David Mark Guest


    No problem there; overflowed content not supposed to count.
    No. That's getScrollDimensions. And may well be susceptible to quirks
    in some cases. Particularly the HTML element.

    The irony
    As were others. IE 4.
     
    David Mark, Dec 2, 2011
    #39
  20. David Mark

    David Mark Guest

    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.
    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.
    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, Dec 2, 2011
    #40
    1. Advertisements

Ask a Question

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

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