开发者

updating contents of stylesheet with .innerText slow

开发者 https://www.devze.com 2023-01-29 23:19 出处:网络
I have a stylesheet I\'m updating the contents of on the fly, based on a user UI. I noticed that in Firefox ( which uses stylesheet.innerHTML )开发者_如何转开发 and IE ( which uses stylesheet.styleShe

I have a stylesheet I'm updating the contents of on the fly, based on a user UI. I noticed that in Firefox ( which uses stylesheet.innerHTML )开发者_如何转开发 and IE ( which uses stylesheet.styleSheet.cssText) works well.

It seems that Chrome and Safari ( which use stylesheet.innerText ) run incredibly slow on larger stylesheets. Has anyone run into this and/or found better solutions?

EDIT: It's not possible to use JS to change inline styles since the application never refreshes and the user can switch "pages" thereby nuking the inline styles. Also if I want to use the UI to modify links, I can't use inline to modify pseudo classes such as :hover ( as far as I know )


So this has been my function for updating stylesheets for the past year or so:

function(style, style_value) {

  if ('cssText' in style.styleSheet) {

    // without this line, IE WILL crash, if no stylesheet settings were set
    if ( typeof(style_value) != 'string' || !style_value.length) {
      return;
    }
    style.styleSheet.cssText = style_value;

  }
  else {
    style.innerHTML = style_value;
  }

}


It makes the sense that reparsing CSS and reflowing the document could be slow. I suggest including all rules you could need but "namespace" them with a class on the <html> element and then change the active rules by adding and removing classes rather than using using cssText/innerText.

CSS:

.foo h1 { color: green }
.bar h1 { color: red }

JavaScript:

document.documentElement.className = new Date().getHours() >= 12 ? 'foo' : 'bar';

This would clobber any other class names on the <html> element so more careful parsing or toggling classes via jQuery (or equivalent) would generally be appropriate.

If your JavaScript knows what CSS rules actually need to change you could also modify the style rules on the fly. In practice, this is similar to modifying any elements style i.e. myElement.style.color = 'green'; Opera web curriculum has a good explanation of modifying CSS via JavaScript.

Example of cross-browser method to modify a single rule:

var modifyStyleRule;

(function(doc){
    var sheets = doc.styleSheets,
        rules = 'cssRules';
    rules = sheets[0][rules] ? rules : 'rules';

    modifyStyleRule = function (sheetIndex, ruleIndex, propertyValues) {
        var style = sheets[sheetIndex][rules][ruleIndex].style,
            prop;

        for (prop in propertyValues) {
            if (propertyValues.hasOwnProperty(prop)) {
                style[prop] = propertyValues[prop];
            }
        }
    };
})(document);

Example usage: modifyStyleRule(0, 0, {color: 'red'});.

Note that depending on the type and amount of changes you make with this (colors vs size/position) this could very easily be slower than sheet.innerHTML or equivalent. This technique does come in handy from time to time and when combined with "style namespaces" and swapping class names, large changes can be still be performant.


If you want to make it browser independent use this code:

var field = document.getElementById(id);  // where u want to use innertext

if(field != null)
{           
    if(navigator.appName == "Netscape") // appName for both FireFox and Chrome its is "Netscape" i checked it with different version.
        field.textContent = value;
    else // for For IE v 8 i checked  .textContent is not supported by IE for me it was not working. 
        field.innerText = value;    
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号