首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检查使用纯js /跨浏览器解决方案的元素中是否存在伪类(:after,:pure,.)

检查使用纯js /跨浏览器解决方案的元素中是否存在伪类(:after,:pure,.)
EN

Stack Overflow用户
提问于 2018-12-20 10:45:16
回答 1查看 5.5K关注 0票数 4

首先,感谢所有愿意帮助我的人。我的问题很大,所以基本上我想要一个方法,它可以识别我给定的HTML元素上所有当前的伪名称。然后检查哪些CSS样式是通过这些伪类添加或修改的,并将它们附加到新的HTML元素中。所有这些都应该尽可能多地放在纯JS和跨浏览器上。

这个问题的一部分是我自己解决的,但是我没有足够的javascript知识或想象力来完成这个任务,也找不到任何类似解决方案的好例子,至少部分是这样的。

代码语言:javascript
运行
复制
    constructor() {
        this._options = {
            pseudoElements: ['active', 'checked', 'disabled', 'empty', 'enabled', 'first-child', 'first-of-type', 'focus', 'hover', 'in-range', 'invalid', 'last-child', 'last-of-type', 'link', 'not(*)', 'nth-child(*)', 'nth-last-child(*)', 'only-of-type', 'only-child', 'optional', 'out-of-range', 'read-only', 'read-write', 'required', 'root', 'target', 'valid', 'visited', 'after', 'before']
        }
    }

    _handleElmCss(domElm, newElm) {
        // could not think any better solution then getting all CSS without pseudo then checking with pseudo the same Style object difference. I need as fast as possible way, because i am working with hundred of thousands elements.
        var computedStyle = getComputedStyle(domElm);
              for (var i = 0, len = this._options.pseudoElements.length; i < len; i++) {
                    var pseu_name = this._options.pseudoElements[i];
                    if (this._containsPseudo(domElm, ':' + pseu_name)) {
                        var differentParameters = this._getComputedDifference(pseu_name, computedStyle, domElm);
                        console.log(differentParameters);
                    }
                };
      }

        _getComputedDifference(pseu_name, computed2, domElm) {
            var computed1 = getComputedStyle(domElm, ':' + pseu_name);
            var array1 = [], array2 = [];
            // I belive there is a faster way to convert getComputedStyle to key-value array.
            for (var i = 0; i < computed1.length; i++) {
                var key = computed1[i];
                var value = computed1.getPropertyValue(key);
                if (key != "" && key != null) {
                    array1[i] = value; // i believe this part is incorrect, i mean array-key should be the "key" variable, but i get JS errors.
                }
            }
            for (var i = 0; i < computed2.length; i++) {
                var key = computed2[i];
                var value = computed2.getPropertyValue(key);
                if (key != "" && key != null) {
                    array2[i] = value; // i believe this part is incorrect, i mean array-key should be the "key" variable, but i get JS errors.
                }
            }
            return array1.filter(val => !array2.includes(val));
        }

    _containsPseudo(node, selector) {
        // this method works only with :empty, :hover and so on. :before and :after does not work.
        var nativeMatches = (node.matches || node.msMatchesSelector);
        try {
            return(nativeMatches.call(node, selector));
        } catch (error) {
            return false;
        }
    }

此代码是从我的库中复制的,可能包含一些丢失的部分或类型错误。

由这个帖子标题,我需要帮助检查是否任何给定的元素包含任何伪类,但如果有人知道解决我以上提到的其他问题,请自由评论。谢谢。

这个剧本应该用我的想象来完成的部分(我可能错了):

  1. 检查当前元素是否包含任何伪类。
  2. 获取当前伪类的顺序(因此CSS不应该被错误地覆盖)。
  3. 预先处理当前伪类,并获取修改后的当前样式,并从任何CSS源中添加。
  4. 向新元素添加新组合样式(仅在伪元素中更改)。
EN

回答 1

Stack Overflow用户

发布于 2018-12-20 12:02:18

您可以使用getComputedStyle() (W3C参考)和第二个param pseudoElt来获得它。请检查此示例:

代码语言:javascript
运行
复制
var el = document.querySelector('#elt'),
pseudo = window.getComputedStyle(el, ':before');
alert(pseudo.getPropertyValue("content"));
代码语言:javascript
运行
复制
#elt:before {
	content: "This element has pseudo class"
}
代码语言:javascript
运行
复制
<div id="elt"></div>

编辑

您可能希望看到此操作:(函数从另一个因此答案)

代码语言:javascript
运行
复制
<style>
#elt {
    color:red;
}
#elt2 {
    color:blue;
}
#elt:before {
}
#elt2:first-child {
}
#elt2:after {
}
</style>

<div id="elt">#ELT1</div>
<div id="elt2">#ELT2</div>
<div id="container"></div>
<hr>
<script type="text/javascript">


function ruleSelector(selector) {
    function uni(selector) {
        return selector.replace(/::/g, ':')
    }
    return Array.prototype.filter.call(Array.prototype.concat.apply([], Array.prototype.map.call(document.styleSheets, function(x) {
        return Array.prototype.slice.call(x.cssRules);
    })), function(x) {
        return uni(x.selectorText) === uni(selector);
    });
}

lists = {pseudos: ['active', 'checked', 'disabled', 'empty', 'enabled', 'first-child', 'first-of-type', 'focus', 'hover', 'in-range', 'invalid', 'last-child', 'last-of-type', 'link', 'not(*)', 'nth-child(*)', 'nth-last-child(*)', 'only-of-type', 'only-child', 'optional', 'out-of-range', 'read-only', 'read-write', 'required', 'root', 'target', 'valid', 'visited', 'after', 'before']};

document.write("<h1>#elt</h1>");
for (var i = 0, len = lists.pseudos.length; i < len; i++) {
    var pseudo = lists.pseudos[i];
    if(ruleSelector("#elt:"+pseudo).length)
        document.write("<strong>#elt has :"+pseudo+"</strong><br>");
    else
        document.write("<small>#elt hasn't :"+pseudo+"</small><br>");
}

document.write("<h1>#elt2</h1>");
for (var i = 0, len = lists.pseudos.length; i < len; i++) {
    var pseudo = lists.pseudos[i];
    if(ruleSelector("#elt2:"+pseudo).length)
        document.write("<strong>#elt2 has :"+pseudo+"</strong><br>");
    else
        document.write("<small>#elt2 hasn't :"+pseudo+"</small><br>");
}

</script>

我刚刚修改了代码,你也可以这么做。好好享受吧。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53867100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档