<img style="filter:alpha(opacity=12);" src="... >
Andrew Poulos
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/
[...]
> 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.
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
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.
> 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:
JFYI: I said that you were wrong because you said Google would not be our
friend here. That is, Google *Search*, _not_ Code.
> 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:
It was the solution for this specific example, of course.
> QUick example:
> javascript: alert(document.body.style.filters.item("alpha"))
Nobody set the filter on the BODY element here.
> It is a more significant problem when the advice on MSDN is followed:
>> <http://msdn.microsoft.com/en-us/library/ms532967(VS.85).aspx>
>>
> [...]
>> 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.
It does not work at all in older IEs (without DirectX support), while the
Alpha filter is backwards-compatible. The additional features of the
DirectX filter are also seldom used.
> The problem is when trying to read the filter using
> the approach el.filters.item("alpha").opacity.
>
> The result is an error is produced.
Borken as designed.
> There are two alpha filters:
Yes, one uses DirectX Image Transformation (DXImageTransform) and the other
one does not.
> 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
OMG.
> <sarcasm>
> Thanks, Microsoft. I really needed one more way to set the filter.
> </sarcasm>
ACK
> Conclusion:
> By parsing the filter string, either type of alpha filter can be read.
To conclude that therefore this would be the best way is a fallacy, though.
PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
Ah, got it. It seemed like you were suggesting that the proposed
solution was wrong.
However, the MSDN link you got from the search result doesn't mention
filter: alpha, but the DXImageTransform filter instead.
>> 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:
>
> It was the solution for this specific example, of course.
>
>> QUick example:
>> javascript: alert(document.body.style.filters.item("alpha"))
>
> Nobody set the filter on the BODY element here.
>
Right. So BODY has no filter. When reading el.filters.item("alpha") off
an element that has no alpha filter, an error is produced.
(Should have been:
javascript: alert(document.body.filters.item("alpha"));
).
The point is that the code results in error when trying to read opacity
off any element for which it has not yet been set.
This is a fairly common scenario:
A program has an element that is initially fully opaque. The element may
fade in and out a few times. The stylesheet does not not set opacity
to 100 (or "1" for css3 opacity).
When the program reads the element's filter opacity opacity, an error
resluts.
>> It is a more significant problem when the advice on MSDN is followed:
>>> <http://msdn.microsoft.com/en-us/library/ms532967(VS.85).aspx>
>>>
>> [...]
>>> 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.
>
> It does not work at all in older IEs (without DirectX support), while the
> Alpha filter is backwards-compatible. The additional features of the
> DirectX filter are also seldom used.
>
DXImageTransform works in IE5.5 and above.
Aside from the error produced when the element has no fitlers, testing
your approach in IE5.5, using IE Tester, I get an error, even when the
alpha filter is specified.
"Error accessing the OLE Registry."
>> The problem is when trying to read the filter using
>> the approach el.filters.item("alpha").opacity.
>>
>> The result is an error is produced.
>
> Borken as designed.
>
Filters do not map so well to CSS. Particularly when an element wants to
use more than 1 filter.
>> There are two alpha filters:
>
> Yes, one uses DirectX Image Transformation (DXImageTransform) and the other
> one does not.
>
[...]
Apparently filter opacity was removed in IE8:
http://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=331735
See also:
https://developer.mozilla.org/en/CSS/opacity
Apparently they put it back. Both alpha and its DX mimic work fine for
me (using IE8 in IETester).
Microsoft has been recommending the extended DXImageTransform since
IE5.5. The solution should allow pages to follow either the vendor
recommendations or the shorthand old-style filter: alpha(opacity=20).
And now we get one more: "-ms-filter":
http://msdn.microsoft.com/en-us/library/ms533754%28VS.85%29.aspx
| Internet Explorer 8. The -ms-filter attribute is an extension to CSS,
| and can be be used as a synonym for filter in IE8 mode. When using
| -ms-filter, enclose the progid in single quotes (') or double quotes
| ("). Multiple values should be separated by commas (,), as shown in
| the Examples section.
>
>> Conclusion:
>> By parsing the filter string, either type of alpha filter can be read.
>
> To conclude that therefore this would be the best way is a fallacy, though.
>
Parsing the filter string works for both type of filter setting and does
not result in error.
Feading the el.filters.item("alpha"), will result in error unless the
alpha filter is set as:
filter: alpha([...]);
The error produced also occurs when using microsoft-recommended
DXImageTransform alpha filter in css, but reading el.filters.item("alpha").
For a general purpose solution, parsing the filter string is less error
prone. This approach works for either alpha or its DX variation and
avoids using try/catch to read the alpha filter.
Man, I'm confused. SHould I use
-ms-filter:"alpha(opacity=52)"
or
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=52)"
?
Anyhow I'm also thinking of using try/catch:
var val;
try {
val = imgRef.filters.item("alpha").opacity;
} catch (err) {
val = 100;
}
as I'd rather not not use a regexp (no great reason).
Andrew Poulos
> Thomas 'PointedEars' Lahn wrote:
>> Garrett Smith wrote:
>>> 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:
>>
>> JFYI: I said that you were wrong because you said Google would not be our
>> friend here. That is, Google *Search*, _not_ Code.
>
> Ah, got it. It seemed like you were suggesting that the proposed
> solution was wrong.
>
> However, the MSDN link you got from the search result doesn't mention
> filter: alpha, but the DXImageTransform filter instead.
The link at the bottom, which I mentioned, describes scripting filters in
general, though. And perhaps a later Google Web Search hit would point
directly to it (I cannot be bothered to check).
>>> 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:
>>
>> It was the solution for this specific example, of course.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> QUick example:
>>> javascript: alert(document.body.style.filters.item("alpha"))
>>
>> Nobody set the filter on the BODY element here.
>
> Right. So BODY has no filter. When reading el.filters.item("alpha") off
> an element that has no alpha filter, an error is produced.
I have marked the important part that you are still missing. I am writing
for intelligent people, so a general solution would use feature-testing
code, of course, thus would be unlikely to break as you describe.
> [snipped: preaching to the choir]
>>> It is a more significant problem when the advice on MSDN is followed:
>>>> <http://msdn.microsoft.com/en-us/library/ms532967(VS.85).aspx>
>>>>
>>> [...]
>>>> 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.
>>
>> It does not work at all in older IEs (without DirectX support), while the
>> Alpha filter is backwards-compatible. The additional features of the
>> DirectX filter are also seldom used.
>
> DXImageTransform works in IE5.5 and above.
True. Apparently you have not been paying attention.
> Aside from the error produced when the element has no fitlers, testing
> your approach in IE5.5, using IE Tester, I get an error, even when the
> alpha filter is specified.
>
> "Error accessing the OLE Registry."
A known bug of IE Tester, if you had bothered to check its homepage.
>>> The problem is when trying to read the filter using
>>> the approach el.filters.item("alpha").opacity.
>>>
>>> The result is an error is produced.
>>
>> Borken as designed.
>
> Filters do not map so well to CSS. Particularly when an element wants to
> use more than 1 filter.
Nonsense.
>>> There are two alpha filters:
>>
>> Yes, one uses DirectX Image Transformation (DXImageTransform) and the
>> other one does not.
>
> [...]
>
> Apparently filter opacity was removed in IE8:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
http://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=331735
>
> See also:
> https://developer.mozilla.org/en/CSS/opacity
According to my tests, IE 8 does not support the `opacity' CSS property for
images.
> Apparently they put it back. Both alpha and its DX mimic work fine for
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> me (using IE8 in IETester).
^^^^^^^^^^^^^^^^^^^^^
You are not making sense. (And yes, filters still work as before in IE 8.)
In any case: I would never have used `filter' within the `style' attribute
value to begin with; proprietary features like this belong in layout-engine
specific stylesheets and scripts, here with Conditional Comments:
<!--[if IE]>...<![endif]-->
> [TLDR]
>
>>> Conclusion:
>>> By parsing the filter string, either type of alpha filter can be read.
>>
>> To conclude that therefore this would be the best way is a fallacy,
>> though.
>
> Parsing the filter string works for both type of filter setting and does
> not result in error.
So does proper feature-testing. There is also little chance of a false
positive with that, much in contrast to your approach. String parsing being
generally less efficient than property access notwithstanding.
> Feading the el.filters.item("alpha"), will result in error
> [snipped: preaching to the choir]
Would you *please* stop and drop it?
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
> Thomas 'PointedEars' Lahn wrote:
>> Garrett Smith wrote:
>>> The problem is when trying to read the filter using
>>> the approach el.filters.item("alpha").opacity.
>>>
>>> The result is an error is produced.
>>
>> Borken as designed.
>>
>>> There are two alpha filters:
>>
>> Yes, one uses DirectX Image Transformation (DXImageTransform) and the
>> other one does not.
>>
>>> 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
>
> Man, I'm confused.
(I was afraid that you might, with Garrett missing my point.) Don't be.
> SHould I use
> -ms-filter:"alpha(opacity=52)"
> or
> -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=52)"
No.
filter: Alpha(opacity=52)
works just fine in all IEs from version 4.0 forward. Be sure to include the
stylesheet with Conditional Comments, though.
> ?
>
> Anyhow I'm also thinking of using try/catch:
Don't (here).
> as I'd rather not not use a regexp (no great reason).
Use feature-testing instead.
>> There are two alpha filters:
>
> Yes, one uses DirectX Image Transformation (DXImageTransform) and the other
> one does not.
>
>> 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)"
In IE 8
If I set the inline style to
filter:alpha(opacity=52)
imgRef.filters.item("alpha").opacity
returns the appropriate value.
If I set the inline style to
-ms-filter:alpha(opacity=52)
imgRef.filters.item("alpha").opacity
returns the appropriate value.
If I set the inline style to
-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(opacity=52)'
imgRef.filters.item("DXImageTransform.Microsoft.Alpha").opacity
returns the appropriate value.
Assuming that I set the style using code, how do I test for the "best"
one to use for any IE?
[Sigh, why can't MS just implement style.opacity.]
Andrew Poulos
filter:alpha(opacity=52);
-ms-filter:alpha(opacity=52)
Or substitute the DXImageTransform variation (unless you care about IE
< 5.5). ISTM they had a -filter variation for a while too (maybe just
during Beta testing). They are nutty with this stuff, but it isn't
that hard if you think about it. The first rule is going to work for
everything but IE8 standards mode. The second will be thrown out by
everything but IE8 standards mode. IE8 standards mode will recognize
both and since they are the same, it doesn't matter which it chooses.
>>> 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
>
> Man, I'm confused.
It's a messy situation.
SHould I use
> -ms-filter:"alpha(opacity=52)"
> or
> -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=52)"
> ?
Either for IE8, but for browsers 8 and below, that won't work. The old
syntax will:
If Microsoft decides to drop the older one, you could use both:
-ms-filter:"alpha(opacity=52)";
filter: alpha(opacity=52);
The result would be older IE would apply the second filter and IE8 would
apply the first and second (which are the same thing), and hypothetical
future version of IE would apply the first only.
or:
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=52)";
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=52);
Given Microsoft's stance on not supporting invalid syntax, and also
because it *is* invalid syntax, it might be better to not use that.
>
> Anyhow I'm also thinking of using try/catch:
Yep. IE produces "unspecified error" when alpha has not been declared in
the element's filters. This is a misfortunate tight coupling.
To ensure that the error is not produced when reading
el.filters.item("alpha"), a try catch is needed.
AIUI, the "unspecified error" is an ActiveX error that has propagated
back to the script. The MSDN documentation Thomas linked to does not
mention that error, though it seems hard to imagine that the person who
all of the examples provided there could not have noticed it at some
point. He probably did get that error at some point and so I wonder why
it was not mentioned there.
>
> var val;
> try {
> val = imgRef.filters.item("alpha").opacity;
> } catch (err) {
> val = 100;
> }
>
> as I'd rather not not use a regexp (no great reason).
>
That function will fail to read opacity if the CSS uses DXImageTransform.
To support both cases, two try/catch would be needed. This is the
approach YUI uses:
http://developer.yahoo.com/yui/docs/Dom.js.html
YUI accesses the filter directly, not using item() method.
a.filters['DXImageTransform.Microsoft.Alpha'].opacity.
Personally I find that nested try/catch to be much messier than a
regexp. It is also going to be less efficient when one or more errors
are thrown and caught.
A possible strategy would be for your code to only use one of the filter
types (the shorter alpha() is an attractive choice). This would
eliminate the need for at least one try/catch.
Allow both filter types allows little more flexibility in the CSS (less
tight coupling of css to script). To make this happen, the script must
either:
1) use try/catch for both filter types
2) parse the filter string
The first option should be a little slower when one or more errors are
thrown. Parsing the currentStyle.filter string with regexp might seem
messy, but I find it a bit messier to have the try/catch wrapping it all.
If that is not enough, the filters collection is also callable, and the
filter string and the Opacity property are all case-insensitive. So the
following can work:
// This line dedicated to VK.
a.filters('dXiMAgeTrAnsfoRM.Microsoft.AlphA').OpAcItY;
No. Use isHostObjectProperty (which uses typeof). It's another
"unknown" type as it is an ActiveX property.
Inexplicably, I have a raw typeof test in mine. I had commented out
the bogus filters collection based branch in the setter years ago, but
never updated the getter. It should have been using
isHostObjectProperty, which disallows 'unknown' types. It's a rare
case that this method is needed outside of feature detection. Or you
could just inline the test as it is simple, but I like having it
centralized in case MS (or somebody else) introduces a new type of
trouble.
Trying it in IE8, this does appear sufficient:-
typeof el.filters.alpha != 'undefined'
If it isn't there, it is 'undefined', if it is, I am sure it is
"unknown", so you shouldn't type convert it. That's where
isHostObjectProperty comes in handy as you don't have to think about
this stuff.
So you could test:-
typeof el.filters.alpha != 'undefined' && el.filters.alpha.enabled
&& ...
But not:
typeof el.filters.alpha != 'undefined' && el.filters.alpha &&
el.filters.alpha.enable && ...
Of course, the first one leaves out the possibility that
el.filters.alpha is null (something isHostObjectProperty handles as
well). And, as mentioned, it is best to leave the filters collection
alone and use a RegExp on the serialization (filter style).
> In IE 8
>
> If I set the inline style to
> filter:alpha(opacity=52)
> imgRef.filters.item("alpha").opacity
> returns the appropriate value.
>
> If I set the inline style to
> -ms-filter:alpha(opacity=52)
> imgRef.filters.item("alpha").opacity
> returns the appropriate value.
>
> If I set the inline style to
> -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(opacity=52)'
> imgRef.filters.item("DXImageTransform.Microsoft.Alpha").opacity
> returns the appropriate value.
>
> Assuming that I set the style using code, how do I test for the "best"
> one to use for any IE?
For any IE/MSHTML 4.0 to 8.0 (filters were not supported before), use (
filter: alpha(opacity=50)
or
filter: Alpha(opacity=50)
) and (
imgRef.filters.item("Alpha").opacity
or
imgRef.filters.Alpha.opacity
or
imgRef.filters.alpha.opacity
)(MSHTML does not appear to be picky there; in Conditional Comments).
That there is yet another possibility to set it now is _not_ sufficient a
reason to make use of it. If and when IE 8.1/9 is about to be released and
no longer supports `filter: Alpha', you should worry about a different
approach; but not before.
> [Sigh, why can't MS just implement style.opacity.]
Sigh. [psf 10.1] Why can't people just read my postings thoroughly, and
make the *proper* tests? Why do they have to make things more complicated
than they need to be?
`filter: Alpha' works fine in IE 8 for images, too, and so does
`imgRef.filters.items("Alpha")' then. Tested¹. Again. Positive.
*Really.*
PointedEars
___________
¹ In
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET
CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR
3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1)"
and
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR
1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR
3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1)",
i.e. in MSHTML Compatibility Mode *and* Strict Mode.
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
> On Nov 21, 12:43 am, Andrew Poulos <ap_p...@hotmail.com> wrote:
>> [...]
>> Assuming that I set the style using code, how do I test for the "best"
>> one to use for any IE?
>>
>> [Sigh, why can't MS just implement style.opacity.]
>
>
> filter:alpha(opacity=52);
> -ms-filter:alpha(opacity=52)
Nonsense.
> Andrew Poulos wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Garrett Smith wrote:
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>> Andrew Poulos wrote:
>>>> 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
>> Man, I'm confused.
>
> It's a messy situation.
Nonsense. The problem is only in your head.
Hardly.
> Trying it in IE8, this does appear sufficient:-
>
> typeof el.filters.alpha != 'undefined'
>
> If it isn't there, it is 'undefined', if it is, I am sure it is
> "unknown", so you shouldn't type convert it
If it is `unknown', your test would produce a false positive.
> That's where isHostObjectProperty comes in handy as you don't have to
> think about this stuff.
As long as it handles this case.
> So you could test:-
>
> typeof el.filters.alpha != 'undefined' && el.filters.alpha.enabled
> && ...
ACK
> But not:
>
> typeof el.filters.alpha != 'undefined' && el.filters.alpha &&
> el.filters.alpha.enable && ...
ACK
> Of course, the first one leaves out the possibility that
> el.filters.alpha is null (something isHostObjectProperty handles as
> well). And, as mentioned, it is best to leave the filters collection
> alone and use a RegExp on the serialization (filter style).
Nonsense.
> Thomas 'PointedEars' Lahn wrote:
>> David Mark wrote:
>> > On Nov 21, 12:43 am, Andrew Poulos <ap_p...@hotmail.com> wrote:
>> >> [...]
>> >> Assuming that I set the style using code, how do I test for the "best"
>> >> one to use for any IE?
>> >>
>> >> [Sigh, why can't MS just implement style.opacity.]
>> >
>> > filter:alpha(opacity=52);
>> > -ms-filter:alpha(opacity=52)
>>
>> Nonsense.
>
> Hardly.
The new `-ms-filter' nonsense is unnecessary here.
It certainly does.
>
> > So you could test:-
>
> > typeof el.filters.alpha != 'undefined' && el.filters.alpha.enabled
> > && ...
>
> ACK
>
> > But not:
>
> > typeof el.filters.alpha != 'undefined' && el.filters.alpha &&
> > el.filters.alpha.enable && ...
>
> ACK
>
> > Of course, the first one leaves out the possibility that
> > el.filters.alpha is null (something isHostObjectProperty handles as
> > well). And, as mentioned, it is best to leave the filters collection
> > alone and use a RegExp on the serialization (filter style).
>
> Nonsense.
>
There you go again. It is certainly not nonsense. It is far more
robust as IE5.x has problems when dealing with the filters
collection. Granted, I've only ever seen it on XP in a multi-IE
setup, but that setup was otherwise reliable AFAIK. And I would
prefer not to break if and when MS drops support for the old-style
alpha(opacity=...) style which was deprecated by MS in IE5.5.
Thinking again, I had it right to begin with. I should _not_ have
used isHostObjectProperty for that as I did not type convert the
object referenced by the alpha property. All I needed to know in that
case was whether it was undefined. But I still don't like messing
with the filters collection in a GP library. Seems inefficient to
check for both styles in this way (certainly either must be allowed).
I didn't say it was necessary. Just a good idea if the reports are to
be believed about -ms-filter. I'm not saying they necessarily are. I
haven't looked into it and don't really care. Personally, I'll wait
and see.
Correction: when and if they drop support for the filter style. As
for dropping alpha(opacity=...), I wouldn't put it past them and don't
care about IE4 anymore, so I think I would favor that today.
And I saw your comment about IE tester. I don't think that's the one
I had, but it could have had DLL mismatch problems. I suppose that
doesn't really matter. We had this discussion back during the Code
Worth Recommending suggestion period.
> Thomas 'PointedEars' Lahn wrote:
>> David Mark wrote:
>> > Of course, the first one leaves out the possibility that
>> > el.filters.alpha is null (something isHostObjectProperty handles as
>> > well). And, as mentioned, it is best to leave the filters collection
>> > alone and use a RegExp on the serialization (filter style).
>> Nonsense.
>
> There you go again. It is certainly not nonsense.
Yes, it is. There is only one "CSS" property declaration necessary, and the
results of that declaration are much more easily feature-tested than parsed.
> It is far more robust as IE5.x has problems when dealing with the filters
> collection.
I stand corrected in that accessing `filters' is apparently not possible in
*Standalone* IE 5.0 and 5.5 (tested on Wine). However, I must be very much
mistaken if <http://PointedEars.de/ufpdb/> broke as I wrote it back in 2000
(it uses the blendTrans filter to blend-out the UFP logo after a while).
Unfortunately, a real IE 5.x is hard to come by these days.
> [...] I would prefer not to break if and when MS drops support for the
> old-style alpha(opacity=...) style which was deprecated by MS in IE5.5.
`opacity' can take over almost seamlessly then; all it takes is changing
<!--[if IE]>...<![endif]-->
into
<!--[if IE lt $VERSION]>...<![endif]-->
Or, if you are a precog, you could write
<!--[if IE lte 8]>...<![endif]-->
in the first place ;-)
That second one doesn't work for me in IE8 on IETester.
To follow the recommended syntax from microsoft, for -ms-filter, quotes
are needed around the value. Values may be comma-separated. The
following works in IE8 (IETester):
-ms-filter: "alpha(opacity=52)"
> Or substitute the DXImageTransform variation (unless you care about IE
With quotes.
Example:
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=52)";
IE5.5 supports:
filter: "alpha( Opacity = 40 );";
Interesting, but I almost never have cause to set opacity in style
sheets.
>
> > Or substitute the DXImageTransform variation (unless you care about IE
>
> With quotes.
> Example:
> -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=52)";
>
> IE5.5 supports:
> filter: "alpha( Opacity = 40 );";
That first semi-colon appears to be a typo. MS has waffled on the
case over the years (in their examples anyway), but it has always been
case insensitive, so I use lowercase.
BTW, there does appear to be a "need" for a third isHost* function.
isHostObjectPropertyButDontTouchIt = function(obj, prop) {
return typeof obj[prop] == 'unknown' || (typeof obj[prop] ==
'object' && obj[prop]);
};
That takes care of the case where MS (or some copycat) switches to
null for missing filters (not inconceivable).
The other one mentioned (isHostObjectProperty) is designed to filter
ActiveX objects, so it is used for properties that may need to be
"touched" (e.g. assigned to a variable, type converted, etc.) like
document.all. You never have to touch these filter objects (just
their properties).
[snips]
> Trying it in IE8, this does appear sufficient:-
>
> typeof el.filters.alpha != 'undefined'
>
> If it isn't there, it is 'undefined', if it is, I am sure it is
> "unknown", so you shouldn't type convert it. That's where
> isHostObjectProperty comes in handy as you don't have to think about
> this stuff.
>
I am not sure. I am getting "object" in IETester. Is this IETester
related result?
> So you could test:-
>
> typeof el.filters.alpha != 'undefined' && el.filters.alpha.enabled
> && ...
>
> But not:
>
> typeof el.filters.alpha != 'undefined' && el.filters.alpha &&
> el.filters.alpha.enable && ...
>
> Of course, the first one leaves out the possibility that
> el.filters.alpha is null (something isHostObjectProperty handles as
> well). And, as mentioned, it is best to leave the filters collection
> alone and use a RegExp on the serialization (filter style).
I have noticed an occasional "unknown error" with either of:
1) el.filters.alpha
2) el.filters["progid:DXImageTransform.Microsoft.Alpha"];
The error does not always occur. I have never understood why it occurs
sometimes and other times it does not.
Typeconverting, etc, and I do not get an error in my test page:
if(el.filters["alpha"]) { /*no error?*/ }
I remember getting errors from that before and I see in YUI the
try/catch, plus a comment.
http://developer.yahoo.com/yui/docs/Dom.js.html
(search for "opacity");
Avoiding that error is my reason for using the currentStyle.filter
string. That has never given me errors.
What is the condition where either (1) or (2) give errors? It is hard to
justify a workaround I when I cannot reproduce the error. Need to know
exactly where and what causes that error.
If you get "object", it shouldn't blow up. But regardless, see that
function I posted for the basic logic that should work every time
without fear of explosions.
>
> > So you could test:-
>
> > typeof el.filters.alpha != 'undefined' && el.filters.alpha.enabled
> > && ...
>
> > But not:
>
> > typeof el.filters.alpha != 'undefined' && el.filters.alpha &&
> > el.filters.alpha.enable && ...
>
> > Of course, the first one leaves out the possibility that
> > el.filters.alpha is null (something isHostObjectProperty handles as
> > well). And, as mentioned, it is best to leave the filters collection
> > alone and use a RegExp on the serialization (filter style).
>
> I have noticed an occasional "unknown error" with either of:
> 1) el.filters.alpha
> 2) el.filters["progid:DXImageTransform.Microsoft.Alpha"];
That's when they are "unknown" types. Remember IE changes host object
types sometimes (e.g. element nodes orphaned by innerHTML). From
"object" to "unknown" seems to indicate a shift in the implementation
behind the scenes to an ActiveX object. God only knows why they would
do it, but it is their right as browser developers. As has always
been the case with MSHTML (and everything else AFAIK), typeof lets you
"peek" without triggering an exception.
>
> The error does not always occur. I have never understood why it occurs
> sometimes and other times it does not.
I never tried to understand such things. :)
>
> Typeconverting, etc, and I do not get an error in my test page:
>
> if(el.filters["alpha"]) { /*no error?*/ }
You would for sure if that filter object was an "unknown" type.
>
> I remember getting errors from that before and I see in YUI the
> try/catch, plus a comment.http://developer.yahoo.com/yui/docs/Dom.js.html
> (search for "opacity");
YUI doesn't know how to feature test MSHTML. Odd considering how many
times this has come up over the years (and that the behavior is
unchanged since at least IE6).
>
> Avoiding that error is my reason for using the currentStyle.filter
> string. That has never given me errors.
It won't. It's definitely the most robust approach, but because of
the ActiveX nonsense. Some multi-IE setups won't handle the filters
collection. First time I saw that on XP, I wondered how my (then)
eight-year old DX code could have broken. Then I went to the MSDN
filter and transitions demo page and saw the same thing. So it is
probably a DLL mixup.
>
> What is the condition where either (1) or (2) give errors?
Properties of ActiveX (unknown type) throw errors on type conversion,
assignment to a variable, etc. You really can't do anything to or
with them directly (other than the typeof operation). It's been
floated that a rigged internal [[Get]] is to blame. But who really
knows? The main thing to know is that they all behave exactly the
same.
> It is hard to
> justify a workaround I when I cannot reproduce the error. Need to know
> exactly where and what causes that error.
I thought you were getting errors at some point. (?) See that last
function. It's a slight modification of isHostObjectProperty.
[snips]
[snip explanation]
That seems to explain it.
>
>> It is hard to
>> justify a workaround I when I cannot reproduce the error. Need to know
>> exactly where and what causes that error.
>
> I thought you were getting errors at some point. (?) See that last
> function. It's a slight modification of isHostObjectProperty.
I was getting errors at some point.
The last example I made did not exhibit the error. Out of curiosity, I
want to know the exact circumstances that can reproduce this error.
I see now that it's a "behind the scenes" type of thing. The code behind
the filters is likely as bizarre and complex as the filters interface,
but I still wonder about the conditions it occurs under.
Regexing the currentStyle.filters string has not let me down, and avoids
the problem, so I will continue as I have been doing. I just wonder
about when the unknown error occurs.
I assume you mean the errors induced by looking too closely at the
object referenced by an ActiveX property (typeof xyz == 'unknown').
>
> The last example I made did not exhibit the error. Out of curiosity, I
> want to know the exact circumstances that can reproduce this error.
I haven't considered it (and prefer not to), but I'll take a wild stab
in the dark and say that the deprecated alpha filter syntax produces a
"normal" host object, which is reported by the browser as an "object"
type. Perhaps the new style results in an ActiveX object ("unknown"
type) behind the scenes? You might try it out if you really want to
know, but I would use a real IE installation.
But best to cover both bases (as the suggested function does). And
ultimately faster to cover both bases with the (string) filter
property. The worst possibility would be testing filters with nested
try-catch clauses, which is both brittle (e.g. IE < 6 on XP) and slow.
>
> I see now that it's a "behind the scenes" type of thing. The code behind
> the filters is likely as bizarre and complex as the filters interface,
> but I still wonder about the conditions it occurs under.
I'm sure it is a mess behind the scenes.
>
> Regexing the currentStyle.filters string has not let me down, and avoids
> the problem, so I will continue as I have been doing. I just wonder
> about when the unknown error occurs.
I'm sure you meant the currentStyle.filter string.