问题
I'm trying to write a Javascript function inside a Java GWT code that gets the value of the following styles
"direction", "fontFamily", "fontSize", "fontSizeAdjust", "fontStyle", "fontWeight", "letterSpacing", "lineHeight", "padding", "textAlign", "textDecoration", "textTransform", "wordSpacing"
The getComputedStyle
was useful in all browsers except IE8 which doesn't support such function as I understand
I looked at the posts about smiler subject here but all of them failed to get one of the above styles
smiler subject posts 1, 2.
Here is my initial solution without the IE8 special case
public static native String getStyleProperty(Element element, String style) /*-{
if (element.currentStyle) {
return element.currentStyle[style];
} else if (window.getComputedStyle) {
return window.getComputedStyle(element, null).getPropertyValue(
style);
}
}-*/;
Any suggestions for a good getComputedStyle
replacement function for IE8 ?
回答1:
Look over here: http://snipplr.com/view/13523/
The code:
if (!window.getComputedStyle) {
window.getComputedStyle = function(el, pseudo) {
this.el = el;
this.getPropertyValue = function(prop) {
var re = /(\-([a-z]){1})/g;
if (prop == 'float') prop = 'styleFloat';
if (re.test(prop)) {
prop = prop.replace(re, function () {
return arguments[2].toUpperCase();
});
}
return el.currentStyle[prop] ? el.currentStyle[prop] : null;
}
return this;
}
}
Example:
window.onload = function() {
var compStyle = window.getComputedStyle(document.getElementById('test'), "");
alert(compStyle.getPropertyValue("color"));
alert(compStyle.getPropertyValue("float"));
alert(compStyle.getPropertyValue("background-color"));
}
回答2:
Here is the solution. It is based on this Trick, but then I've expanded it in case to resolve two problems.
First problem is that borderTopWidth
(left
,bottom
,right
) in el.currentStyle
returns as adjective - 'thin'
, 'medium'
, 'thick'
- or 'none'
. The Trick will return exception.
And second problem - some values will not be calculated correctly. Such as opacity
and some else. You can check it by yourself by applying this Trick-method to all the properties:
var _style = el.currentStyle;
for (var key in _style) {
/// here is the Trick.....
}
At last, here is my solution, based on assumption, that I know all the properties I want to get by this function:
if (!window.getComputedStyle) window.getComputedStyle = function(el){
var __style = el.currentStyle,
_style = {};
for (var i in __style) {
_style[i] = __style[i];
}
// IE8 returns border widths as adjectives
if (style.indexOf("border") === 0)
switch (_style[style]) {
case "thin":
_style[style] = 2;
break;
case "medium":
_style[style] = 4;
break;
case "thick":
_style[style] = 6;
break;
default:
_style[style] = 0;
}
// based on http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
var leftCopy = el.style.left;
var runtimeLeftCopy = el.runtimeStyle.left;
// some properties, that I want to use
_styleParams = {
left : 1,
right : 1,
top : 1,
bottom : 1,
width : 1,
height : 1,
borderLeftWidth : 1,
borderRightWidth : 1,
borderTopWidth : 1,
borderBottomWidth : 1,
paddingLeft : 1,
paddingRight : 1,
paddingTop : 1,
paddingBottom : 1,
marginLeft : 1,
marginRight : 1,
marginTop : 1,
marginBottom : 1
}
for (var key in _styleParams) {
el.runtimeStyle.left = el.currentStyle.left;
el.style.left = _style[key];
_style[key] = el.style.pixelLeft;
el.style.left = leftCopy;
el.runtimeStyle.left = runtimeLeftCopy;
}
// opacity for IE8
if (_style.filter.match('alpha')) {
_style.opacity = _style.filter.substr(14);
_style.opacity = parseInt(_style.opacity.substring(0, _style.opacity.length-1)) / 100;
} else {
_style.opacity = 1;
}}
回答3:
Here is more complete polyfill for IE8/getComputedStyle which should handle all cases:
https://github.com/jonathantneal/Polyfills-for-IE8/blob/master/getComputedStyle.js
回答4:
I used a similar method to my original solution with an additional case to handle inline styles, also the way to check if the current document support the getComputedStyle
is a bit different it checks in the document.defaultView
instead of the window itself, here is the full function
public static native String getStyleProperty(Element el, String prop) /*-{
var computedStyle;
if (document.defaultView && document.defaultView.getComputedStyle) { // standard (includes ie9)
computedStyle = document.defaultView.getComputedStyle(el, null)[prop];
} else if (el.currentStyle) { // IE older
computedStyle = el.currentStyle[prop];
} else { // inline style
computedStyle = el.style[prop];
}
return computedStyle;
}-*/;
source
回答5:
The best solution I've found so far was from another answer here: https://stackoverflow.com/a/17890142/3672465. It's a standalone version of the jQuery curCSS() code; you may need to adjust it to suit your needs (as Maksim notes in his answer). Here's a compact version of the IE 8 portion, if you just want something to drop in.
if( !window.getComputedStyle && document.documentElement.currentStyle ){
function getStyles( elem ){ return elem.currentStyle; };
function curCSS( elem, name, computed ){
var rnum = /^([+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/i;
var t = 'left', l, rs, rsL, c = computed || getStyles( elem ),
r = c ? c[ name ] : undefined, s = elem.style;
if( r == null && s && s[ name ] ){ r = s[ name ]; }
if( rnum.test( r ) && !/^(top|right|bottom|left)$/.test( name ) ){
l = s[t]; rs = elem.runtimeStyle; rsL = rs && rs[t];
if( rsL ){ rs[t] = elem.currentStyle[t]; }
s[t] = name === 'fontSize' ? '1em' : r; r = s.pixelLeft + 'px';
s[t] = l; if( rsL ){ rs[t] = rsL; }
}
return r === '' ? 'auto' : r;
};
}
来源:https://stackoverflow.com/questions/21797258/getcomputedstyle-like-javascript-function-for-ie8