这个方案可以兼容IE7和IE6吗?

6

有什么方法可以使这个解决方案兼容IE6和IE7吗?

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


摘自这个问题

我认为我已经找到了一个真正的解决方案。我把它做成了一个新的函数:

jQuery.style(name, value, priority);

你可以像使用.css('name')一样,使用.style('name')来获取值,使用.style()获取CSSStyleDeclaration,并且还可以设置值——同时指定优先级为“important”。请参见https://developer.mozilla.org/en/DOM/CSSStyleDeclaration

演示

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'));

以下是输出结果:

null
red
blue
important

函数

// 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;
    }
}

请参考https://developer.mozilla.org/en/DOM/CSSStyleDeclaration了解如何读取和设置CSS值的示例。我的问题在于,我已经在我的CSS中将宽度设置为!important,以避免与其他主题CSS冲突,但是我在jQuery中对宽度进行的任何更改都不会受到影响,因为它们将被添加到style属性中。

兼容性

使用setProperty函数进行优先级设置,http://help.dottoro.com/ljdpsdnb.php说支持IE 9+和所有其他浏览器。我已经尝试过IE 8,但失败了,这就是为什么我在我的函数中构建了对其的支持(请参见上文)。它将适用于使用setProperty的所有其他浏览器,但需要我的自定义代码才能在< IE 9中运行。

26
请停止支持IE6! - Kyle
9
别再抱怨IE6了,我们都知道它很糟糕,不要把这个问题变成又一个IE6争论。柯克已经说过这是必须的,就此打住。 - Ben
10
有些人/公司由于各种原因仍在使用IE 6浏览器,开发者的责任是为用户服务,而不是用户为他们服务。 - Tim Down
9
当我的老板说“我们必须支持IE6”时,我会说“不,因为@KyleSevenoaks要求我不这样做”。 - Dan Blows
3
嗯,您没有我们的分析数据...并非所有使用情况都提供相同的数据。 - Kirk Strobeck
显示剩余9条评论
3个回答

9

看起来过于复杂了… 我会在容器内使用基于em的字号,并使用百分比调整容器的字号。这样,容器内的所有标签都会自动调整大小。

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);  
            }
        );
});

我已经删除了保存到cookie的部分,但是重新应用也很容易。唯一的诀窍是将初始百分比保存在某个地方(我使用了data()),因为如果您尝试使用.css('font-size')检索它,它会给您计算出来的大小(例如“16px”)。可能有一种方法可以获得百分比值,但我记不清了。
当重新应用cookie保存部分时,请记住将初始data()设置为cookie中的值,而不是100%,然后调用changeFontSize(0)来应用它。
无论如何,这段代码在IE6中都有效。

我提供了一种替代方法,但我认为这是最好的方式,也是我过去实现类似功能的方式。+1。 - Tim Down
这段额外代码的主要原因是 !important 在 IE6 中会破坏某些东西,这段代码是否适用于 !important - Kirk Strobeck
为什么需要使用!important?不知道你的代码长什么样,很难说清楚。 - Ben
说实话,我在编程中使用 !important 的时候,大多数情况下其实可以不用(只是因为这样更容易)。但是这个情况好像并不需要使用它。 - Camilo Martin
这是一个很好的解决方案,但不幸的是,我必须覆盖一堆已经存在的CSS,所以这对我的用例不起作用:\ - Kirk Strobeck
@KirkStrobeck 很遗憾。不能重写CSS吗?也许你需要Tim Down的版本。 - Ben

4
您无法在IE 6或7中使用它。我建议创建新的样式规则,其中可以包括!important声明,并且可以通过以下函数在所有主要浏览器中实现。它需要通过选择器(例如ID选择器)识别您的元素,如果不存在,则需要添加ID到元素,并且仅创建样式规则而不是检索它们,尽管这对于您的示例来说是可以的。
我已更新您的示例,现在可以在所有主要浏览器中使用,包括IE 6和7:http://jsfiddle.net/9ZZVP/1/ 样式规则创建代码:
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;
    }
}

示例用法:

createCssRule("#foo", "background-color: purple !important;");

有一个很有用的库可以处理这种事情:https://dev59.com/c3VC5IYBdhLWcg3wYQEp#5077782 - thirtydot
@thirtydot:从快速浏览来看,这看起来不错,而且与我自己为项目编写的东西非常相似。 - Tim Down

-1

前往http://www.javascriptlint.com/online_lint.php

将您的Javascript粘贴到那里。

您会看到有相当多的警告。首先,修复所有警告。一旦JavaScript Lint不再生成警告,请在IE中进行测试。这至少可以让您开始找到解决方案的路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接