From: Andrew Poulos on 20 Nov 2009 01:51 How do I get the opacity value in IE where the opacity is set via a filter eg. <img style="filter:alpha(opacity=12);" src="... > Andrew Poulos
From: Garrett Smith on 20 Nov 2009 03:07 Andrew Poulos wrote: > How do I get the opacity value in IE where the opacity is set via a > filter eg. > > <img style="filter:alpha(opacity=12);" src="... > This was discussed not too long ago, related to Gregor's library. The common saying: "Google is your friend" does not hold true here. Here's what I do: Excerpted from APE[1]: var alphaOpExp = /\Wopacity\s*=\s*([\d]+)/i; /* |cs| is an IE currentStyle object. */ function getFilterOpacity(cs) { var o, f = cs.filter; if(!alphaOpExp.test(f)) return 1; o = alphaOpExp.exec(f); return o[1]/100; } Why do I say "Google is your friend" does not hold true here? Google Closure style.js http://closure-library.googlecode.com/svn/trunk/closure/goog/style/style.js /** * Gets the opacity of a node (x-browser). This gets the inline style * opacity of the node, and does not take into account the cascaded or * the computed style for this node. * @param {Element} el Element whose opacity has to be found. * @return {number|string} Opacity between 0 and 1 or an empty string * {@code ''} if the opacity is not set. */ goog.style.getOpacity = function(el) { var style = el.style; var result = ''; if ('opacity' in style) { result = style.opacity; } else if ('MozOpacity' in style) { result = style.MozOpacity; } else if ('filter' in style) { var match = style.filter.match(/alpha\(opacity=([\d.]+)\)/); if (match) { result = String(match[1] / 100); } } return result == '' ? result : Number(result); }; This function works only for inline style, fails in IE even for that. The result of calling String(match[1] / 100); is pointless as |result| is converted to number. The numeric conversion can be more efficiently achieved by using unary + operator. The variant return type returns string, if the opacity is not set in the element's inline style. I cannot understand why the API would want to require opacity to be set in ElementCSSInlineStyle (or IE equivalent inline style property) and knowingly failing to return the element's opacity when set in a cascading stylesheet. Doesn't style information belong in the stylesheet? The function will fail if there is any whitespace in the element's filter string, or if the filter string uses proper case, (and examples on MSDN do). <div id="x" style="filter: alpha( Opacity = 10 )">hey hey, goodbye</div> var x = document.getElementById("x") goog.style.getOpacity(x); Will fail to get the opacity in IE. This function does not read from currentStyle; only inline style. For reading currentStyle, Google Closure provides: goog.style.getStyle_ = function(element, style) { return goog.style.getComputedStyle(element, style) || goog.style.getCascadedStyle(element, style) || element.style[style]; }; goog.style.getStyle_ calls goog.style.getCascadedStyle, which uses IEs currentStyle property: goog.style.getCascadedStyle = function(element, style) { return element.currentStyle ? element.currentStyle[style] : null; }; Method goog.style.getStyle_ fails to read "opacity" in IE because no versions of IE (IE8 is the latest) support the CSS3 "opacity" style property. That function mightwork for IE9, should IE decide to provide support of CSS3, though IE supporting CSS3 in a currentStyle should be thought out carefully. The naming of getStyle_ uses a trailing underscore. This is apparently to make the function "fake private". Instead, a closure could have been used. If a closure had been used, the identifier could be hidden in scope and made publicly available. This is arguably better design as it simplifies the public interface of goog.style (not having an extra object exposed to the API). Regardless of the design nit, the code will fail to read opacity in so many cases that changing that at this point would miss the point (would still be broken). Ironic that the Google Closure library uses fake private in code instead of using actual closures. Using closures can result in simpler API, faster performance by using in-scope variables, and more munging (local identifiers can be munged) resulting in smaller file size. Knowing how to use closures, one can write code that is faster, smaller, have a simplified interface. Google has, in the past, justified using Global identifiers with performance, however it has been shown that Global identifiers are not resolved more quickly, except for in Firefox 3.5 (and that is due to an internal optimization which may in the future, apply to non-global containing scope). I cannot justify the design decision of fake private; but see benefits to using a closure based approach: * smaller - no long namespace + "_" for "fake private", more munging. * faster - local variables are resolved faster * simplified interface - no fake private. [1]http://github.com/GarrettS/ape-javascript-library/blob/master/src/dom/style-f.js#L32 -- Garrett comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Garrett Smith on 20 Nov 2009 03:15 Garrett Smith wrote: > Andrew Poulos wrote: >> How do I get the opacity value in IE where the opacity is set via a >> filter eg. >> [...] > if (match) { > result = String(match[1] / 100); > } > } > return result == '' ? result : Number(result); > }; > > This function works only for inline style, fails in IE even for that. > > The result of calling String(match[1] / 100); is pointless as |result| > is converted to number. > Ah, no sorry, that does make a difference if the result is "0". "0" / 100 results in 0 (number). Since 0 == '', the result would be returned then. A strict equality test seems less confusing. -- Garrett comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Thomas 'PointedEars' Lahn on 20 Nov 2009 07:35 Andrew Poulos wrote: > How do I get the opacity value in IE where the opacity is set via a > filter eg. > > <img style="filter:alpha(opacity=12);" src="... > imgRef.filters.item("alpha").opacity Garrett is wrong, STFW for "filter:alpha(opacity" would have helped. The MSDN Library entry is the first hit here: <http://msdn.microsoft.com/en-us/library/ms532967(VS.85).aspx> It contains a link to "Scripting Filters" at the bottom. 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
From: Garrett Smith on 20 Nov 2009 13:41 Thomas 'PointedEars' Lahn wrote: > Andrew Poulos wrote: > >> How do I get the opacity value in IE where the opacity is set via a >> filter eg. >> >> <img style="filter:alpha(opacity=12);" src="... > > > imgRef.filters.item("alpha").opacity > > Garrett is wrong, STFW for "filter:alpha(opacity" would have helped. > The MSDN Library entry is the first hit here: > That suggestion will result in error when the filter object is undefined or uses the recommended DXImageTransform filter instead of just alpha. This is a problem because it is undefined when not set: QUick example: javascript: alert(document.body.style.filters.item("alpha")) It is a more significant problem when the advice on MSDN is followed: > <http://msdn.microsoft.com/en-us/library/ms532967(VS.85).aspx> > <msdn comment> That MSDN page is unusable in IE7. When scrolling the window. the content in the body stays fixed and the navigation scrolls. There doesn't seem to be a way to switch to script free view. I remember a javascript: button at the botttom of the page, but cannot scroll to reach it in IE7. Launching in Opera, I get script free, with no parameter. Then, clicking lightweight, I get the option to switch to "ScriptFree", which does contain the "loband" parameter. OK, now that I can view the page, back to the discussion... </msdn comment> > It contains a link to "Scripting Filters" at the bottom. > http://msdn.microsoft.com/en-us/library/ms532847(VS.85,loband).aspx Suggests using the DXImageTransform filter instead. Example: el.filter:progid:DXImageTransform.Microsoft.Alpha(opacity=20); That works great. The problem is when trying to read the filter using the approach el.filters.item("alpha").opacity. The result is an error is produced. There are two alpha filters: filter: alpha(opacity = 10); filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 10); The latter is being changed now to follow CSS 2.1 Syntax: -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=52)" http://blogs.msdn.com/ie/archive/2008/09/08/microsoft-css-vendor-extensions.aspx <sarcasm> Thanks, Microsoft. I really needed one more way to set the filter. </sarcasm> Conclusion: By parsing the filter string, either type of alpha filter can be read. -- Garrett comp.lang.javascript FAQ: http://jibbering.com/faq/
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Google Closure: The Evil Parts Next: Encapsulation and js, html, css |