簡體   English   中英

如何檢測覆蓋的css屬性?

[英]How can I detect overwritten css properties?

我可以使用document.stylesheets獲取元素的所有css屬性,但其中一些不活動,因為這些屬性被覆蓋。 在firebug中(chrome開發者工具也有這個功能),如果有一個覆蓋的css屬性,你會看到類似的東西: 在此輸入圖像描述

我能想到的唯一方法是比較元素的活動css屬性(在jQuery $(element).css(property) )和document.stylesheets定義的css屬性,但這不是一種可行的方法。 有什么建議嗎?

在webkit中,您可以使用getMatchedCSSRules來實現您想要的功能。 它按照瀏覽器應用的繼承順序返回CSS規則集,它是webkit檢查器不久前使用的。 對於像Firefox這樣的基於Gecko的瀏覽器雖然我沒有對它進行過測試,但似乎可以在這里使用polyfill。

一個基本的工作解決方案

以下代碼也可作為小提琴使用

因為getMatchedCSSRules 僅適用於內聯樣式表 ,所以首先必須內聯鏈接的樣式表:

function inlineStyles() {
    var stylesheets = document.getElementsByTagName('link'),
        head = document.getElementsByTagName('head')[0];

    for (var i = 0; i < stylesheets.length; i++) {
        if (stylesheets[i].getAttribute('rel') == 'stylesheet') {
            (function (stylesheet) {
                var xmlhttp = new XMLHttpRequest();
                xmlhttp.open("GET", stylesheet.getAttribute('href'), true);
                xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        var inlineStyle = document.createElement('style');
                        inlineStyle.setAttribute('type', 'text/css');
                        inlineStyle.innerText = xmlhttp.responseText;
                        head.replaceChild(inlineStyle, stylesheet);
                    }
                };
                xmlhttp.send();
            })(stylesheets[i]);
        } else {
            continue;
        }
    };
}

然后,大塊:這是第一槍,隨意改進。 它可以處理inherit規則和最多一個!important定義,但就是這樣。 對於非常復雜的設置,這將不得不改進:

function getStyle(s, id) {
    var element = typeof id === 'string' ? document.getElementById(id) : id,
        css = window.getMatchedCSSRules(element),
        style = window.getComputedStyle(element),
        value = style[s],
        styles = [],
        rules = [],
        inherited, currentRule;

    // if there's a computed style, start calculation
    if (value) {

        // add matched rules if there are any
        if (css) {
            for (var i = 0; i < css.length; i++) {
                styles.push(css[i]);
            }
        }

        // add the element style attribute as a matched rule
        styles.push({
            style: element.style,
            cssText: 'element.style {' + element.getAttribute('style') + ' }'
        });

        for (var i = styles.length - 1; i >= 0; i--) {
            var def = styles[i],
                rule = {
                    index: rules.length,
                    style: s,
                    value: styles[i].style[s],
                    cssText: def.cssText
                };

            if (rule.value == 'inherit' && !currentRule) {
                if (inherited = getInherited(element, s, value)) {
                    rule.inheritedFrom = inherited;
                    currentRule = rule;
                    inherited = undefined;
                } else {
                    rules.push(rule);
                }
            } else if (rule.value == 'inherit' && currentRule && isImportant(s, value, def.cssText)) {
                if (inherited = getInherited(element, s, def)) {
                    rule.inheritedFrom = inherited;
                    rules.splice(currentRule.index, 0, currentRule);
                    currentRule = rule;
                    inherited = undefined;
                } else {
                    rules.push(rule);
                }
            } else if (rule.value == value && !currentRule) {
                currentRule = rule;
            } else if (rule.value == value && currentRule && isImportant(s, value, def.cssText)) {
                rules.splice(currentRule.index, 0, currentRule);
                currentRule = rule;
            } else if (rule.value.length) {
                rules.push(rule)
            }
        }

        return {
            current: currentRule,
            overwritten: rules
        };

    } else {
        return false;
    }
}

如果正在進行繼承,我們走向DOM節點以找到使用此幫助函數定義CSS規則的元素並獲取其樣式:

function getInherited(element, s, value) {
    while (element.parentNode && window.getComputedStyle(element.parentNode)[s] == value) {
        element = element.parentNode;
    }

    if (element) {
        return getStyle(s, element).current;
    } else {
        return null;
    }
}

我們確定是否使用此輔助函數將CSS規則標記為重要:

function isImportant(s, style, text) {
    return new RegExp(s.replace(/([A-Z])/g, '-$1').toLowerCase() + ':\\s+' + style + '\\s+!important').test(text)
}

看看小提琴看它是否正常工作

這段代碼可能對您有用,它過去幫助過我,將它應用到您的一個CSS文件中,並且您將能夠通過查找元素CSS的特定位置來查看哪些對象被其他類/ ID規則覆蓋聲明是,並通過跟蹤他們的父母。 我的猜測是你有繼承問題。

* { outline: 2px dotted red }
* * { outline: 2px dotted green }
* * * { outline: 2px dotted orange }
* * * * { outline: 2px dotted blue }
* * * * * { outline: 1px solid red }
* * * * * * { outline: 1px solid green }
* * * * * * * { outline: 1px solid orange }
* * * * * * * * { outline: 1px solid blue }

或者你可以添加一個:hover屬性,它會讓它更容易導航,但代碼片段的基本原理是向你展示元素的嵌套,並可以幫助你確定CSS中的問題所在是

您必須解析鏈接到頁面的CSS文件才能確定正在使用的樣式。 您還必須確定可以使用哪些屬性來定位CSS中的元素。 以下是您必須遵循的流程:

元素可以是以下目標:標記,ID,類,偽類和繼承

然后你會有一個給定的元素,例如:

<a href="#" id="link" class="button">Woop</a>

默認情況下,該元素有幾個與之關聯的選擇器。 所有元素都可以繼承父CSS,因此您必須創建父元素的層次結構。 以后的樣式將優先。 然后,您必須考慮標記a和任何也共享此選擇器的父級,例如body a 同樣,您必須創建繼承屬性的層次結構。 您將為類,屬性和偽類重復此過程。 編譯元素的樹列表后,可以解析CSS文檔以獲取相應的樣式。

這絕對是一項艱巨的任務,重新發明輪子是沒有意義的。 我建議看看已經完成此項工作的開源項目。 WebKit是一個已經構建了這個系統的開源項目。 考慮使用他們的實現作為起點並從那里進行更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM