js修改伪元素的属性、styleSheets获取样式表,Failed to read the 'cssRules' property from 'CSSStyleSheet' Cannot acces

登录验证中的判断逻辑

1.提示输入用户,输入8 - 16位密码2.检验输入用户名和密码是否正确

  • 用户名不允许空格,任何字符数字都行,不允许为空

  • 密码8-16位,不允许空格 ,小于8位给出提示

  • 密码必须包含字母,数字,符号两种

  • 手机号码,11位,只允许数字

效果类似于

js修改伪元素的属性、styleSheets获取样式表,Failed to read the 'cssRules' property from 'CSSStyleSheet' Cannot acces_第1张图片

js修改伪元素的属性、styleSheets获取样式表,Failed to read the 'cssRules' property from 'CSSStyleSheet' Cannot acces_第2张图片

js修改伪元素的属性、styleSheets获取样式表,Failed to read the 'cssRules' property from 'CSSStyleSheet' Cannot acces_第3张图片

想要达成的目的

实现提示时,用的span的伪元素加载背景图片,实现icon变化的效果。通过动态控制伪元素的属性和杨思,达到效果。

 


    
            ​                                                  
                       
       

问题:

伪元素本身不是DOM元素,它不存在于文档中。所以Js无法获取它。伪元素有六个,分别是::after、::before、::first-line、::first-letter、::selection、::backdrop。

解决方案:

想得到伪元素,用js控制

方案一:控制伪元素的content动态显示,动态改变。

通过css的函数attr()和Html5的自定义data-*属性。

attr()方法,就是返回当前元素获得的属性值,比如当前元素

attr(herf)获得的就是http://www.test.com

而herf是自带的属性,我们可以通过Html5来自定义一个属性,选定这个属性,去修改content的值。

data-*就是去自定义一个属性

但data-*创建属性是附加在伪元素的父类身上,也就是这种方法不是去操作伪元素,而是去操作伪元素的父类,达到目的。

/* 自定义属性data-after,操作data-after里面的属性值,来修改content的值 */

#register-hint-length ::before {
    content: attr(data-after);
    }
 var PswInputHint = document.getElementById("register-hint-psw-length");
 PswInputHint.setAttribute("data-after", "长度为8-16个字符");

看代码就知道,并非选中了伪元素,我们要实现的功能是小于8个字符的密码框,会弹出提示长度为8-16个字符,并非将伪元素控制的背景icon变为红色警示icon,字体颜色变为红色。

用div套div的实现会简单很多,但试试js控制伪元素。

工作中就不较真了,做个考量采取最优计划,但学习过程中就探究下为什么不能解决问题,为什么出现这些毛病。

解决方案一中遇到的问题

百度几篇文章,提到如下方法获得伪元素去控制

var myIdElement = document.getElementById("myId");
var beforeStyle = window.getComputedStyle(myIdElement, ":before");
console.log(beforeStyle); // [CSSStyleDeclaration Object]
console.log(beforeStyle.width); // 100px
console.log(beforeStyle.getPropertyValue("width")); // 100px
console.log(beforeStyle.content);

Window.getComputedStyle()

语法

/**
* @param  {获取到的一个元素} element
* @param  {里面的伪元素} [pseudoElt]
* @return {返回的style是一个实时的 CSSStyleDeclaration 对象,当元素的样式更改时,它会自动更新本身。}
*/
let style = window.getComputedStyle(element, [pseudoElt]);

Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有CSS属性的值。 私有的CSS属性值可以通过对象提供的API或通过简单地使用CSS属性名称进行索引来访问。

描述

返回的对象与从元素的 style  属性返回的对象具有相同的类型;然而,两个对象具有不同的目的。从getComputedStyle返回的对象是只读的,可以用于检查元素的样式(包括由一个


    
嵌套树      
父亲节点          
孩子节点          
     
 
 
底部
var customStyle = document.styleSheets[0];//获取的是内联样式表
    customStyle.insertRule('#top::before {color:green}', customStyle.cssRules.length);
    var linkStyle = document.styleSheets[1];//获取的是外联样式表

解决方案二中遇到的问题

首先了解下 document.styleSheets,这是获取样式表,按照浏览器加载的顺序排成一个styleSheets数组,内外联都在里面。插入是没问题的,用customStyle.cssRules.length动态添加。

全部样式表

js修改伪元素的属性、styleSheets获取样式表,Failed to read the 'cssRules' property from 'CSSStyleSheet' Cannot acces_第4张图片

 

styleListp[0]是内联样式表,styleListp[1]是外联样式表

但控制台打印样式表过程中出现,无法获取外联样式表,如下图,抛出了异常。

用trycatch捕捉到异常。

    try {
        var cssrules = styleList[1].cssRules || styleListp[1].rules;
    } catch (e) {
        console.warn("warning" + e);
    }

warningSecurityError: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules(anonymous) @ test-stylesheet.html:60

这个问题好像是64位的Chrome和IE9存在安全性的问题,无法获取外部文件,解决方法是

https://github.com/code-dot-org/code-dot-org/pull/21082

能够获取外联样式表

还有个问题,customStyle.cssRules.length是计算的插入样式表之后的数组长度,这个的逻辑。

她应该计算当前渲染页面后的css规则,从0开始计算,当没有规则的时候,便插入为0,当有三个规则的时候,插入下标为3,但实际上是插在从0计算的前三个后面。

 

总结

  • 在js里控制样式的代码,太多,没有达到样式与逻辑的分离,最好不用

  • 可以直接通过写错误提示的样式,正确提示的样式,默认样式,再改变选定元素的classname,来重新渲染样式。

  • 参考:

    用js控制伪元素的方式

https://blog.csdn.net/xiaoya_syt/article/details/60577553

无法读取cssRules的解释

https://stackoverflow.com/questions/49161159/uncaught-domexception-failed-to-read-the-rules-property-from-cssstylesheet

CSSOM

https://www.w3.org/TR/cssom-1/#the-stylesheet-interface

 

 

你可能感兴趣的:(前端,简单粗暴的解决方式)