opacity

Discussion in 'Javascript' started by Darko, Nov 19, 2007.

  1. Darko

    Darko Guest

    Hi,

    I'm trying to get and set an element's opacity, but I'm stuck with,
    what a hell of surprise, Internet Explorer. As for getting the
    element's opacity, I have the following (not working) lines of code:

    if ( targetObject.filters && targetObject.filters.length > 0 )
    opacity =
    targetObject.filters.item("DXImageTransform.Microsoft.Alpha").Opacity;

    Setting it, I tried:

    if ( targetObject.filters && targetObject.filters.length > 0 )
    targetObject.setAttribute( "style", "filter: alpha(opacity=" +
    opacity + ")" );

    None work. I have digged these out from some MSDN article, but they
    aren't working, at least they don't work in to me available IE 6.0. Do
    you have better (i.e. working) ways of yours?

    Thanks

    Darko
     
    Darko, Nov 19, 2007
    #1
    1. Advertising

  2. Darko

    Stevo Guest

    Darko wrote:
    > I'm trying to get and set an element's opacity, but I'm stuck with,
    > what a hell of surprise, Internet Explorer. As for getting the
    > element's opacity, I have the following (not working) lines of code:


    I don't know what was wrong there, but I see you think that opacity is
    only available for IE. There's an equivalent feature in Mozilla browsers
    using custom CSS properties. You'll have to sniff for the browsers and
    branch your code to handle it (totally) differently, but it's definitely
    possible. Not that I've ever used it, but I have seen itt.
     
    Stevo, Nov 20, 2007
    #2
    1. Advertising

  3. Darko

    VK Guest

    On Nov 19, 10:38 pm, Darko <> wrote:
    > As for getting the
    > element's opacity, I have the following (not working) lines of code:
    >
    > if ( targetObject.filters && targetObject.filters.length > 0 )
    > opacity =
    > targetObject.filters.item("DXImageTransform.Microsoft.Alpha").Opacity;
    >
    > Setting it, I tried:
    >
    > if ( targetObject.filters && targetObject.filters.length > 0 )
    > targetObject.setAttribute( "style", "filter: alpha(opacity=" +
    > opacity + ")" );
    >
    > None work. I have digged these out from some MSDN article


    Do you still remember which one?

    > but they
    > aren't working, at least they don't work in to me available IE 6.0.


    Of course they don't: setAttribute method has nothing to do with it.

    > Do you have better (i.e. working) ways of yours?


    Not mine, but tested working:

    http://www.quirksmode.org/js/opacity.html
     
    VK, Nov 20, 2007
    #3
  4. Darko

    Stevo Guest

    Stevo, Nov 20, 2007
    #4
  5. VK wrote:
    > On Nov 19, 10:38 pm, Darko <> wrote:
    >> As for getting the
    >> element's opacity, I have the following (not working) lines of code:
    >>
    >> if ( targetObject.filters && targetObject.filters.length > 0 )
    >> opacity =
    >> targetObject.filters.item("DXImageTransform.Microsoft.Alpha").Opacity;
    >>
    >> Setting it, I tried:
    >>
    >> if ( targetObject.filters && targetObject.filters.length > 0 )
    >> targetObject.setAttribute( "style", "filter: alpha(opacity=" +
    >> opacity + ")" );
    >>
    >> None work. I have digged these out from some MSDN article

    >
    > Do you still remember which one?


    Probably
    http://msdn2.microsoft.com/en-us/library/ms532847.aspx#Scripting_Filters or
    a previous version.

    >> but they
    >> aren't working, at least they don't work in to me available IE 6.0.

    >
    > Of course they don't: setAttribute method has nothing to do with it.


    To be precise, setAttribute() does not seem to work there *for IE*.

    >> Do you have better (i.e. working) ways of yours?

    >
    > Not mine, but tested working:
    >
    > http://www.quirksmode.org/js/opacity.html


    However, it does not make sense in passing ranges from 0 to 10 and then
    computing the required value twice. With the division for `opacity', there
    is even a rounding error involved, needlessly. It makes more sense have
    `value' range from 0 to 1 (thereby to pass the percentage x% as 0.0x to the
    function); the computation will have to be done only once (for `filter'),
    and the used values will be as exact as the layout engine allows it:

    function setOpacity(value)
    {
    testObj.style.opacity = value;
    testObj.style.filter = 'alpha(opacity=' + value * 100 + ')';
    }


    PointedEars
    --
    Prototype.js was written by people who don't know javascript for people
    who don't know javascript. People who don't know javascript are not
    the best source of advice on designing systems that use javascript.
    -- Richard Cornford, cljs, <f806at$ail$1$>
     
    Thomas 'PointedEars' Lahn, Nov 20, 2007
    #5
  6. Darko

    Guest

    On Nov 19, 11:38 am, Darko <> wrote:
    > Hi,
    >
    > I'm trying to get and set an element's opacity, but I'm stuck with,
    > what a hell of surprise, Internet Explorer. As for getting the
    > element's opacity, I have the following (not working) lines of code:
    >
    > if ( targetObject.filters && targetObject.filters.length > 0 )
    > opacity =
    > targetObject.filters.item("DXImageTransform.Microsoft.Alpha").Opacity;
    >
    > Setting it, I tried:
    >
    > if ( targetObject.filters && targetObject.filters.length > 0 )
    > targetObject.setAttribute( "style", "filter: alpha(opacity=" +
    > opacity + ")" );
    >
    > None work. I have digged these out from some MSDN article, but they
    > aren't working, at least they don't work in to me available IE 6.0. Do
    > you have better (i.e. working) ways of yours?
    >


    Does the element have a layout? In IE terms, it's gotta have position
    or height/width for proprietary hasLayout to be be true.

    DXImageTransform can work for background images, too, but doesn't let
    you set any other background-properties (like background-position).

    Regarding other comments on this thread: Opacity is CSS3, not a moz-
    specific css. it works in Mozilla, Webkit and Opera.

    Garrett

    > Thanks
    >
    > Darko
     
    , Nov 20, 2007
    #6
  7. Darko

    Darko Guest

    On Nov 20, 4:03 pm, Stevo <> wrote:
    > Darko wrote:
    > > I'm trying to get and set an element's opacity, but I'm stuck with,
    > > what a hell of surprise, Internet Explorer. As for getting the
    > > element's opacity, I have the following (not working) lines of code:

    >
    > I don't know what was wrong there, but I see you think that opacity is
    > only available for IE. There's an equivalent feature in Mozilla browsers
    > using custom CSS properties. You'll have to sniff for the browsers and
    > branch your code to handle it (totally) differently, but it's definitely
    > possible. Not that I've ever used it, but I have seen itt.


    No, I don't think that. I use "opacity" regularly for other browsers,
    but
    it doesn't work with IE. So I googled out that IE needs this filter
    thing,
    which they claim works by accessing .filters subobject, but it seems
    as if it
    does not. So I gave up and did as it was only possible, using
    ..style.filter = ..., which I like less than the proposed solution from
    MSDN
    (which doesn't work). Never mind.
     
    Darko, Nov 21, 2007
    #7
  8. Darko

    Darko Guest

    On Nov 19, 8:38 pm, Darko <> wrote:
    > Hi,
    >
    > I'm trying to get and set an element's opacity, but I'm stuck with,
    > what a hell of surprise, Internet Explorer. As for getting the
    > element's opacity, I have the following (not working) lines of code:
    >
    > if ( targetObject.filters && targetObject.filters.length > 0 )
    > opacity =
    > targetObject.filters.item("DXImageTransform.Microsoft.Alpha").Opacity;
    >
    > Setting it, I tried:
    >
    > if ( targetObject.filters && targetObject.filters.length > 0 )
    > targetObject.setAttribute( "style", "filter: alpha(opacity=" +
    > opacity + ")" );
    >
    > None work. I have digged these out from some MSDN article, but they
    > aren't working, at least they don't work in to me available IE 6.0. Do
    > you have better (i.e. working) ways of yours?
    >
    > Thanks
    >
    > Darko


    As for opacity, now that I gave in and had it .style.filter = "...",
    it finally
    works well with IE, too. Another problem though - Konqueror. It seems
    to ignore:
    opacity
    -moz-opacity
    -khtml-opacity
    filter

    Wtf. does it need? Does Konqueror actually support element's opacity?
    I wouldn't mind
    the bloody Konqueror not working properly with my site, but as I
    understand Safari uses
    the same KHTML engine, so I reckon if Konqueror doesn't work (as it
    doesn't), then Safari
    won't neither. Am I right? Or Safari uses a KHTML branch that actually
    supports the standard?

    Thanks
     
    Darko, Nov 21, 2007
    #8
  9. wrote:
    > On Nov 19, 11:38 am, Darko <> wrote:
    >> I'm trying to get and set an element's opacity, but I'm stuck with,
    >> what a hell of surprise, Internet Explorer. As for getting the
    >> element's opacity, I have the following (not working) lines of code:
    >>
    >> if ( targetObject.filters && targetObject.filters.length > 0 )
    >> opacity =
    >> targetObject.filters.item("DXImageTransform.Microsoft.Alpha").Opacity;
    >>
    >> Setting it, I tried:
    >>
    >> if ( targetObject.filters && targetObject.filters.length > 0 )
    >> targetObject.setAttribute( "style", "filter: alpha(opacity=" +
    >> opacity + ")" );
    >>
    >> None work. I have digged these out from some MSDN article, but they
    >> aren't working, at least they don't work in to me available IE 6.0. Do
    >> you have better (i.e. working) ways of yours?

    >
    > Does the element have a layout? In IE terms, it's gotta have position
    > or height/width for proprietary hasLayout to be be true.


    The issue is not that the element has "no layout" which you could
    have figured out by now. And nobody mentioned `hasLayout' (whatever
    that might be) until now.

    > DXImageTransform can work for background images, too,


    I have to see that before I believe it.

    > but doesn't let you set any other background-properties (like
    > background-position).


    You are probably describing the following PNGA workaround for IE 6:

    #portal-logo {
    background: none;
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,
    sizingMethod=scale src='bannertop_right.png');
    }

    In which case the background image is *disabled* in order to apply the
    filter. The result is not a real background image.

    Please learn to quote.


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
     
    Thomas 'PointedEars' Lahn, Nov 21, 2007
    #9
  10. David Mark posted his code for setting opacity

    <URL http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/792457773ca7cf01/4763865f827f7605>

    and with his subsequent corrections I believe he intended to post the
    following


    var global = this;
    var setOpacity = (function() {
    var i, l, html;
    var doc = global.document;
    var opacityStyles = ['opacity', 'MozOpacity', 'KhtmlOpacity'];

    if (doc) {
    html = (doc.all[0].tagName == '!')?doc.all[1]:doc.all[0];
    if (!html && doc.all && doc.all[0]) {
    html = (doc.all[0].tagName == '!')?doc.all[0]:doc.all[1];
    }
    }
    if (html && html.style) {
    if (typeof html.style.filter != 'undefined') {
    return function(el, o) {
    var f;
    if (el.filters) {
    if (el.currentStyle && !el.currentStyle.hasLayout) {
    el.style.zoom = 1;
    }
    f = el.filters.alpha;
    if (typeof(f) != 'undefined') {
    if (o == 1) {
    f.enabled = false;
    }
    else {
    f.enabled = true;
    f.opacity = o * 100;
    }
    }
    else {
    if (el.style && typeof(el.style.filter) != 'undefined') {
    el.style.filter += "alpha(opacity=" + (o * 100) + ")";
    }
    }
    }
    };
    }
    i = 0;
    l = opacityStyles.length;
    while (i < l) {
    if (typeof(html.style[opacityStyles]) == 'string') {
    return (function(s) {
    return function(el, o) {
    el.style = o;
    };
    })(opacityStyles);
    }
    i++;
    }
    }

    })();


    I don't know what is trying to be accomplished with this part which
    doesn't work in Firefox as document.all is not available. Is this a
    way to get the document.documentElement object?

    if (doc) {
    html = (doc.all[0].tagName == '!')?doc.all[1]:doc.all[0];
    if (!html && doc.all && doc.all[0]) {
    html = (doc.all[0].tagName == '!')?doc.all[0]:doc.all[1];
    }
    }


    --------------------------------------------

    The code I have been using is the following

    function setOpacity(el, val) {

    // If "val" is very small then when converted to a string
    // may will use scientific notation. This is not allowed in CSS.
    // For example, in Firefox 1.5
    // (0.0000001).toString() --> "1e-7"
    if (val<0.00001) {
    val = 0;
    }

    var s = el.style;

    if (typeof s.filter == 'string') {

    s.filter = s.filter.replace(/alpha\([^\)]*\)/gi,'') +
    ((val < 1) ? 'alpha(opacity='+val*100+')' : '');

    // alpha opacity only applies if the element "has layout".
    // IE4 has alpha but does not have currentStyle
    if (!el.currentStyle ||
    //IE 5+ can determine if element "has layout"
    !el.currentStyle.hasLayout) {
    // setting zoom is one of the ways to insure
    // an element "has layout"
    el.style.zoom = 1;
    }
    } else {
    // if (early release edition of Firefox && val === 1) {
    // // This trick is from Scriptaculous
    // // Some version of Firefox (before 1.5?) flickers
    // // when animating opacity up to a value of 1.
    // // If this trick is to be used the test will probably be
    // // expensive and should only be preformed the first time.
    // //
    // // Apparently using this trick increases the weight of
    // // the DOM, for rendering speed?
    //
    // val = 0.999999;
    // }

    // Mac/Firefox-1.5, Mac/Opera-9, Mac/Safari-2,
    // Win/NetscapeNavigator-8.0, KDE4/Konqueror
    s.opacity = val;
    // Win/NetscapeNavigator 6.0/7.0/8.0, Mac/Firefox-1.5
    s.MozOpacity = val;
    // -khtml-opacity does not apply to any version of Konqueror
    // according to the
    // folks on irc.freenode.net#kde. I set up some tests and
    // one person ran them on
    // development versions of KDE 4 and this is not supported
    // Konqueror for KDE 4
    // will be the first Konqueror version to support opacity
    // settings.
    // These KDE folks also told me that it was Safari 1.1 that
    // supported the
    // property below. I don't have anything less then 1.3
    // anymore and have only tested
    // on 2.0 so far. This does not work with Safari 2.0
    s.KhtmlOpacity = val; // TODO some net sources have KHTMLOpacity
    // YUI had this and I don't think it would work since
    // their -moz-opacity didn't work
    //s['-khtml-opacity'] = val;
    }
    }


    Peter
     
    Peter Michaux, Nov 21, 2007
    #10
  11. Darko

    Guest

    On Nov 21, 4:35 pm, Peter Michaux <> wrote:
    > David Mark posted his code for settingopacity
    >
    > <URLhttp://groups.google.com/group/comp.lang.javascript/browse_frm/thread...>
    >
    > and with his subsequent corrections I believe he intended to post the
    > following
    >
    > var global = this;
    > var setOpacity = (function() {
    > var i, l, html;
    > var doc = global.document;
    > var opacityStyles = ['opacity', 'MozOpacity', 'KhtmlOpacity'];
    >
    > if (doc) {
    > html = (doc.all[0].tagName == '!')?doc.all[1]:doc.all[0];
    > if (!html && doc.all && doc.all[0]) {
    > html = (doc.all[0].tagName == '!')?doc.all[0]:doc.all[1];
    > }
    > }
    > if (html && html.style) {
    > if (typeof html.style.filter != 'undefined') {
    > return function(el, o) {
    > var f;
    > if (el.filters) {
    > if (el.currentStyle && !el.currentStyle.hasLayout) {
    > el.style.zoom = 1;
    > }
    > f = el.filters.alpha;
    > if (typeof(f) != 'undefined') {
    > if (o == 1) {
    > f.enabled = false;
    > }
    > else {
    > f.enabled = true;
    > f.opacity= o * 100;
    > }
    > }
    > else {
    > if (el.style && typeof(el.style.filter) != 'undefined') {
    > el.style.filter += "alpha(opacity=" + (o * 100) + ")";
    > }
    > }
    > }
    > };
    > }
    > i = 0;
    > l = opacityStyles.length;
    > while (i < l) {
    > if (typeof(html.style[opacityStyles]) == 'string') {
    > return (function(s) {
    > return function(el, o) {
    > el.style = o;
    > };
    > })(opacityStyles);
    > }
    > i++;
    > }
    > }
    >
    > })();
    >
    > I don't know what is trying to be accomplished with this part which
    > doesn't work in Firefox as document.all is not available. Is this a
    > way to get the document.documentElement object?


    There appears to be a missing line from this transcription:

    html = (doc.getElementsByTagName)?doc.getElementsByTagName('html')
    [0]:doc.documentElement;


    And since I posted that, I updated the function to deal with an IE5
    DirectX incompatibility. I just updated it again to deal with the
    float to string issue you mention in your version, as well as to force
    the layout fix for IE4. I haven't tested the updated version.

    setOpacity = (function(el) {
    var i, l;
    var reOpacity = new RegExp('alpha\\(opacity=[^\\)]+\\)', 'i');
    var opacityStyles = ['opacity', 'MozOpacity', 'KhtmlOpacity'];
    if (typeof el.style.filter == 'string') {
    return function(el, o) {
    var f;
    if (el.filters) {
    if (!el.currentStyle || !el.currentStyle.hasLayout)
    { el.style.zoom = 1; }
    f = el.filters.alpha;
    if (typeof(f) != 'undefined') {
    f.enabled = o != 1;
    f.opacity = o * 100;
    }
    else {
    if (el.style.filter.indexOf('alpha(opacity=') == -1) {
    el.style.filter = 'alpha(opacity=' + (o * 100) + ')';
    }
    else {
    el.style.filter = el.style.filter.replace(reOpacity,
    "alpha(opacity=" + (o * 100) + ")");
    }
    }
    }
    };
    }
    i = 0;
    l = opacityStyles.length;
    while (i < l) {
    if (typeof(el.style[opacityStyles]) == 'string') {
    return (function(s) { return function(el, o) { el.style = (o < .
    00001)?0:eek:; }; })(opacityStyles);
    }
    i++;
    }
    })(html);

    The html variable passed to the one-off function is defined by a
    dependant function, which calls other dependant functions, etc., so I
    won't post that, but in a nutshell: try the documentElement, then try
    getElementsByTagName if it is a feature of the document object, then
    try doc.all.tags('html'). Otherwise, you are out of luck as there is
    nothing to test with and you shouldn't run the above code at all.

    >
    > if (doc) {
    > html = (doc.all[0].tagName == '!')?doc.all[1]:doc.all[0];
    > if (!html && doc.all && doc.all[0]) {
    > html = (doc.all[0].tagName == '!')?doc.all[0]:doc.all[1];
    > }
    >


    This was a silly way to get around doc.all returning the docType
    declaration. I had forgotten all about the tags method of the all
    object.

    > }
    >
    > --------------------------------------------
    >
    > The code I have been using is the following
    >
    > function setOpacity(el, val) {
    >
    > // If "val" is very small then when converted to a string
    > // may will use scientific notation. This is not allowed in CSS.
    > // For example, in Firefox 1.5
    > // (0.0000001).toString() --> "1e-7"
    > if (val<0.00001) {
    > val = 0;
    > }
    >
    > var s = el.style;
    >
    > if (typeof s.filter == 'string') {
    >
    > s.filter = s.filter.replace(/alpha\([^\)]*\)/gi,'') +
    > ((val < 1) ? 'alpha(opacity='+val*100+')' : '');
    >
    > // alphaopacityonly applies if the element "has layout".
    > // IE4 has alpha but does not have currentStyle
    > if (!el.currentStyle ||
    > //IE 5+ can determine if element "has layout"
    > !el.currentStyle.hasLayout) {
    > // setting zoom is one of the ways to insure
    > // an element "has layout"


    It's the best way I know to do it.

    > el.style.zoom = 1;
    > }
    > } else {
    > // if (early release edition of Firefox && val === 1) {
    > // // This trick is from Scriptaculous
    > // // Some version of Firefox (before 1.5?) flickers


    I've seen this recently. It drove me to distraction while I was
    working on a special effects module. I don't think it was an early
    release though. I am pretty sure it was the latest major release.

    > // // when animatingopacityup to a value of 1.
    > // // If this trick is to be used the test will probably be
    > // // expensive and should only be preformed the first time.
    > // //
    > // // Apparently using this trick increases the weight of
    > // // the DOM, for rendering speed?


    I am not sure what that means, but as I recall, setting .999999
    instead of 1 makes no visible difference, other than to eliminate the
    annoying flicker.

    > //
    > // val = 0.999999;
    > // }
    >
    > // Mac/Firefox-1.5, Mac/Opera-9, Mac/Safari-2,
    > // Win/NetscapeNavigator-8.0, KDE4/Konqueror
    > s.opacity= val;
    > // Win/NetscapeNavigator 6.0/7.0/8.0, Mac/Firefox-1.5
    > s.MozOpacity = val;
    > // -khtml-opacitydoes not apply to any version of Konqueror
    > // according to the
    > // folks on irc.freenode.net#kde. I set up some tests and
    > // one person ran them on
    > // development versions of KDE 4 and this is not supported
    > // Konqueror for KDE 4
    > // will be the first Konqueror version to supportopacity
    > // settings.
    > // These KDE folks also told me that it was Safari 1.1 that
    > // supported the
    > // property below. I don't have anything less then 1.3
    > // anymore and have only tested
    > // on 2.0 so far. This does not work with Safari 2.0
    > s.KhtmlOpacity = val; // TODO some net sources have KHTMLOpacity


    I can't help verify the original opacity code was written five or six
    years ago and I can't remember if I ever tested it with Safari back
    then. I have tested recently with Windows Safari, but I am pretty
    sure it used the standard opacity style. That being said,
    KHTMLOpacity just looks wrong to me.

    > // YUI had this and I don't think it would work since
    > // their -moz-opacitydidn't work
    > //s['-khtml-opacity'] = val;


    Clearly YUI is wrong in both cases.
     
    , Dec 4, 2007
    #11
  12. On Dec 4, 12:17 am, wrote:
    > On Nov 21, 4:35 pm, Peter Michaux <> wrote:


    [snip]

    > And since I posted that, I updated the function to deal with an IE5
    > DirectX incompatibility.


    What is that and what part of your code relates to this problem?

    [code below slightly reformatted to avoid wrapping]

    > I just updated it again to deal with the
    > float to string issue you mention in your version, as well as to force
    > the layout fix for IE4. I haven't tested the updated version.
    >
    > setOpacity = (function(el) {
    >
    > var i,l;
    > var reOpacity = new RegExp('alpha\\(opacity=[^\\)]+\\)', 'i');
    > var opacityStyles = ['opacity', 'MozOpacity', 'KhtmlOpacity'];
    >
    > if (typeof el.style.filter == 'string') {
    >
    > return function(el, o) {
    >
    > var f;
    >
    > if (el.filters) {
    > if (!el.currentStyle || !el.currentStyle.hasLayout) {
    > el.style.zoom = 1;
    > }
    >
    > f = el.filters.alpha;
    >
    > if (typeof(f) != 'undefined') {
    > f.enabled = o != 1;
    > f.opacity = o * 100;
    > }
    > else {
    > if (el.style.filter.indexOf('alpha(opacity=') == -1) {
    > el.style.filter = 'alpha(opacity=' + (o * 100) + ')';
    > }
    > else {
    > el.style.filter = el.style.filter.replace(reOpacity,
    > "alpha(opacity=" + (o * 100) + ")");
    > }
    > }


    What is the benefit of the above if-else with the first f.enabled/
    f.opacity branch? It is quite a bit of code bulk. Do you know of a
    browser with el.filters that will not work with the else branch above?

    Instead of the above 13 lines, in my version, I just write the
    following

    s.filter = s.filter.replace(/alpha\([^\)]*\)/gi,'') +
    ((val < 1) ? 'alpha(opacity='+val*100+')' : '');


    > }
    > };
    >
    > }
    >
    > i = 0;
    >
    > l = opacityStyles.length;
    >
    > while (i < l) {
    > if (typeof(el.style[opacityStyles]) == 'string') {
    > return (function(s) {
    > return function(el, o) {
    > el.style = (o < .00001)?0:eek:;
    > };
    > })(opacityStyles);
    > }
    > i++;
    > }
    >
    > })(html);
    >
    > The html variable passed to the one-off function is defined by a
    > dependant function, which calls other dependant functions, etc., so I
    > won't post that, but in a nutshell: try the documentElement, then try
    > getElementsByTagName if it is a feature of the document object, then
    > try doc.all.tags('html'). Otherwise, you are out of luck as there is
    > nothing to test with and you shouldn't run the above code at all.


    I can see that checking for document.documentElement and then falling
    back to document.all.tags('html')[0] is beneficial as IE4 can set
    opacity but doesn't have document.documentElement; however, what
    browser is enabled by adding a check with getElementsByTagName into
    the mix? I tested a bunch of browsers around the correct vintage and
    didn't find one where adding the getElementsByTagName check helps. I
    can see having the getElementsByTagName check for completeness but do
    you happen to know of a browser where this check is the one that works
    and document.documentElement and document.all.tags('html')[0] both
    don't work?

    Opera 5.02
    document.documentElement // undefined
    document.getElementsByTagName // undefined
    document.all.tags('html').length // 0
    document.all.tags('body').length // 1

    Opera 6.0
    document.documentElement // undefined
    document.getElementsByTagName('html').length // 0
    document.getElementsByTagName('body').length // 1
    document.all.tags('html').length // 0
    document.all.tags('body').length // 1

    Opera 7.02
    document.documentElement // [object HTMLHtmlElement]
    document.getElementsByTagName('html').length // 1
    document.getElementsByTagName('body').length // 1
    document.all.tags('html').length // 0
    document.all.tags('body').length // 1

    Opera 8.0
    document.documentElement // [object HTMLHtmlElement]
    document.getElementsByTagName('html').length // 1
    document.getElementsByTagName('body').length // 1
    document.all.tags('html').length // 1
    document.all.tags('body').length // 1

    IE 4
    document.documentElement // undefined
    document.getElementsByTagName // undefined
    document.all.tags('html').length // 1

    IE 5.0
    document.documentElement // [Object]
    document.getElementsByTagName('html').length // 1
    document.all.tags('html').length // 1

    NN4.0 & NN4.08 & NN4.5
    document.documentElement // undefined
    document.getElementsByTagName // undefined
    document.all // undefined

    NN6.0
    document.documentElement // [object HTMLHtmlElement]
    document.getElementsByTagName('html').length // 1
    document.all // undefined



    > > if (doc) {
    > > html = (doc.all[0].tagName == '!')?doc.all[1]:doc.all[0];
    > > if (!html && doc.all && doc.all[0]) {
    > > html = (doc.all[0].tagName == '!')?doc.all[0]:doc.all[1];
    > > }

    >
    > This was a silly way to get around doc.all returning the docType
    > declaration. I had forgotten all about the tags method of the all
    > object.


    I didn't even know about it.


    [snip]

    > > // if (early release edition of Firefox && val === 1) {
    > > // // This trick is from Scriptaculous
    > > // // Some version of Firefox (before 1.5?) flickers

    >
    > I've seen this recently. It drove me to distraction while I was
    > working on a special effects module. I don't think it was an early
    > release though. I am pretty sure it was the latest major release.


    I've never managed to make it flicker on any version.


    > > // // when animatingopacityup to a value of 1.
    > > // // If this trick is to be used the test will probably be
    > > // // expensive and should only be preformed the first time.
    > > // //
    > > // // Apparently using this trick increases the weight of
    > > // // the DOM, for rendering speed?

    >
    > I am not sure what that means, but as I recall, setting .999999
    > instead of 1 makes no visible difference, other than to eliminate the
    > annoying flicker.


    Someone told me or I read that by setting several elements with
    opacity makes the DOM "heavier". I can only assume they mean it takes
    longer to render or that it takes more RAM or something like that. The
    idea of limiting this 0.99999 trick to only the versions of FF that
    need it was to avoid adding this "weight" to browsers that don't need
    the trick. The importance given to this "weight" issue sounded a
    little like flaky to me.


    > > //
    > > // val = 0.999999;
    > > // }

    >
    > > // Mac/Firefox-1.5, Mac/Opera-9, Mac/Safari-2,
    > > // Win/NetscapeNavigator-8.0, KDE4/Konqueror
    > > s.opacity= val;
    > > // Win/NetscapeNavigator 6.0/7.0/8.0, Mac/Firefox-1.5
    > > s.MozOpacity = val;
    > > // -khtml-opacitydoes not apply to any version of Konqueror
    > > // according to the
    > > // folks on irc.freenode.net#kde. I set up some tests and
    > > // one person ran them on
    > > // development versions of KDE 4 and this is not supported
    > > // Konqueror for KDE 4
    > > // will be the first Konqueror version to supportopacity
    > > // settings.
    > > // These KDE folks also told me that it was Safari 1.1 that
    > > // supported the
    > > // property below. I don't have anything less then 1.3
    > > // anymore and have only tested
    > > // on 2.0 so far. This does not work with Safari 2.0
    > > s.KhtmlOpacity = val; // TODO some net sources have KHTMLOpacity

    >
    > I can't help verify the original opacity code was written five or six
    > years ago and I can't remember if I ever tested it with Safari back
    > then. I have tested recently with Windows Safari, but I am pretty
    > sure it used the standard opacity style. That being said,
    > KHTMLOpacity just looks wrong to me.



    I have personally tested opacity on Safari 1.0 and Safari 1.2+. Safari
    1.0 does not support any opacity setting, as far as I could tell.
    Safari 1.2 and up supports the standard CSS "opacity" and no option
    related to any string with "khtml" in any case. By process of
    elimination,Safari 1.1 must be the browser that had this khtml opacity
    business. I cannot find a built copy of this version and have not been
    able to test it.

    I chatted with the folks on IRC freenode#webkit (users proton and
    bdash, in particular) and they had some helpful information...

    On the following page you can see which webkit build goes with which
    svn repository tag goes with which version of Safari

    http://developer.apple.com/internet/safari/uamatrix.html

    Safari 1.1 has the "Safari-100" build and the approriate bit of code
    is a function called "jsNameToProp"

    <URL: http://trac.webkit.org/projects/webkit/browser/tags/Safari-100/WebCore/khtml/ecma/kjs_css.cpp#L34>

    static QString jsNameToProp( const Identifier &p )
    {
    QString prop = p.qstring();
    int i = prop.length();
    while( --i ) {
    char c = prop.latin1();
    if ( c < 'A' || c > 'Z' )
    continue;
    prop.insert( i, '-' );
    }

    return prop.lower();
    }

    A '-' character will be inserted before any capital letter and then
    the whole string is lowercased. So "KhtmlOpacity" will be converted to
    "-khtml-opacity". This is the desired output.

    ------------------

    The confusion comes later in Safari-110 when "jsNameToProp" is
    replaced with "cssPropertyName". The new "cssPropertyName" function
    will convert both "KhtmlOpacity" and "khtmlOpacity" to "-khtml-
    opacity"

    <URL: http://trac.webkit.org/projects/webkit/browser/tags/Safari-110/WebCore/khtml/ecma/kjs_css.cpp#L34>

    static QString cssPropertyName(const Identifier &p, bool
    *hadPixelOrPosPrefix = 0)
    {
    QString prop = p.qstring();

    int i = prop.length();
    while (--i) {
    char c = prop.latin1();
    if (c >= 'A' && c <= 'Z')
    prop.insert(i, '-');
    }

    prop = prop.lower();

    if (hadPixelOrPosPrefix)
    *hadPixelOrPosPrefix = false;

    if (prop.startsWith("css-")) {
    prop = prop.mid(4);
    } else if (prop.startsWith("pixel-")) {
    prop = prop.mid(6);
    if (hadPixelOrPosPrefix)
    *hadPixelOrPosPrefix = true;
    } else if (prop.startsWith("pos-")) {
    prop = prop.mid(4);
    if (hadPixelOrPosPrefix)
    *hadPixelOrPosPrefix = true;
    } else if (prop.startsWith("khtml-")) {
    prop.insert(0, '-');
    }

    return prop;
    }


    In conclusion (without testing), the most backwards compatible option
    is to use "KhtmlOpacity" and I really think open source software is
    cool.

    [snip]

    On the Quirksmode site it states that opacity cannot be set on tbody
    and tr elements in many browsers. So just because the setOpacity
    function is defined in a particular browser based on analysis of the
    <html> element, it doesn't mean that setting opacity on any element
    will "just work".

    Cross browser opacity setting is just so much fun! :-S

    Peter
     
    Peter Michaux, Dec 5, 2007
    #12
  13. Darko

    David Mark Guest

    On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    > On Dec 4, 12:17 am, wrote:
    >
    > > On Nov 21, 4:35 pm, Peter Michaux <> wrote:

    >
    > [snip]
    >
    > > And since I posted that, I updated the function to deal with an IE5
    > > DirectX incompatibility.

    >
    > What is that and what part of your code relates to this problem?
    >
    > [code below slightly reformatted to avoid wrapping]



    el.style.filter += 'alpha(opacity=' + (o * 100) + ')';

    This was incorrectly posted as:

    el.style.filter = 'alpha(opacity=' + (o * 100) + ')';

    If you don't check first, IE5 will tack that on over and over as that
    browser never creates the el.filters.alpha property. The regex was
    added to update the filter property in IE5.

    >
    >
    >
    >
    >
    > > I just updated it again to deal with the
    > > float to string issue you mention in your version, as well as to force
    > > the layout fix for IE4. I haven't tested the updated version.

    >
    > > setOpacity = (function(el) {

    >
    > > var i,l;
    > > var reOpacity = new RegExp('alpha\\(opacity=[^\\)]+\\)', 'i');
    > > var opacityStyles = ['opacity', 'MozOpacity', 'KhtmlOpacity'];

    >
    > > if (typeof el.style.filter == 'string') {

    >
    > > return function(el, o) {

    >
    > > var f;

    >
    > > if (el.filters) {
    > > if (!el.currentStyle || !el.currentStyle.hasLayout) {
    > > el.style.zoom = 1;
    > > }

    >
    > > f = el.filters.alpha;

    >
    > > if (typeof(f) != 'undefined') {
    > > f.enabled = o != 1;
    > > f.opacity = o * 100;
    > > }
    > > else {
    > > if (el.style.filter.indexOf('alpha(opacity=') == -1) {
    > > el.style.filter = 'alpha(opacity=' + (o * 100) + ')';
    > > }
    > > else {
    > > el.style.filter = el.style.filter.replace(reOpacity,
    > > "alpha(opacity=" + (o * 100) + ")");
    > > }
    > > }

    >
    > What is the benefit of the above if-else with the first f.enabled/
    > f.opacity branch? It is quite a bit of code bulk. Do you know of a
    > browser with el.filters that will not work with the else branch above?


    The first branch is cleaner and faster. You don't want to get into
    string concatenation and/or regex manipulation unless it is necessary
    (the first time for each element in IE6/7 and every time in IE5.)
    That being said, it looks like the else branch could be tightened up a
    bit in terms of size. No need to figure the opacity filter string in
    two different places.

    >
    > Instead of the above 13 lines, in my version, I just write the
    > following
    >
    > s.filter = s.filter.replace(/alpha\([^\)]*\)/gi,'') +
    > ((val < 1) ? 'alpha(opacity='+val*100+')' : '');
    >


    Smaller in size, but slower in IE6/7. I think this is as small as it
    gets without compromising performance:

    f = el.filters.alpha;
    if (f) {
    f.enabled = o != 1; // IE screws up some fonts when filter is left
    enabled
    f.opacity = o * 100; // This has got to be faster than string
    concatenation
    }
    else { // IE6/7 never get here unless an opacity has never been set
    s = 'alpha(opacity=' + (o * 100) + ')';
    if (reOpacity.test(el.style.filter)) { // IE5 every time
    el.style.filter = el.style.filter.replace(reOpacity, s);
    }
    else { // IE6/7 once
    el.style.filter += s;
    }
    }


    >
    >
    >
    >
    > > }
    > > };

    >
    > > }

    >
    > > i = 0;

    >
    > > l = opacityStyles.length;

    >
    > > while (i < l) {
    > > if (typeof(el.style[opacityStyles]) == 'string') {
    > > return (function(s) {
    > > return function(el, o) {
    > > el.style = (o < .00001)?0:eek:;
    > > };
    > > })(opacityStyles);
    > > }
    > > i++;
    > > }

    >
    > > })(html);

    >
    > > The html variable passed to the one-off function is defined by a
    > > dependant function, which calls other dependant functions, etc., so I
    > > won't post that, but in a nutshell: try the documentElement, then try
    > > getElementsByTagName if it is a feature of the document object, then
    > > try doc.all.tags('html'). Otherwise, you are out of luck as there is
    > > nothing to test with and you shouldn't run the above code at all.

    >
    > I can see that checking for document.documentElement and then falling
    > back to document.all.tags('html')[0] is beneficial as IE4 can set
    > opacity but doesn't have document.documentElement; however, what
    > browser is enabled by adding a check with getElementsByTagName into
    > the mix? I tested a bunch of browsers around the correct vintage and
    > didn't find one where adding the getElementsByTagName check helps. I
    > can see having the getElementsByTagName check for completeness but do
    > you happen to know of a browser where this check is the one that works
    > and document.documentElement and document.all.tags('html')[0] both
    > don't work?


    It would have to be a browser without document.documentElement and
    with gEBTN. No idea is such an animal exists.

    >
    > Opera 5.02
    > document.documentElement // undefined
    > document.getElementsByTagName // undefined
    > document.all.tags('html').length // 0


    That's odd.

    > document.all.tags('body').length // 1
    >
    > Opera 6.0
    > document.documentElement // undefined
    > document.getElementsByTagName('html').length // 0


    So is that.

    > document.getElementsByTagName('body').length // 1
    > document.all.tags('html').length // 0


    And that. I realize Opera 5/6 were lousy browsers, but how could they
    dispute the existence of at least one HTML element? Do these support
    opacity? If so, and you really want to support them, then defer the
    feature test until the body element is parsed and pass it to the one-
    off. I do that for some things that don't need to be used until the
    document is ready.

    > document.all.tags('body').length // 1
    >
    > Opera 7.02
    > document.documentElement // [object HTMLHtmlElement]
    > document.getElementsByTagName('html').length // 1
    > document.getElementsByTagName('body').length // 1
    > document.all.tags('html').length // 0


    Stupid.

    > document.all.tags('body').length // 1
    >
    > Opera 8.0
    > document.documentElement // [object HTMLHtmlElement]
    > document.getElementsByTagName('html').length // 1
    > document.getElementsByTagName('body').length // 1
    > document.all.tags('html').length // 1
    > document.all.tags('body').length // 1
    >
    > IE 4
    > document.documentElement // undefined
    > document.getElementsByTagName // undefined
    > document.all.tags('html').length // 1


    That's really the case I was thinking of when I added the document.all
    check.

    >
    > IE 5.0
    > document.documentElement // [Object]
    > document.getElementsByTagName('html').length // 1
    > document.all.tags('html').length // 1
    >
    > NN4.0 & NN4.08 & NN4.5
    > document.documentElement // undefined
    > document.getElementsByTagName // undefined
    > document.all // undefined


    Never mind these.

    >
    > NN6.0
    > document.documentElement // [object HTMLHtmlElement]
    > document.getElementsByTagName('html').length // 1
    > document.all // undefined
    >
    > > > if (doc) {
    > > > html = (doc.all[0].tagName == '!')?doc.all[1]:doc.all[0];
    > > > if (!html && doc.all && doc.all[0]) {
    > > > html = (doc.all[0].tagName == '!')?doc.all[0]:doc.all[1];
    > > > }

    >
    > > This was a silly way to get around doc.all returning the docType
    > > declaration. I had forgotten all about the tags method of the all
    > > object.

    >
    > I didn't even know about it.
    >
    > [snip]
    >
    > > > // if (early release edition of Firefox && val === 1) {
    > > > // // This trick is from Scriptaculous
    > > > // // Some version of Firefox (before 1.5?) flickers

    >
    > > I've seen this recently. It drove me to distraction while I was
    > > working on a special effects module. I don't think it was an early
    > > release though. I am pretty sure it was the latest major release.

    >
    > I've never managed to make it flicker on any version.


    It only seems to happen when animating the opacity with a timer and
    only when starting from 1. Start from .99999 or whatever and it goes
    away. I eventually changed the timing of something and got it worked
    out of my effects module without resorting to the .99999 hack.

    >
    > > > // // when animatingopacityup to a value of 1.
    > > > // // If this trick is to be used the test will probably be
    > > > // // expensive and should only be preformed the first time.
    > > > // //
    > > > // // Apparently using this trick increases the weight of
    > > > // // the DOM, for rendering speed?

    >
    > > I am not sure what that means, but as I recall, setting .999999
    > > instead of 1 makes no visible difference, other than to eliminate the
    > > annoying flicker.

    >
    > Someone told me or I read that by setting several elements with
    > opacity makes the DOM "heavier". I can only assume they mean it takes
    > longer to render or that it takes more RAM or something like that. The
    > idea of limiting this 0.99999 trick to only the versions of FF that
    > need it was to avoid adding this "weight" to browsers that don't need
    > the trick. The importance given to this "weight" issue sounded a
    > little like flaky to me.


    I think it does take a little more work to render a semi-transparent
    element, but the idea of using .999999 in lieu of 1 is silly.

    >
    >
    >
    >
    >
    > > > //
    > > > // val = 0.999999;
    > > > // }

    >
    > > > // Mac/Firefox-1.5, Mac/Opera-9, Mac/Safari-2,
    > > > // Win/NetscapeNavigator-8.0, KDE4/Konqueror
    > > > s.opacity= val;
    > > > // Win/NetscapeNavigator 6.0/7.0/8.0, Mac/Firefox-1.5
    > > > s.MozOpacity = val;
    > > > // -khtml-opacitydoes not apply to any version of Konqueror
    > > > // according to the
    > > > // folks on irc.freenode.net#kde. I set up some tests and
    > > > // one person ran them on
    > > > // development versions of KDE 4 and this is not supported
    > > > // Konqueror for KDE 4
    > > > // will be the first Konqueror version to supportopacity
    > > > // settings.
    > > > // These KDE folks also told me that it was Safari 1.1 that
    > > > // supported the
    > > > // property below. I don't have anything less then 1.3
    > > > // anymore and have only tested
    > > > // on 2.0 so far. This does not work with Safari 2.0
    > > > s.KhtmlOpacity = val; // TODO some net sources have KHTMLOpacity

    >
    > > I can't help verify the original opacity code was written five or six
    > > years ago and I can't remember if I ever tested it with Safari back
    > > then. I have tested recently with Windows Safari, but I am pretty
    > > sure it used the standard opacity style. That being said,
    > > KHTMLOpacity just looks wrong to me.

    >
    > I have personally tested opacity on Safari 1.0 and Safari 1.2+. Safari
    > 1.0 does not support any opacity setting, as far as I could tell.
    > Safari 1.2 and up supports the standard CSS "opacity" and no option
    > related to any string with "khtml" in any case. By process of
    > elimination,Safari 1.1 must be the browser that had this khtml opacity
    > business. I cannot find a built copy of this version and have not been
    > able to test it.
    >
    > I chatted with the folks on IRC freenode#webkit (users proton and
    > bdash, in particular) and they had some helpful information...
    >
    > On the following page you can see which webkit build goes with which
    > svn repository tag goes with which version of Safari
    >
    > http://developer.apple.com/internet/safari/uamatrix.html
    >
    > Safari 1.1 has the "Safari-100" build and the approriate bit of code
    > is a function called "jsNameToProp"
    >
    > <URL:http://trac.webkit.org/projects/webkit/browser/tags/Safari-100/WebCor...>
    >
    > static QString jsNameToProp( const Identifier &p )
    > {
    > QString prop = p.qstring();
    > int i = prop.length();
    > while( --i ) {
    > char c = prop.latin1();
    > if ( c < 'A' || c > 'Z' )
    > continue;
    > prop.insert( i, '-' );
    > }
    >
    > return prop.lower();
    >
    > }
    >
    > A '-' character will be inserted before any capital letter and then
    > the whole string is lowercased. So "KhtmlOpacity" will be converted to
    > "-khtml-opacity". This is the desired output.


    I thought that was the right one.

    >
    > ------------------
    >
    > The confusion comes later in Safari-110 when "jsNameToProp" is
    > replaced with "cssPropertyName". The new "cssPropertyName" function
    > will convert both "KhtmlOpacity" and "khtmlOpacity" to "-khtml-
    > opacity"
    >
    > <URL:http://trac.webkit.org/projects/webkit/browser/tags/Safari-110/WebCor...>
    >
    > static QString cssPropertyName(const Identifier &p, bool
    > *hadPixelOrPosPrefix = 0)
    > {
    > QString prop = p.qstring();


    [snip]

    > In conclusion (without testing), the most backwards compatible option
    > is to use "KhtmlOpacity" and I really think open source software is
    > cool.


    [snip]


    >On the Quirksmode site it states that opacity cannot be set on tbody
    >and tr elements in many browsers. So just because the setOpacity
    >function is defined in a particular browser based on analysis of the
    ><html> element, it doesn't mean that setting opacity on any element
    >will "just work".


    For the most part it does. Doing it for table rows or groups of table
    rows would seem an odd thing to do anyway. Add a disclaimer about
    table rows at the top and you are done. Feel free to add it to your
    repository.

    >Cross browser opacity setting is just so much fun! :-S


    It's a picnic compared to some things.
     
    David Mark, Dec 5, 2007
    #13
  14. Darko

    David Mark Guest

    On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    [snip]

    A couple other notes.

    The original stand-alone version tested for the existence of the style
    object. The recently posted version comes from a module that checks
    that elsewhere. So that check should be added.

    And seeing that Opera 5/6 refuse to find the html element using gEBTN
    or the all object, I updated my code to use the previously posted
    check of all[0] and all[1] if the html variable cannot be set any
    other way. That branch will only run for Opera 5/6 or antiquated
    mobile browsers and is only a couple of extra lines. It is a moot
    point for this example if Opera 5/6 do not support opacity, but the
    function that finds the html element is crucial for lots of other
    feature tests (at least if they are to be run in the head of the
    document.)

    If this is to be added to your repository, it would be a good
    foundation for it and other style-related code to have functions that
    find the html element for a given document and determine if the host
    is capable of CSS manipulation by testing for the presence of the
    element's style object.
     
    David Mark, Dec 5, 2007
    #14
  15. On Dec 4, 11:47 pm, David Mark <> wrote:
    > On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    >
    > > On Dec 4, 12:17 am, wrote:

    >
    > > > On Nov 21, 4:35 pm, Peter Michaux <> wrote:


    [snip]

    > > > > // if (early release edition of Firefox && val === 1) {
    > > > > // // This trick is from Scriptaculous
    > > > > // // Some version of Firefox (before 1.5?) flickers

    >
    > > > I've seen this recently. It drove me to distraction while I was
    > > > working on a special effects module. I don't think it was an early
    > > > release though. I am pretty sure it was the latest major release.

    >
    > > I've never managed to make it flicker on any version.

    >
    > It only seems to happen when animating the opacity with a timer and
    > only when starting from 1. Start from .99999 or whatever and it goes
    > away. I eventually changed the timing of something and got it worked
    > out of my effects module without resorting to the .99999 hack.
    >
    > > > > // // when animatingopacityup to a value of 1.
    > > > > // // If this trick is to be used the test will probably be
    > > > > // // expensive and should only be preformed the first time.
    > > > > // //
    > > > > // // Apparently using this trick increases the weight of
    > > > > // // the DOM, for rendering speed?

    >
    > > > I am not sure what that means, but as I recall, setting .999999
    > > > instead of 1 makes no visible difference, other than to eliminate the
    > > > annoying flicker.

    >
    > > Someone told me or I read that by setting several elements with
    > > opacity makes the DOM "heavier". I can only assume they mean it takes
    > > longer to render or that it takes more RAM or something like that. The
    > > idea of limiting this 0.99999 trick to only the versions of FF that
    > > need it was to avoid adding this "weight" to browsers that don't need
    > > the trick. The importance given to this "weight" issue sounded a
    > > little like flaky to me.

    >
    > I think it does take a little more work to render a semi-transparent
    > element, but the idea of using .999999 in lieu of 1 is silly.


    I believe the flicker issue included animating from an opacity below 1
    up to 1 in which case the animation needed to stop before 1. I can't
    say this is silly.

    [snip]

    > For the most part it does. Doing it for table rows or groups of table
    > rows would seem an odd thing to do anyway. Add a disclaimer about
    > table rows at the top and you are done. Feel free to add it to your
    > repository.


    I'm starting a branch for opacity. I think it will serve as a good
    first DHTML example.

    Peter
     
    Peter Michaux, Dec 5, 2007
    #15
  16. On Dec 5, 2:48 am, David Mark <> wrote:
    > On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    > [snip]
    >
    > A couple other notes.
    >
    > The original stand-alone version tested for the existence of the style
    > object. The recently posted version comes from a module that checks
    > that elsewhere. So that check should be added.
    >
    > And seeing that Opera 5/6 refuse to find the html element using gEBTN
    > or the all object, I updated my code to use the previously posted
    > check of all[0] and all[1] if the html variable cannot be set any
    > other way. That branch will only run for Opera 5/6 or antiquated
    > mobile browsers and is only a couple of extra lines. It is a moot
    > point for this example if Opera 5/6 do not support opacity, but the
    > function that finds the html element is crucial for lots of other
    > feature tests (at least if they are to be run in the head of the
    > document.)
    >
    > If this is to be added to your repository, it would be a good
    > foundation for it and other style-related code to have functions that
    > find the html element for a given document and determine if the host
    > is capable of CSS manipulation by testing for the presence of the
    > element's style object.


    Would you mind posting your function that finds the html element?

    Peter
     
    Peter Michaux, Dec 5, 2007
    #16
  17. Darko

    David Mark Guest

    On Dec 5, 9:33 am, Peter Michaux <> wrote:
    > On Dec 5, 2:48 am, David Mark <> wrote:
    >
    >
    >
    >
    >
    > > On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    > > [snip]

    >
    > > A couple other notes.

    >
    > > The original stand-alone version tested for the existence of the style
    > > object. The recently posted version comes from a module that checks
    > > that elsewhere. So that check should be added.

    >
    > > And seeing that Opera 5/6 refuse to find the html element using gEBTN
    > > or the all object, I updated my code to use the previously posted
    > > check of all[0] and all[1] if the html variable cannot be set any
    > > other way. That branch will only run for Opera 5/6 or antiquated
    > > mobile browsers and is only a couple of extra lines. It is a moot
    > > point for this example if Opera 5/6 do not support opacity, but the
    > > function that finds the html element is crucial for lots of other
    > > feature tests (at least if they are to be run in the head of the
    > > document.)

    >
    > > If this is to be added to your repository, it would be a good
    > > foundation for it and other style-related code to have functions that
    > > find the html element for a given document and determine if the host
    > > is capable of CSS manipulation by testing for the presence of the
    > > element's style object.

    >
    > Would you mind posting your function that finds the html element?
    >
    > Peter- Hide quoted text -
    >
    > - Show quoted text -


    Okay. I just updated it this morning and haven't had time to test it
    thoroughly.

    var doc = this.document;

    var isRealObject = function(o) {
    return !!(o && typeof(o) == 'object');
    };

    var htmlElement = function(docNode) {
    var html;
    docNode = docNode || doc;
    html = isRealObject(docNode.documentElement)?docNode.documentElement:
    (documentElementsByTagName)?documentElementsByTagName('html', docNode)
    [0]:null);
    if (!html && docNode.all && docNode.all[0]) {
    html = docNode.all[(docNode.all[0].tagName == '!')?1:0] || null;
    if (html && html.tagName.toLowerCase() != 'html') { html = null; }
    }
    return html;
    };

    The missing documentElementsByTagName function is a wrapper for gEBTN
    that only exists if the document object features such a method. It
    exists to smooth out problems with the "*" parameter, as well as using
    the all object for agents that don't feature gEBTN. It isn't really
    needed now that the additional clause has been added to handle Opera
    5/6, so you should just change it to doc.getElementsByTagName. And if
    you are wondering why these are created with variable assignments, it
    is because they create object methods in the original code.
     
    David Mark, Dec 5, 2007
    #17
  18. On Dec 5, 8:08 am, David Mark <> wrote:
    > On Dec 5, 9:33 am, Peter Michaux <> wrote:
    >
    > > On Dec 5, 2:48 am, David Mark <> wrote:

    >
    > > > On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    > > > [snip]

    >
    > > > A couple other notes.

    >
    > > > The original stand-alone version tested for the existence of the style
    > > > object. The recently posted version comes from a module that checks
    > > > that elsewhere. So that check should be added.

    >
    > > > And seeing that Opera 5/6 refuse to find the html element using gEBTN
    > > > or the all object, I updated my code to use the previously posted
    > > > check of all[0] and all[1] if the html variable cannot be set any
    > > > other way. That branch will only run for Opera 5/6 or antiquated
    > > > mobile browsers and is only a couple of extra lines. It is a moot
    > > > point for this example if Opera 5/6 do not support opacity, but the
    > > > function that finds the html element is crucial for lots of other
    > > > feature tests (at least if they are to be run in the head of the
    > > > document.)

    >
    > > > If this is to be added to your repository, it would be a good
    > > > foundation for it and other style-related code to have functions that
    > > > find the html element for a given document and determine if the host
    > > > is capable of CSS manipulation by testing for the presence of the
    > > > element's style object.

    >
    > > Would you mind posting your function that finds the html element?

    >
    >
    > Okay. I just updated it this morning and haven't had time to test it
    > thoroughly.
    >
    > var doc = this.document;
    >
    > var isRealObject = function(o) {
    > return !!(o && typeof(o) == 'object');
    >
    > };
    >
    > var htmlElement = function(docNode) {
    > var html;
    > docNode = docNode || doc;
    > html = isRealObject(docNode.documentElement)


    If docNode.documentElement is defined, will it ever be any type other
    than 'object'? It seems like checking this is unnecessary if there has
    never been a known problem.

    > ?docNode.documentElement:
    > (documentElementsByTagName)?documentElementsByTagName('html', docNode)


    If documentElementsByTagName may be undefined then the above ternary
    conditional will error in browsers where it is undefined. I think it
    should be

    (typeof documentElementsByTagName != 'undefined')?
    documentElementsByTagName('html', docNode)



    > [0]:null);
    > if (!html && docNode.all && docNode.all[0]) {
    > html = docNode.all[(docNode.all[0].tagName == '!')?1:0] || null;
    > if (html && html.tagName.toLowerCase() != 'html') { html = null; }
    > }
    > return html;
    >
    > };
    >
    > The missing documentElementsByTagName function is a wrapper for gEBTN
    > that only exists if the document object features such a method. It
    > exists to smooth out problems with the "*" parameter, as well as using
    > the all object for agents that don't feature gEBTN. It isn't really
    > needed now that the additional clause has been added to handle Opera
    > 5/6, so you should just change it to doc.getElementsByTagName.


    When I looked at document.documentElement, document.all.tags and
    document.getElementsByTagName, I stated that in IE4
    document.all.tags('html').length is 1. That is only true after
    window.onload fires. Before window.onload the length is 0. Since
    feature testing is preferably done in the head right when the script
    loads, the document.all.tags check isn't really enabling any
    particular browsers, as far as I know. This goes along with your "It
    isn't really needed now...."

    Of the browsers I checked that can set opacity, only IE4 and Opera 6-
    don't have document.documentElement. I don't mind degrading those
    browsers to not use opacity setting. This would make the setOpacity
    and all other functions requiring an element for feature testing not
    dependent on an htmlElement function like you've outlined. In my eyes,
    that is a nice reduction in code size. Code always might contain bugs
    and needs testing as we have seen even here (not meant as criticism
    but as an argument to reduce code size where reasonable). I think that
    only checking for document.documentElement is a reasonable place to
    draw the line in browser history given the approximate distribution of
    browser version in use today. Any non-trivial CSS that may need the
    fallbacks in the htmlElement function for a feature tests likely won't
    work in IE4 anyway. Sound reasonable?

    As a reference for this threshold, I don't wrap document.all and
    document.getElementById together in a function. I just check for
    document.getElementById.

    [snip]

    Peter
     
    Peter Michaux, Dec 5, 2007
    #18
  19. Darko

    David Mark Guest

    On Dec 5, 1:04 pm, Peter Michaux <> wrote:
    > On Dec 5, 8:08 am, David Mark <> wrote:
    >
    >
    >
    >
    >
    > > On Dec 5, 9:33 am, Peter Michaux <> wrote:

    >
    > > > On Dec 5, 2:48 am, David Mark <> wrote:

    >
    > > > > On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    > > > > [snip]

    >
    > > > > A couple other notes.

    >
    > > > > The original stand-alone version tested for the existence of the style
    > > > > object. The recently posted version comes from a module that checks
    > > > > that elsewhere. So that check should be added.

    >
    > > > > And seeing that Opera 5/6 refuse to find the html element using gEBTN
    > > > > or the all object, I updated my code to use the previously posted
    > > > > check of all[0] and all[1] if the html variable cannot be set any
    > > > > other way. That branch will only run for Opera 5/6 or antiquated
    > > > > mobile browsers and is only a couple of extra lines. It is a moot
    > > > > point for this example if Opera 5/6 do not support opacity, but the
    > > > > function that finds the html element is crucial for lots of other
    > > > > feature tests (at least if they are to be run in the head of the
    > > > > document.)

    >
    > > > > If this is to be added to your repository, it would be a good
    > > > > foundation for it and other style-related code to have functions that
    > > > > find the html element for a given document and determine if the host
    > > > > is capable of CSS manipulation by testing for the presence of the
    > > > > element's style object.

    >
    > > > Would you mind posting your function that finds the html element?

    >
    > > Okay. I just updated it this morning and haven't had time to test it
    > > thoroughly.

    >
    > > var doc = this.document;

    >
    > > var isRealObject = function(o) {
    > > return !!(o && typeof(o) == 'object');

    >
    > > };

    >
    > > var htmlElement = function(docNode) {
    > > var html;
    > > docNode = docNode || doc;
    > > html = isRealObject(docNode.documentElement)

    >
    > If docNode.documentElement is defined, will it ever be any type other
    > than 'object'? It seems like checking this is unnecessary if there has
    > never been a known problem.


    There is the possibility, however remote, that it could be a null
    object.

    >
    > > ?docNode.documentElement:
    > > (documentElementsByTagName)?documentElementsByTagName('html', docNode)

    >
    > If documentElementsByTagName may be undefined then the above ternary
    > conditional will error in browsers where it is undefined. I think it
    > should be
    >
    > (typeof documentElementsByTagName != 'undefined')?
    > documentElementsByTagName('html', docNode)


    If you mean that documentElementsByTagName has never been declared,
    that is impossible in the context this code came from (it is a
    declared variable.) It may have an undefined value, but that won't
    throw an error.


    >
    > > [0]:null);
    > > if (!html && docNode.all && docNode.all[0]) {
    > > html = docNode.all[(docNode.all[0].tagName == '!')?1:0] || null;
    > > if (html && html.tagName.toLowerCase() != 'html') { html = null; }
    > > }
    > > return html;

    >
    > > };

    >
    > > The missing documentElementsByTagName function is a wrapper for gEBTN
    > > that only exists if the document object features such a method. It
    > > exists to smooth out problems with the "*" parameter, as well as using
    > > the all object for agents that don't feature gEBTN. It isn't really
    > > needed now that the additional clause has been added to handle Opera
    > > 5/6, so you should just change it to doc.getElementsByTagName.

    >
    > When I looked at document.documentElement, document.all.tags and
    > document.getElementsByTagName, I stated that in IE4
    > document.all.tags('html').length is 1. That is only true after
    > window.onload fires. Before window.onload the length is 0. Since
    > feature testing is preferably done in the head right when the script
    > loads, the document.all.tags check isn't really enabling any
    > particular browsers, as far as I know. This goes along with your "It
    > isn't really needed now...."


    Were all of those results determined after onload? If so, I would
    like to see what they look like when run in the head. Regardless, I
    assume that document.all[0] is defined before the onload event fires,
    so the added test should be sufficient.

    >
    > Of the browsers I checked that can set opacity, only IE4 and Opera 6-
    > don't have document.documentElement. I don't mind degrading those
    > browsers to not use opacity setting. This would make the setOpacity
    > and all other functions requiring an element for feature testing not
    > dependent on an htmlElement function like you've outlined. In my eyes,


    Opacity yes, but all other style-related functions? That seems
    extreme. Also, there is no reason why such functions can't run after
    the body has been parsed (e.g. in a real or simulated DOMContentLoaded
    listener.) I do that for several functions that have to create
    elements and append them to the body to detect quirks like Opera's
    botched offsetLeft/Top reporting. It seems like setOpacity is
    something that wouldn't be needed until the document is ready, else
    how would you reliably find the element you want to fade?

    > that is a nice reduction in code size. Code always might contain bugs
    > and needs testing as we have seen even here (not meant as criticism
    > but as an argument to reduce code size where reasonable). I think that


    Well, it turned out that it wasn't a bug, but I get your point.

    > only checking for document.documentElement is a reasonable place to
    > draw the line in browser history given the approximate distribution of
    > browser version in use today. Any non-trivial CSS that may need the
    > fallbacks in the htmlElement function for a feature tests likely won't
    > work in IE4 anyway. Sound reasonable?


    Sort of. How would a script determine if CSS is even available when
    running in IE4, Opera 6, etc.? One of the first flags I set is based
    on the presence of a style object. If it doesn't exist then lots of
    unneeded feature testing is skipped and style-related functions are
    not created. Next I check the types of the display, visibility and
    position properties of the object (typically strings, but not always)
    and those three results determine which style-related modules should
    be initialized. They are also referenced by applications to determine
    if it is possible to hide dynamically replaced content during the page
    load (i.e. if a style rule is added before the body is parsed, will it
    be possible to overrule it with an inline style once the content is
    replaced after parsing.) Can you confirm if IE4 can get the HTML
    element via document.all[0] (or document.all[1]?) If not, can it get
    any element during page load?

    >
    > As a reference for this threshold, I don't wrap document.all and
    > document.getElementById together in a function. I just check for
    > document.getElementById.
    >


    I still allow for the use of document.all when gEBI isn't present, but
    I did remove support for document.layers a few years back.
     
    David Mark, Dec 5, 2007
    #19
  20. On Dec 5, 10:43 am, David Mark <> wrote:
    > On Dec 5, 1:04 pm, Peter Michaux <> wrote:
    >
    > > On Dec 5, 8:08 am, David Mark <> wrote:

    >
    > > > On Dec 5, 9:33 am, Peter Michaux <> wrote:

    >
    > > > > On Dec 5, 2:48 am, David Mark <> wrote:

    >
    > > > > > On Dec 4, 8:22 pm, Peter Michaux <> wrote:
    > > > > > [snip]

    >
    > > > > > A couple other notes.

    >
    > > > > > The original stand-alone version tested for the existence of the style
    > > > > > object. The recently posted version comes from a module that checks
    > > > > > that elsewhere. So that check should be added.

    >
    > > > > > And seeing that Opera 5/6 refuse to find the html element using gEBTN
    > > > > > or the all object, I updated my code to use the previously posted
    > > > > > check of all[0] and all[1] if the html variable cannot be set any
    > > > > > other way. That branch will only run for Opera 5/6 or antiquated
    > > > > > mobile browsers and is only a couple of extra lines. It is a moot
    > > > > > point for this example if Opera 5/6 do not support opacity, but the
    > > > > > function that finds the html element is crucial for lots of other
    > > > > > feature tests (at least if they are to be run in the head of the
    > > > > > document.)

    >
    > > > > > If this is to be added to your repository, it would be a good
    > > > > > foundation for it and other style-related code to have functions that
    > > > > > find the html element for a given document and determine if the host
    > > > > > is capable of CSS manipulation by testing for the presence of the
    > > > > > element's style object.

    >
    > > > > Would you mind posting your function that finds the html element?

    >
    > > > Okay. I just updated it this morning and haven't had time to test it
    > > > thoroughly.

    >
    > > > var doc = this.document;

    >
    > > > var isRealObject = function(o) {
    > > > return !!(o && typeof(o) == 'object');

    >
    > > > };

    >
    > > > var htmlElement = function(docNode) {
    > > > var html;
    > > > docNode = docNode || doc;
    > > > html = isRealObject(docNode.documentElement)

    >
    > > If docNode.documentElement is defined, will it ever be any type other
    > > than 'object'? It seems like checking this is unnecessary if there has
    > > never been a known problem.

    >
    > There is the possibility, however remote, that it could be a null
    > object.


    I asked about this sort of testing on c.l.js a when I was first
    venturing into feature testing. I thought I'd have to test everything.
    If document.getElementsById is present then I'd have to check if it
    was callable before calling it. There is a chance it may not be
    callable; however, since this situation has never been observed, the
    general feeling was to trust is it callable until it is observed to be
    not callable in at least one browser. Feature testing even when no
    problems has ever been observed could balloon the feature tests to
    hugely paranoid proportions.

    That said, I understand you may have had the isRealObject function
    around for another situation and it was just handy to use in this
    case.

    [snip]

    > > > [0]:null);
    > > > if (!html && docNode.all && docNode.all[0]) {
    > > > html = docNode.all[(docNode.all[0].tagName == '!')?1:0] || null;
    > > > if (html && html.tagName.toLowerCase() != 'html') { html = null; }
    > > > }
    > > > return html;

    >
    > > > };

    >
    > > > The missing documentElementsByTagName function is a wrapper for gEBTN
    > > > that only exists if the document object features such a method. It
    > > > exists to smooth out problems with the "*" parameter, as well as using
    > > > the all object for agents that don't feature gEBTN. It isn't really
    > > > needed now that the additional clause has been added to handle Opera
    > > > 5/6, so you should just change it to doc.getElementsByTagName.

    >
    > > When I looked at document.documentElement, document.all.tags and
    > > document.getElementsByTagName, I stated that in IE4
    > > document.all.tags('html').length is 1. That is only true after
    > > window.onload fires. Before window.onload the length is 0. Since
    > > feature testing is preferably done in the head right when the script
    > > loads, the document.all.tags check isn't really enabling any
    > > particular browsers, as far as I know. This goes along with your "It
    > > isn't really needed now...."

    >
    > Were all of those results determined after onload?


    Yes


    > If so, I would
    > like to see what they look like when run in the head. Regardless, I
    > assume that document.all[0] is defined before the onload event fires,
    > so the added test should be sufficient.


    The added test seems to be fine in IE4 at least with the HTML page I
    tested.


    > > Of the browsers I checked that can set opacity, only IE4 and Opera 6-
    > > don't have document.documentElement. I don't mind degrading those
    > > browsers to not use opacity setting. This would make the setOpacity
    > > and all other functions requiring an element for feature testing not
    > > dependent on an htmlElement function like you've outlined. In my eyes,

    >
    > Opacity yes, but all other style-related functions? That seems
    > extreme.


    Can you think of an example of a browser without
    document.documentElement where style-related functions would work if
    the document.all fallback is used for testing? Do the entire scripts
    associated with these style-related functions work in these browsers?


    > Also, there is no reason why such functions can't run after
    > the body has been parsed (e.g. in a real or simulated DOMContentLoaded
    > listener.) I do that for several functions that have to create
    > elements and append them to the body to detect quirks like Opera's
    > botched offsetLeft/Top reporting. It seems like setOpacity is
    > something that wouldn't be needed until the document is ready, else
    > how would you reliably find the element you want to fade?


    Since document.all[0] or document.all[1] seems to work in the head
    this point may be moot.

    [snip]


    > > only checking for document.documentElement is a reasonable place to
    > > draw the line in browser history given the approximate distribution of
    > > browser version in use today. Any non-trivial CSS that may need the
    > > fallbacks in the htmlElement function for a feature tests likely won't
    > > work in IE4 anyway. Sound reasonable?

    >
    > Sort of. How would a script determine if CSS is even available when
    > running in IE4, Opera 6, etc.? One of the first flags I set is based
    > on the presence of a style object. If it doesn't exist then lots of
    > unneeded feature testing is skipped and style-related functions are
    > not created. Next I check the types of the display, visibility and
    > position properties of the object (typically strings, but not always)
    > and those three results determine which style-related modules should
    > be initialized.


    This is exactly the direction in which I'd like to go with this code
    repository.


    > They are also referenced by applications to determine
    > if it is possible to hide dynamically replaced content during the page
    > load (i.e. if a style rule is added before the body is parsed, will it
    > be possible to overrule it with an inline style once the content is
    > replaced after parsing.) Can you confirm if IE4 can get the HTML
    > element via document.all[0] (or document.all[1]?)


    It can.


    > If not, can it get
    > any element during page load?
    >
    > > As a reference for this threshold, I don't wrap document.all and
    > > document.getElementById together in a function. I just check for
    > > document.getElementById.

    >
    > I still allow for the use of document.all when gEBI isn't present,


    How many of your pages have enabled JavaScript functionality because
    of these archaic checks and how many actual visitors benefit? If there
    are pages that do become enabled with these checks that would not
    become enabled with the modern checks only, it still may be better
    overall (faster download times, less code to maintain) to just slide
    these down the degradation path given how few users benefit. They
    still do get a perfectly working HTML page, after all.

    I think setting the feature threshold at document.getElementById and
    document.documentElement is ok today. If there is outrage over this
    then the code repository could allow for the the document.all
    fallbacks. I cringe a little when I type that thought. I strongly vote
    we go "modern" (NN6 November 2000, IE5.5 July 2000).

    > but I did remove support for document.layers a few years back.


    Peter
     
    Peter Michaux, Dec 5, 2007
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nebojsa Dinic

    JPanel transparency (opacity)

    Nebojsa Dinic, Apr 16, 2004, in forum: Java
    Replies:
    0
    Views:
    3,346
    Nebojsa Dinic
    Apr 16, 2004
  2. DU
    Replies:
    13
    Views:
    944
  3. Sentient Fluid

    Opacity

    Sentient Fluid, Apr 22, 2005, in forum: HTML
    Replies:
    0
    Views:
    578
    Sentient Fluid
    Apr 22, 2005
  4. windandwaves

    opacity

    windandwaves, Feb 18, 2006, in forum: HTML
    Replies:
    10
    Views:
    2,299
    Jim Higson
    Feb 26, 2006
  5. Jim Higson

    What is -khtml-opacity for?

    Jim Higson, Mar 4, 2006, in forum: HTML
    Replies:
    3
    Views:
    9,750
    Toby Inkster
    Mar 5, 2006
Loading...

Share This Page