Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can this solution be IE7 and IE6 compatible?

Is there any way to make this solution IE6 and IE7 compatible?

http://jsfiddle.net/kirkstrobeck/sDh7s/1/


Pulled from this question

I think I've found a real solution. I've made it into a new function:

jQuery.style(name, value, priority);

You can use it to get values with .style('name') just like .css('name'), get the CSSStyleDeclaration with .style(), and also set values - with the ability to specify the priority as 'important'. See https://developer.mozilla.org/en/DOM/CSSStyleDeclaration.

Demo

var div = $('someDiv');
console.log(div.style('color'));
div.style('color', 'red');
console.log(div.style('color'));
div.style('color', 'blue', 'important');
console.log(div.style('color'));
console.log(div.style().getPropertyPriority('color'));

Here's the output:

null
red
blue
important

The Function

// For those who need them (< IE 9), add support for CSS functions
var isStyleFuncSupported = CSSStyleDeclaration.prototype.getPropertyValue != null;
if (!isStyleFuncSupported) {
    CSSStyleDeclaration.prototype.getPropertyValue = function(a) {
        return this.getAttribute(a);
    };
    CSSStyleDeclaration.prototype.setProperty = function(styleName, value, priority) {
        this.setAttribute(styleName,value);
        var priority = typeof priority != 'undefined' ? priority : '';
        if (priority != '') {
            // Add priority manually
            var rule = new RegExp(RegExp.escape(styleName) + '\\s*:\\s*' + RegExp.escape(value) + '(\\s*;)?', 'gmi');
            this.cssText = this.cssText.replace(rule, styleName + ': ' + value + ' !' + priority + ';');
        } 
    }
    CSSStyleDeclaration.prototype.removeProperty = function(a) {
        return this.removeAttribute(a);
    }
    CSSStyleDeclaration.prototype.getPropertyPriority = function(styleName) {
        var rule = new RegExp(RegExp.escape(styleName) + '\\s*:\\s*[^\\s]*\\s*!important(\\s*;)?', 'gmi');
        return rule.test(this.cssText) ? 'important' : '';
    }
}

// Escape regex chars with \
RegExp.escape = function(text) {
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}

// The style function
jQuery.fn.style = function(styleName, value, priority) {
    // DOM node
    var node = this.get(0);
    // Ensure we have a DOM node 
    if (typeof node == 'undefined') {
        return;
    }
    // CSSStyleDeclaration
    var style = this.get(0).style;
    // Getter/Setter
    if (typeof styleName != 'undefined') {
        if (typeof value != 'undefined') {
            // Set style property
            var priority = typeof priority != 'undefined' ? priority : '';
            style.setProperty(styleName, value, priority);
        } else {
            // Get style property
            return style.getPropertyValue(styleName);
        }
    } else {
        // Get CSSStyleDeclaration
        return style;
    }
}

See https://developer.mozilla.org/en/DOM/CSSStyleDeclaration for examples of how to read and set the CSS values. My issue was that I had already set !important for the width in my CSS to avoid conflicts with other theme CSS, but any changes I made to the width in jQuery would be unaffected since they would be added to the style attribute.

Compatibility

For setting with the priority using the setProperty function, http://help.dottoro.com/ljdpsdnb.php says there is support for IE 9+ and all other browsers. I have tried with IE 8 and it has failed, which is why I built support for it in my functions (see above). It will work on all other browsers using setProperty, but it will need my custom code to work in < IE 9.

like image 484
Kirk Strobeck Avatar asked Jan 25 '12 19:01

Kirk Strobeck


2 Answers

That looks needlessly complicated.. I would just use em based font size for the tags inside the container and adjust the container's font size using percents. That way all the tag inside container get automatically resized..

JsFiddle: http://jsfiddle.net/qqxe9/

CSS:

.container {
 font-size:100%;   
}

p {
 font-size:1em;   
}

JS

function changeFontSize(n)
{
    var size = $('.container').data('size');
    size += n * 10;
    $('.container').css('font-size',size+'%').data('size',size);
}


$(document).ready(function(){
        $('body').prepend(' \
            <div class="font-size-changer"> \
                <a href="#" class="decrease">A&darr;</a> \
                <!--<a href="#" class="reset">A</a>--> \
                <a href="#" class="increase">A&uarr;</a> \
                <a href="#" class="null">null</a> \
            </div> \
        ').find('> .container').data('size',100);
        
        
        $('.font-size-changer .increase').click(
            function() 
            {
                changeFontSize(1);  
            }
        );
        
        $('.font-size-changer .decrease').click(
            function() 
            {
                changeFontSize(-1);  
            }
        );
});

I've stripped the saving to cookie part but that's easy enough to re-apply..

The one trick is to save the initial percentage somewhere (i used data()) because if you try to retrieve it with .css('font-size') it'll give you the calculated size (e.g. '16px'). There might be a way to get the value as a percentage but can't remember how.

When re-applying the cookie saving part, remember to set the initial data() to the value in the cookie instead of 100%, then call changeFontSize(0) to apply it.

Anyway, this code works in IE6.

like image 52
Ben Avatar answered Sep 18 '22 02:09

Ben


You won't be able to get this working in IE 6 or 7 as it is. I would suggest instead creating new style rules, which can include !important declarations and can be achieved in all major browsers using something like the following function. It would require your elements to be identifiable via a selector, such as an ID selector (which would necessitate adding IDs to the elements if not present), and only creates style rules rather than retrieving them, although this is fine for your example.

I've updated your example and it now works in all major browsers, including IE 6 and 7: http://jsfiddle.net/9ZZVP/1/

Style rule creation code:

var addRule;

if (typeof document.styleSheets != "undefined" && document.styleSheets) {
    addRule = function(selector, rule) {
        var styleSheets = document.styleSheets, styleSheet;
        if (styleSheets && styleSheets.length) {
            styleSheet = styleSheets[styleSheets.length - 1];
            if (styleSheet.addRule) {
                styleSheet.addRule(selector, rule)
            } else if (typeof styleSheet.cssText == "string") {
                styleSheet.cssText = selector + " {" + rule + "}";
            } else if (styleSheet.insertRule && styleSheet.cssRules) {
                styleSheet.insertRule(selector + " {" + rule + "}", styleSheet.cssRules.length);
            }
        }
    }
} else {
    addRule = function(selector, rule, el, doc) {
        el.appendChild(doc.createTextNode(selector + " {" + rule + "}"));
    };
}

function createCssRule(selector, rule, doc) {
    doc = doc || document;
    var head = doc.getElementsByTagName("head")[0];
    if (head && addRule) {
        var styleEl = doc.createElement("style");
        styleEl.type = "text/css";
        styleEl.media = "screen";
        head.appendChild(styleEl);
        addRule(selector, rule, styleEl, doc);
        styleEl = null;
    }
}

Example usage:

createCssRule("#foo", "background-color: purple !important;");
like image 25
Tim Down Avatar answered Sep 18 '22 02:09

Tim Down