CSS3 PIE Forums
http://css3pie.com/forum/

Attach PIE.js automatically on elements with CSS3 properties
http://css3pie.com/forum/viewtopic.php?f=4&t=1306
Page 1 of 3

Author:  xem [ Sat Oct 15, 2011 6:01 am ]
Post subject:  Attach PIE.js automatically on elements with CSS3 properties

.
.
. => PIE_auto 0.1: viewtopic.php?f=4&t=1306&p=4539#p4539 <=
.
.





Hi,

I made this JS code to manage automatically which elements need PIE, and attach PIE to it (it uses jQuery):

Code:

function getStyleProperty(element, styleProperty)
{
  var prop="";
  if(element.currentStyle)
  {
    prop=element.currentStyle[styleProperty];
  }
  else if(window.getComputedStyle)
  {
    prop=document.defaultView.getComputedStyle(element,null).getPropertyValue(styleProperty);
  }
  return prop;
}

// When the page is loaded
$(function()
{
  // attach PIE on elements with CSS3
  if(window.PIE)
  {
    $("body *").each(function()
    {
     if(getStyleProperty(this,'border-radius')||getStyleProperty(this,'box-shadow')||getStyleProperty(this,'-pie-background'))
     {
       PIE.attach(this);
     }
    });
  }
});



It only detects border-radius, box-shadow and -pie-background for now.
It works.
Do you have other/better ideas?
Could such a system be part of a future version of PIE.js? (or even PIE.htc?)

I tried it on a huge page (300 CSS3 elements + 5000 non-css3 elements) and this code takes about 3 seconds to run. (not far from the regular use of PIE.js in such a case, I guess)

Thanks for your advices

Author:  webaware [ Mon Nov 07, 2011 3:33 pm ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

You could try replacing the jQuery search and iteration with a simple iteration over document.all; it should speed things up a little:

NB: this loop variant is the fastest style on IE

Code:
var i, element;
for (i = document.all.len; i--; ) {
    element = document.all[i];
    // your test and attach code here, replacing "this" with "element"
}


But the PIE.attach call is likely to be the biggest delay here. If you have a *lot* of elements this applies to, you might just have to look for other solutions. e.g. we recently dropped the PIE linear gradients on a website because the stupid design had them on every menu item on a big drop-down menu and an equally big expanding side menu; the DirectX filters gave us the same linear gradients without the performance hit.

Author:  xem [ Fri Nov 18, 2011 9:14 am ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

Thanks for your advice webaware

My goal wasn't really to cover cases of huge pages with lots of Pie's elements, I just want to automate the process of PIE attachment to any element needing it.

You're right about the non-use of jQuery, and about the more efficient use of other fixes than PIE in particular cases.

Anyway, I'm going to try your code. I'll post an updated version here if it works!

Author:  guugie [ Fri Nov 18, 2011 12:22 pm ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

Very nice script. Thank you very much, will use it on my current project, right now :?

Author:  xem [ Mon Nov 21, 2011 1:41 am ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

No problem, it's here to be shared (and enhanced by people that know Javascript better than me ^^)

Author:  xem [ Mon Nov 21, 2011 10:24 am ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

Help: the solution above doesn't work. This does nothing:
Code:
<script>
  // CSS property tester
  function getStyleProperty(element, styleProperty)
  {
    var prop="";
    if(element.currentStyle)
    {
      prop=element.currentStyle[styleProperty];
    }
    else if(window.getComputedStyle)
    {
      prop=document.defaultView.getComputedStyle(element,null).getPropertyValue(styleProperty);
    }
    return prop != undefined;
  }

  // Attach PIE to all elements having a CSS3 property
  window.onload = function()
  {
    if(window.PIE)
    {
      for (i = document.all.len; i--; )
      {
        element = document.all[i];
        if(getStyleProperty(element,'border-radius')||getStyleProperty(element,'box-shadow')||getStyleProperty(element,'-pie-background'))
        {
         PIE.attach(element);
        }
      }
    }
  }

Author:  webaware [ Mon Nov 21, 2011 3:21 pm ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

Sorry, this:
Code:
for (i = document.all.len; i--; )

should be this:
Code:
for (i = document.all.length; i--; )

Author:  xem [ Tue Nov 22, 2011 4:15 am ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

Indeed, thanks, it works perfectly on IE6-7-8

But on IE9, my getStyleProperty test passes on every element of the page, not just the 3 DIVs

( IE9 always agrees with "if(getStyleProperty(element,'border-radius')||getStyleProperty(element,'box-shadow')||getStyleProperty(element,'-pie-background'))" )

Do you know why?

Do you have a better way to detect if a css property is applied to an element?

Maybe jQuery's .css() ...

Author:  xem [ Tue Nov 22, 2011 6:40 am ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

Nope, jQuery's .css() doesn't have any effect.

And I couldn't find a way to attach PIE only to the right elements on IE9...

Author:  xem [ Tue Nov 22, 2011 6:51 am ]
Post subject:  Re: Attach PIE.js automatically on elements with CSS3 proper

I did it! The CSS3 properties (inline or separated) are now tested distinctly for IE<9 and IE >= 9. Now, all works fine.
Here's the demo page (needs PIE.js in the same folder):


Sadly, I can't make IE6 read the "-pie-background" property, I'd like Jason to look if he has a solution...


Code:
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>PIE</title>
  <!--[if lt IE 10]><script type="text/javascript" src="PIE.js"></script><![endif]-->
  <style>
    #div1{border-radius: 50%; width: 200px; height: 100px; border: 1px solid black; padding: 40px 90px;}
    #div2{box-shadow: #000 10px 10px 10px; width: 200px; height: 100px; border: 1px solid black; padding: 40px 90px; background: #fff;}
    #div3{-pie-background: linear-gradient(#000, #fff); width: 200px; height: 100px; border: 1px solid black; padding: 40px 90px;}
  </style>
</head>

<body>
  <div style="border-radius: 50%; width: 200px; height: 100px; border: 1px solid black; padding: 40px 90px;">ok</div>
  <br>
  <div style="box-shadow: #000 10px 10px 10px; width: 200px; height: 100px; border: 1px solid black; padding: 40px 90px; background: #fff;">ok</div>
  <br>
  <div style="-pie-background: linear-gradient(#000, #fff); width: 200px; height: 100px; border: 1px solid black; padding: 40px 90px;">ok</div>
  <br>
  <div id="div1">ok</div>
  <br>
  <div id="div2">ok</div>
  <br>
  <div id="div3">ok</div>

  <script>
  // CSS property tester
  function getCSS(e, p)
  {
    var prop = "";
    if(e.currentStyle)
    {
      prop = e.currentStyle[p];
    }
    else if(window.getComputedStyle)
    {
      prop = document.defaultView.getComputedStyle(e,null).getPropertyValue(p);
    }
    return prop;
  }

  // Attach PIE to all elements having a CSS3 property
  window.onload = function()
  {
    if(window.PIE)
    {
      for (i = document.all.length; i--; )
      {
        e = document.all[i];
        if ((getCSS(e, 'border-radius') != undefined && getCSS(e, 'border-radius') != "0px" ) // For IE < 9, border-radius, if not set, is undefined, for IE >= 9 it's "0px"
        || ( getCSS(e, 'box-shadow') != undefined && getCSS(e, 'box-shadow') != "none" )      // For IE < 9, box-shadow, if not set, is undefined, for IE >= 9 it's "none"
        || getCSS(e, '-pie-background') != undefined )                                        // For all IE, -pie-background, if not set, is undefined (except IE6, still to fix)
        {
          // alert("ok"); // Uncomment this line to be sure we do only 6 PIE.attach
          PIE.attach(e);
        }
      }
    }
  }
  </script>
</body>

</html>

Page 1 of 3 All times are UTC - 7 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/