In keeping with this week’s theme of researching backward compatibility of the various projects I’ve worked on over the past year I decided to figure out why parts of my fast animation framework weren’t updating as expected. The short answer is that IE 11 (and presumably 10 and 9 as well) simply does not process more than one parameter passed to a scale
command in a style.transform
assignment. I originally saw this happen in the debugger using the transform
property directly. Changing the code to use msTransform
(both when hard-coded and when switched after detection) didn’t change the behavior.
Here’s the relevant code running in the IE 11 debugger, as it appears just after having executed the statement at line 957. (transformPrefix
has the value of “msTransform” in this case.)
…and here is the value of the variable we have supposedly assigned:
Doing the same thing in most other browsers results in the watch values taking on the expected result with both parameters. Although the Mozilla spec says that browsers should accept an optional second parameter, IE does not do so.
The solution, therefore,is to test to see if we’re running IE (9 or later?) and handle this scaling operation with only a single parameter as a special case. This means we cannot specify different scaling factors in the x- and y-directions but hey, it is what it is and it will do something. If we really, truly need to scale the axes independently then we can create a mechanism that uses the scaleX
and scaleY
commands separately.
I’ll implement the custom code tomorrow.
I used this code to detect which browser I was using and which prefixes I should use.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
function GetVendorPrefix(arrayOfPrefixes) { var tmp = document.createElement("div"); var result = ""; for (var i = 0; i < arrayOfPrefixes.length; ++i) { var fred = tmp.style[arrayOfPrefixes[i]]; if ((typeof tmp.style[arrayOfPrefixes[i]] != 'undefined') && (typeof tmp.style[arrayOfPrefixes[i]] != "")) { result = arrayOfPrefixes[i]; break; } else { result = null; } } return result; } var transformPrefix = GetVendorPrefix(["msTransform", "MozTransform", "WebkitTransform", "OTransform", "transform"]); var transitionPrefix = GetVendorPrefix(["transition", "msTransition", "MozTransition", "WebkitTransition", "OTransition"]); var animationPrefix = GetVendorPrefix(["animation", "msAnimation", "MozAnimation", "WebkitAnimation", "OAnimation"]); var gridPrefix = GetVendorPrefix(["gridRow", "msGridRow", "MozGridRow", "WebkitGridRow", "OGridRow"]); var hyphensPrefix = GetVendorPrefix(["hyphens", "msHyphens", "MozHyphens", "WebkitHyphens", "OHyphens"]); var columnPrefix = GetVendorPrefix(["columnCount", "msColumnCount", "MozColumnCount", "WebkitColumnCount", "OColumnCount"]); |
transformPrefix
is the only value relevant in this code but I’ve included the others to demonstrate that they can be used. The code I lifted from an online example (from 2012) didn’t test for the typeof result coming back as an empty string; I had to add that when I got that result in the various debuggers when testing the value transform
. That used to be first in the list of parameters to the GetVendorPrefix
call but I moved it to the end to ensure I captured other possible results first.
Once the value of transformPrefix
is set it can be used in a couple of different ways:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//here I'm just building a string that will be executed as a standalone command function bcDefineScaleTween(sElement,pStartX,pStartY,pEndX,pEndY,tBegin,tDuration,mMethod) { //var s = sElement+".style.transform='scale("+pStartX+","+pStartY+")';"; var s = sElement+".style."+transformPrefix+"='scale("+pStartX+","+pStartY+")';"; ... //here I'm assigning the property when I can't write the new code out, transformPrefix = "msTransform" var handle003 = document.getElementById("handle003"); bcInitElement(handle003,"120px","60px","yellow","rgba(0,0,0,0)","80px",0,"block","This text grows in scale"); // here's where the action is; it works the same way if hard-coded to handle003.style.msTransform handle003.style[transformPrefix] = "scale(0.5,0.5)"; addTransformToList("handle003",0.05,{opacity:1.0},"linear","handle001:2-=0.05"); addTransformToList("handle003",1.50,{scale:"(2.0,2.0)"},"linear","+=0.50"); addTransformToList("handle003",0.00,{display:"none"}); |
It turns out that just using transform
property in most modern browsers will achieve the desired results. This must be the outcome of many years of standardization by the vendors.