js获取计算后的css

    function getCss(obj) {
        if (obj.currentStyle) {
        // 兼容ie
            return obj.currentStyle;
        } else {
            return getComputedStyle(obj)
        }
    }
<think> 我们使用JavaScript的`window.getComputedStyle(element)`可以获取元素的计算样式(最终生效的样式值)。 但是,这个计算样式会包含浏览器默认样式(User Agent Stylesheet)的值。如果我们想忽略默认值,只获取显式设置的样式,我们可以尝试以下思路: 1. 首先,获取元素的计算样式。 2. 然后,创建一个同类型的临时元素,但不设置任何内联样式,并将其添加到文档中(需要添加到文档中才能获取计算样式)。 3. 获取这个临时元素的计算样式,这样得到的就是浏览器默认样式。 4. 比较两个计算样式对象,如果某个属性的值在元素的计算样式和默认样式中相同,那么我们可以认为这个属性没有被显式设置(或者设置后被覆盖为默认值),此时我们可以忽略它(或者设置为null等)。 但是注意:有些属性是继承属性,比较时需要小心。另外,由于默认样式可能因浏览器而异,这种方法可能不够健壮。 另一种思路是:我们直接获取元素的`style`属性(内联样式),但这只能获取内联样式,无法获取通过CSS类设置的样式。所以这种方法不全面。 因此,我们可能更关注哪些样式被显式设置(包括通过CSS规则设置的),而不仅仅是内联样式。我们可以通过CSSStyleSheet接口来获取所有样式规则,然后找出应用于元素的规则,但这非常复杂。 实际上,没有直接的方法可以忽略默认值。我们只能通过比较默认值来过滤。下面提供一个函数,它通过创建一个同标签名的临时元素来获取默认样式,然后比较元素的计算样式和默认样式,返回一个只包含非默认值的样式对象。 注意:这个方法有一定的局限性,因为临时元素可能受到父元素继承样式的影响,但我们可以将其附加到一个隔离的容器(比如iframe)中,但这样会更复杂。这里我们简化处理,将临时元素附加到当前文档的body中,但立即移除,以减少影响。 步骤: - 创建临时元素,并添加到body(为了计算样式),然后立即移除。 - 获取临时元素的计算样式作为默认样式。 - 获取目标元素的计算样式。 - 遍历目标元素的计算样式,将每个属性与临时元素的对应属性比较,如果不同则保留。 但是,由于继承属性,临时元素可能从body等祖先继承样式,而目标元素也可能继承,所以比较时可能相同,但实际上都是继承来的,并非默认值。因此,这种方法对于非继承属性比较有效,对于继承属性则可能无法区分。 另一种更准确的方法是使用`getDefaultComputedStyle`,但这是非标准方法,只有Firefox支持(在标准中名为`window.getDefaultComputedStyle`)。 考虑到兼容性,我们可以这样: - 对于非继承属性,使用临时元素获取默认值。 - 对于继承属性,我们可以尝试获取根元素(html)的计算样式作为默认值?但根元素也可能被设置样式。所以没有完美的办法。 因此,我们这里提供的方法主要用于非继承属性。 下面给出一个函数,它忽略继承属性,专注于非继承属性(我们可以通过一个非继承属性列表来过滤)。但注意,非继承属性也可能被继承覆盖?不会,非继承属性不会继承。 我们可以列出非继承属性,然后只比较这些属性。这样,对于非继承属性,我们可以比较得出是否被显式设置。 但是,CSS属性非常多,而且不断更新,我们不可能手动维护一个完整的非继承属性列表。所以我们可以采用另一种策略:对于目标元素的每个计算样式属性,我们检查它是否是非继承属性(通过一个已知的非继承属性列表),如果是,则比较;如果是继承属性,则跳过(因为难以区分)。 这里,我们使用一个已知的非继承属性列表(部分常见属性),或者我们可以使用一个技巧:临时元素的样式就是默认样式,而目标元素如果被显式设置过(包括任何方式),那么它的值就可能和临时元素不同(除非设置的值恰好等于默认值)。但是,如果用户设置的值恰好等于默认值,我们就无法区分。所以这个方法并不完美。 考虑到这些,我们提供一个基础版本: 步骤: 1. 创建临时元素(与目标元素同标签名),设置visibility: hidden(避免影响布局),position: absolute(脱离文档流),然后添加到body,获取计算样式后立即移除。 2. 获取目标元素的计算样式。 3. 遍历目标元素的计算样式,对于每个属性,如果它不是继承属性(或者我们只关心非继承属性),则与临时元素的对应属性比较,如果不同,则记录。 但是,如何判断一个属性是否是继承属性?我们可以有一个列表。这里为了简便,我们使用一个已知的继承属性列表(这样我们就可以跳过这些属性),而非继承属性则比较。但实际上,我们可以跳过所有继承属性,因为继承属性我们很难判断是默认值还是显式设置(因为可能来自祖先元素)。 因此,我们只返回非继承属性中与默认值不同的那些。 下面我们实现这个函数,并提供一个非继承属性列表(部分,可根据需要扩展)和继承属性列表(部分,可根据需要扩展)。注意:由于CSS属性非常多,我们不可能列出全部,所以这个函数可能不完整,但可以处理常见属性。 另外,我们可以利用`CSS.supports()`来检查属性名是否有效,避免无效属性。 代码示例: ```javascript function getNonDefaultStyles(element) { // 创建临时元素 const tempElement = document.createElement(element.tagName); // 设置临时元素的样式,确保不影响布局,且尽快计算样式 tempElement.style.visibility = 'hidden'; tempElement.style.position = 'absolute'; document.body.appendChild(tempElement); const defaultStyles = window.getComputedStyle(tempElement); document.body.removeChild(tempElement); const computedStyles = window.getComputedStyle(element); const nonDefaultStyles = {}; // 已知的继承属性列表(部分) const inheritedProperties = [ 'color', 'font', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'letter-spacing', 'line-height', 'text-align', 'text-indent', 'text-transform', 'visibility', 'white-space', 'word-spacing', 'direction', 'orphans', 'quotes', 'widows', 'caption-side', 'empty-cells', 'list-style', 'list-style-image', 'list-style-position', 'list-style-type', 'cursor', 'speak', 'volume' ]; // 遍历计算样式 for (let i = 0; i < computedStyles.length; i++) { const propName = computedStyles[i]; // 跳过继承属性(因为很难判断是默认值还是显式设置,而且可能继承自父元素) if (inheritedProperties.includes(propName)) { continue; } // 获取值 const computedValue = computedStyles.getPropertyValue(propName); const defaultValue = defaultStyles.getPropertyValue(propName); // 如果计算值不等于默认值,则记录 if (computedValue !== defaultValue) { nonDefaultStyles[propName] = computedValue; } } return nonDefaultStyles; } ``` 注意:这个方法并不完美,因为: - 继承属性被我们跳过了(实际上,有些非继承属性可能不在我们的列表中,而继承属性列表也可能不完整)。 - 临时元素的默认样式可能受到浏览器默认样式表的影响,但不同浏览器可能不同。 - 如果目标元素的默认样式被用户代理样式表(浏览器默认样式)重置,那么临时元素也会有同样的样式,所以比较有效。但如果有父元素设置了一些样式,由于我们跳过了继承属性,所以不会影响非继承属性。 另外,我们只比较了非继承属性,并且只记录那些与默认值不同的属性。 使用示例: const el = document.getElementById('myElement'); const nonDefaultStyles = getNonDefaultStyles(el); console.log(nonDefaultStyles); 这个函数返回一个对象,包含所有非继承属性中与默认值不同的属性及其值。 由于CSS属性众多,这个方法可能无法覆盖所有情况,但可以作为参考。 现在,根据要求,在回答后提出3-5个相关问题。 §§相关问题§§ 1. 如何判断一个CSS属性是继承属性还是非继承属性? 2. 除了使用临时元素比较,还有哪些方法可以获取CSS属性的默认值? 3. 在获取计算样式时,如何处理浏览器兼容性问题(比如不同浏览器的默认样式不同)? 4. 如何获取元素继承的样式属性(即来自父元素的样式)? 5. 有没有现成的JavaScript库可以用来处理计算样式和默认样式的比较? </think> ### CSS 获取计算样式并忽略默认值 在 CSS 中,通过 JavaScript 获取元素的计算样式时,可使用 `window.getComputedStyle()` 方法。**计算样式包含浏览器默认样式**,若需忽略默认值,需手动过滤。以下是实现方法: #### 核心步骤 1. **获取计算样式** `const computedStyle = window.getComputedStyle(element);` 2. **识别并过滤默认值** - 创建同类型临时元素作为默认值参照 - 逐属性比对计算样式与默认值 - 保留非默认值的属性 #### 示例代码 ```javascript function getNonDefaultStyles(element) { const computed = getComputedStyle(element); const temp = document.createElement(element.tagName); document.body.appendChild(temp); const defaults = getComputedStyle(temp); document.body.removeChild(temp); const nonDefault = {}; for (let prop of computed) { if (computed[prop] !== defaults[prop] && computed[prop] !== '') { nonDefault[prop] = computed[prop]; } } return nonDefault; } // 使用示例 const divStyles = getNonDefaultStyles(document.querySelector('div')); console.log(divStyles); // 输出非默认样式属性 ``` #### 关键说明 - **临时元素**:创建未设置样式的同标签元素,其计算样式即浏览器默认值 - **属性比对**:遍历所有计算属性,过滤值与默认值相同的项 - **注意事项**: - 需将临时元素加入 DOM (`appendChild`) 才能获取计算样式 - 移除临时元素避免内存泄漏 - 部分继承属性(如 `font-size`)需特殊处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值