Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用纯js/跨浏览器解决方案检查元素中是否存在伪类(:after,:before,…)_Javascript_Html_Css - Fatal编程技术网

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

Javascript 使用纯js/跨浏览器解决方案检查元素中是否存在伪类(:after,:before,…),javascript,html,css,Javascript,Html,Css,首先感谢所有愿意帮助我的人。 我的问题很大,所以基本上我想要一个方法,可以识别给定HTML元素上所有当前的伪名称。然后检查通过这些伪类添加或修改了哪些CSS样式,并将它们附加到新的HTML元素中。所有这些都应该尽可能在纯JS和跨浏览器上实现 这个问题的一部分是我自己解决的,但我没有足够的javascript知识或想象力来完成这项工作,并且找不到任何类似解决方案的好例子,至少部分是这样 constructor() { this._options = {

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

这个问题的一部分是我自己解决的,但我没有足够的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;
        }
    }
constructor(){
此选项。\u选项={
伪元素:['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(*)')“,”仅限类型“,”唯一子“,”可选“,”超出范围“,”只读“,”读写“,”必需“,”根“,”目标“,”有效“,”已访问“,”之后“,”之前“]
}
}
_handleElmCss(多梅尔姆、纽厄姆){
//我想不出比不使用pseudo获得所有CSS,然后使用pseudo检查相同样式的对象差异更好的解决方案。我需要尽可能快的方法,因为我正在处理数十万个元素。
var computedStyle=getComputedStyle(domElm);
对于(var i=0,len=this.\u options.pseudoElements.length;i!array2.includes(val));
}
_containsPseudo(节点、选择器){
//此方法仅适用于:empty、:hover等。:before和:after不起作用。
var nativeMatches=(node.matches | | node.msMatchesSelector);
试一试{
return(nativeMatches.call(节点,选择器));
}捕获(错误){
返回false;
}
}
此代码是从我的库中复制的,可能包含一些缺少的部分或类型错误

最初,通过这个帖子标题,我需要检查任何给定元素是否包含任何伪类的帮助,但是如果有人知道我上面提到的其他问题的解决方案,请随意评论。多谢各位

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

  • 检查当前元素是否包含任何伪类
  • 获取当前伪类的顺序(这样CSS就不会被错误地覆盖)
  • foreach当前的伪类,并获取从任何CSS源添加的修改的当前样式
  • 向新元素添加新的组合样式(仅在伪元素中更改的样式)
  • 您可以使用with second param
    pseudoElt
    来获取它。 检查此示例:

    var el=document.querySelector('elt'),
    pseudo=window.getComputedStyle(el':before');
    警报(pseudo.getPropertyValue(“内容”)
    英语教学:之前{
    内容:“此元素具有伪类”
    }

    嘿,谢谢你的回答,如果我错了,请更正,但我可以看到你只得到你知道存在的伪元素参数(“内容”)。正如我用getComputedStyle测试的一样,我可以看到,如果您给它现有的伪名称与否,它会返回许多参数,因此简言之,这并不确定伪名称是否存在,它只会返回已经知道存在的非常特定的伪元素。我在上面的代码中使用了类似的技术,我过滤了两个数组之间的差异(带pseudo和不带pseudo)。但是这个解决方案不是一个好的解决方案,而且需要内存。是的,你说得对。getComputedStyle不会占用大量内存。请分析我的代码,特别是_getComputedDifference方法,因为您可以看到它在每次找到伪元素时都会通过循环并检查两个大数组(对于:after,:before不能正常工作)。我说的是,这部分内存不足。此外,当您检查数百个或数百万个元素或至少数万个+1以提供工作解决方案时,性能开始感觉良好,但此解决方案在我的情况下不起作用,因为我正在使用许多元素。在典型的小规模站点上,脚本执行耗时90秒(它会对所有站点元素进行爬网)。最坏情况下,这应该需要大约1秒,而不是更长时间。:)谢谢1 您似乎混淆了伪类和伪元素。标题引用了伪元素,但代码中包含这两种类型的字符串。当这两个术语是两个不同的概念时,可以互换使用。