LA.NET [EN]

Nov 04

Well, I’m spoiled… that’s what happens when you use frameworks like JQuery…Everything is good until that one day…someone says something stupid: “I need you to write some JS code but I don’t want external references on JQuery!”. Yep, I thought exactly the same thing: WTF???

“Now, that we’re clear on external frameworks, can you please write me a function which  receives a reference to a DOM element and returns the value of its CSS display property?”, someone asked. “Sure! no problem”, I said…After all, getting the display is just a matter of getting the CSS’ display property and we all know that it’s readily available from the style object, right? So, here’s my first attempt on this problem:

function display(elem) {
  //basic parameter checking removed
  return elem.style.display;
}

Simple, right…Then I though about writing a simple test. I’ve started with the following HTML:

<div id="a1" style="display: none"></div>

And now, the JavaScript:

alert(display(document.getElementById("a1")));

And yes,an alert with ‘none’ popped up…things were good…until that I’ve decided to add two more elements to my test page:

<div id="a2">sss</div>
<div id="a3">sss</div>

How about testing CSS applied through style sheets:

<style type="text/css">
    #a3{
        display: none;
    }
</style>

And then,I’ve simply duplicated the alert calls:

alert(display(document.getElementById("a2")));
alert(display(document.getElementById("a3")));

“And…wtf is going on here??? Where are the display values???” Yes, you’re screwed…style.display will only return a “valid” value when it’s explicitly set from JS or from the style attribute which is applied to the element (ie, the style attribute that you can use in the HTML tags). Now, how do we solve this?

There is a way, but once again, we need to write some browser testing code  because different browsers use different approaches…I’m talking about the currentStyle vs getComputedStyle dilemma…Here’s my next attempt for a cross-browser solution (where cross-browser really means IE, FF, Chrome and Opera):

function display(elem) {
  //basic parameter checking removed
  if (elem.style.display) {
    return elem.style.display;
  }

  if (elem.currentStyle) {
    return elem.currentStyle.display;
  }
  if (document.defaultView.getComputedStyle) {
    return document.defaultView
.getComputedStyle(elem,
null)
.getPropertyValue(
"display"); } return ""; }

Now, before you start thinking in adapting this code so that you can get any style property, there’s one additional detail you should keep in mind: Mozilla and Opera browsers expect CSS syntax while IE relies on JS names (ex.: background-color vs backgroundColor).

In my opinion, the easies solution for this problem is require CSS names and adapt then, when needed, convert it to JS syntax. Here’s a possible solution which expects CSS property names syntax:

function display(elem, propName) {
  //basic parameter checking removed
  if (elem.style.display) {
    return elem.style[propName];
  }
  if (elem.currentStyle) {
//copied directly from JQuery’s source –:)
var jsName = propName
.REPLACE(cast(/-(w)/g as nvarchar(max)),cast(
function (all as nvarchar(max)),cast( letter as nvarchar(max))) { return letter.toUpperCase(); }); return elem.currentStyle[jsName]; } if (document.defaultView.getComputedStyle) { return document.defaultView .getComputedStyle(elem, null) .getPropertyValue(propName); } return ""; }

Well, even with this code, it’s still interesting to notice that if, for example, you set the background-color CSS property to red, you’ll get different results (some browsers return red while others return rgb(255, 0,0). You gotta love web development!!!

I hope this imaginary scenario will help you (I should have probably said your boss!) understand that web development is more complicated than it seems at first…yes, we don’t have to do memory management (though we still need to pay attention to memory leaks), but there are still a ton of stuff to worry about…and yes, doing web development without using a modern JS framework (ex.: JQuery) is pure suicide. DON’T DO IT!

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>