Friday, January 18, 2008

Next! - getStyle

Hi, we all need sometimes to get the style of one HTMLElement, and most times we do

var a=theelement.style.color;

If there was a "color" rule on the element own style, that will work. But it wont work if the "color" was set on a CSS rule.
So that breaks, for example in PrototypeJS they have $("elid").visible() that should return true if the element is visible, how they check?

element.style.display!="none";

But that will say the object is visible if i set it to display:none on a CSS rule

While working with PrototypeJS i had lots of troubles cause i always had to use style="display:none" or the animation stuff ( Script.aculo.us ) would not work.

This guy http://berniecode.com/writing/animator.html did a fix on the code he use for animate CSS properties, so i adapted it to work on Next!, its cross browser

/**
* Get the value of the style
* Based on http://berniecode.com/writing/animator.html
* @param {String} style
*/
HTMLElement.prototype.getStyle=function(property, def){
def=(def===undefined)?"":def;
if (property=="float" || property=="cssFloat" || property=="propertyFloat"){
property=(this.style.styleFloat)?"styleFloat":"cssFloat";
}
if (property=="opacity" && this.filters){
try{
return this.filters.item("Alpha").opacity/100;
}catch(e){
return 1;
}
}
var style;
if(document.defaultView && document.defaultView.getComputedStyle){
style = document.defaultView.getComputedStyle(this, "").getPropertyValue(property);
if (style) {
return style;
}
}
property = property.camelize();
if(this.currentStyle){
style = this.currentStyle[property];
}
return style || this.style[property];
};

This function itself fix also the "opacity" so in this lib you can not only set the opacity but you can get the opacity of the element even if it is a filter ( IE ) on some CSS rule

This code is need and really moves the library to a next stage, we can get the REAL style of the element not only the in-line style, just great!

Now that we have a getStyle we must also have a setstyle
setStyle its simpler it will just set the inline style of the element

/**
* Set the style of the element
* @param {String|Object} style
* @return {HTMLElement}
*/
HTMLElement.prototype.setStyle=function(style){
if (String.is(style)){
this.style.cssText+=";"+style;
if (style.contains("opacity:")){
this.setOpacity(style.match(/opacity:\s*(\d?\.?\d*)/)[1]);
}
}else if (Object.is(style)){
for (i in style){
if (i == "float" || i == "cssFloat" || i == "styleFloat") {
this.style.cssFloat=style[i];
this.style.styleFloat=style[i];
}else if (i=="opacity"){
this.setOpacity(style[i]);
}else{
this.style[i]=style[i];
}
}
}
return this;
};

This code is still missing a fix, it will be done soon, but the base idea is that you can do
theelement.setStyle("color:red;");
theelement.setStyle({"color":"red"});

More things are comming!!

No comments: