我可以通过 Javascript 获取非标准 CSS 属性的值吗?

IT技术 javascript css
2021-03-14 18:39:11

我正在尝试读取自定义(非标准)CSS 属性,在样式表(不是内联样式属性)中设置并获取其值。以这个 CSS 为例:

#someElement {
  foo: 'bar';
}

我已经设法通过 IE7 中的 currentStyle 属性获得了它的值:

var element = document.getElementById('someElement');
var val = element.currentStyle.foo;

但是 currentStyle 是特定于 MS 的。所以我在 Firefox 3 和 Safari 3 中尝试了 getComputedStyle():

var val = getComputedStyle(element,null).foo;

...它返回未定义。有谁知道检索自定义 CSS 属性值的跨浏览器方式?

(您可能已经注意到,这不是有效的 CSS。但只要该值遵循正确的语法,它就应该可以工作。更好的属性名称是“-myNameSpace-foo”或其他名称。)

6个回答

现代浏览器只会丢弃任何无效的 css。但是,您可以使用内容属性,因为它仅用了效果 :after:before等等。你可以存储JSON里面:

#someElement {
    content: '{"foo": "bar"}';
}

然后使用这样的代码来检索它:

var CSSMetaData = function() {

    function trimQuotes( str ) {
         return str.replace( /^['"]/, "" ).replace( /["']$/, "" );   
    }

    function fixFirefoxEscape( str ) {
        return str.replace( /\\"/g, '"' );
    }

    var forEach = [].forEach,
        div = document.createElement("div"),
        matchesSelector = div.webkitMatchesSelector ||
                          div.mozMatchesSelector ||
                          div.msMatchesSelector ||
                          div.oMatchesSelector ||
                          div.matchesSelector,
        data = {};

    forEach.call( document.styleSheets, function( styleSheet ) {
        forEach.call( styleSheet.cssRules, function( rule ) {
            var content = rule.style.getPropertyValue( "content" ),
                obj;

            if( content ) {
                content = trimQuotes(content);
                try {
                   obj = JSON.parse( content );
                }
                catch(e) {
                    try {

                        obj = JSON.parse( fixFirefoxEscape( content ) );
                    }
                    catch(e2) {
                        return ;
                    }

                }
                data[rule.selectorText] = obj;
            }
        });

    });


    return {

        getDataByElement: function( elem ) {
            var storedData;
            for( var selector in data ) {
                if( matchesSelector.call( elem, selector ) ) {
                    storedData = data[selector];
                    if( storedData ) return storedData;

                }
            }

            return null;
        }
    };

}();
var obj = CSSMetaData.getDataByElement( document.getElementById("someElement"));
console.log( obj.foo ); //bar

请注意,这仅适用于现代浏览器。演示:http : //jsfiddle.net/xFjZp/3/

好的,我提交了一份报告:-) 然而,官方测试通过了这两种行为......
2021-04-19 18:39:11
@Bergi 是的,但那是一个错误。参见规范w3.org/TR/CSS21/generate.html#content
2021-04-21 18:39:11
不适用于 Opera,它不仅将 content 属性应用于伪元素 - 而不是实际内容,而是显示 JSON。
2021-04-30 18:39:11

Firefox 不会将它不理解的标签、属性或 CSS 样式从代码转移到 DOM。那是设计使然。Javascript 只能访问 DOM,而不能访问代码。所以不,没有办法从浏览器本身不支持的 javascript 访问属性。

严格来说,这不是真的。Firefox 不会为非标准 HTML 属性创建 DOM 属性,但可以通过getAttribute访问它们
2021-04-16 18:39:11

通过在 IE 中读取样式表信息,您可以获得这些“虚假”属性,但仅限于我知道的 IE 中。

var firstSS = document.styleSheets[0];
var firstSSRule = firstSS.rules[0];
if(typeof(firstSSRule.style.bar) != 'undefined'){
  alert('value of [foo] is: ' + firstSSRule.style.bar);
} else {
  alert('does not have [foo] property');
}

它的代码很丑,但你明白了。

不错的把戏!我上面的示例在 IE 中也可以正常工作,但在其他地方(参见quirksmode.org/dom/w3c_css.html 中的currentStyle )虽然它需要一个与选择器匹配的元素(CSS 方式) 一种方法是通过 Javascript 解析样式表。不过感觉不太实用。
2021-04-28 18:39:11

我也有一些页面在 MSIE 中运行良好,但在样式和样式表中有很多信息。所以我正在考虑解决方法。幸运的是,Firefox 允许的一件事是将内联属性放入 DOM。所以这是一个部分策略:

  1. 将 html 文档中的每个内联样式替换为相应的“nStyle”,例如 <span class="cls1" nStyle="color:red; nref:#myid; foo:bar"> ... </span>

  2. 页面加载后,对每个元素节点执行以下操作:(a) 将 nStyle 属性的值复制到标签的 cssText 中,同时 (b) 将非标准属性转换为更简单的格式,以便,例如, node.getAttribute('nStyle') 成为对象 {"nref":"#myid", "foo":"bar"}。

  3. 编写一个“calculatedStyle”函数,根据可用的内容获取样式或 nStyle。

为样式表编写一个粗略的解析器可能会为他们提供类似的策略,但我有一个问题:如何在没有 Firefox 审查的情况下克服阅读样式表的障碍?

一种方法当然是用 Javascript 编写自己的 CSS 解析器。但我相信这真的太过分了。

绝对是最重要的,但这在绝望的情况下是一个有用的建议:)。
2021-05-07 18:39:11