Document.styleSheets 只读属性,
返回一个由 StyleSheet 对象组成的 StyleSheetList,
每个 StyleSheet 对象都是一个文档中链接或嵌入的样式表。
let styleSheetList = document.styleSheets;
它是一个 StyleSheet 对象的有序集合。
styleSheetList.item(index) 或 styleSheetList[index] 
根据它的索引(索引基于0)返回一个单独的样式表对象。

CSSRule 对象

cssRule接口表示一个CSS规则。规则存在若干种类型。

CSSStyleRule  //  CSSRule.STYLE_RULE ==1
 // CSSRule.CHARSET_RULE ==2
CSSImportRule //CSSRule.IMPORT_RULE ==3
CSSMediaRule  // @media 规则  CSSRule.MEDIA_RULE==4
CSSFontFaceRule //CSSRule.FONT_FACE_RULE ==5
CSSPageRule //CSSRule.PAGE_RULE==6
CSSKeyframesRule // CSSRule.KEYFRAMES_RULE ==7  对应于@keyframes at-rule的完整的关键帧
CSSKeyframeRule // CSSRule.KEYFRAME_RULE==8 对应于@keyframes at-rule的单个关键帧
CSSNamespaceRule //CSSRule.NAMESPACE_RULE==10
CSSCounterStyleRule
CSSDocumentRule
CSSSupportsRule //CSSRule.SUPPORTS_RULE ==12
CSSFontFeatureValuesRule
CSSViewportRule

其中 CSSKeyframesRule 规则 定义了 @keyframes 动画的完整的关键帧;

查找动画关键帧样式位置

通过遍历 找到 document.styleSheets下的cssRules获取属性表对象

document.styleSheets[0].cssRules //返回 CSSRuleList

在这里插入图片描述
其中type代表cssRule规则类型的值,而type 等于7 代表完整的动画帧的规则CSSKeyframesRule
所以我们要修改动画样式 需要先找到 type==7的列表;

修改动画关键帧样式

//样式表中插入一条规则。
appendRule(rule, index) //Chrome  IE9及以上 FireFox
insertRule(rule, index) // 暂未找到那个版本支持
addRule(selector, rules, [index])// IE 特有(以下,以上被删除了)
//样式表中插入删除条规则。
removeRule([index]) IE // IE 特有( ie9 以下,以上被删除了)
deleteRule(index) //Chrome  IE9及以上 FireFox

注意:修改时一定要找到所有的样式表修改;如下图存在两个同名的样式表,
在这里插入图片描述
两个同名的样式表都要修改,否则样式不生效;
如下图修改是只修改了最后一列样式表
f12查看样式修改成功!
但是会出现复用当前组件时,复用两次以上的动画不生效!

在这里插入图片描述
注意:由于vue需要打包,vue会把css生成的样式打包成link引入的方式,当使用link引入方式时无法通过cssRules进行查找

在这里插入图片描述
所以这里我们需要使用appendRule或者insertRule插入一条规则;
在这里插入图片描述

vue 代码参考 (细节请自行修改)

    animationName: "",
      sheetsIndex: "",
      keyframeIndex: "",
      // 动画总耗时 (毫秒)
      animationDuration: "350",
      // 动画关键帧数组
      animationArr: [],
methods
    // 改变窗口动画
    changeAnimation() {
      // 动画加载一定程度后再加载视图,否则性能差,出现掉帧情况
      this.viewShow = false;
      setTimeout(() => {
        this.viewShow = true;
      }, (this.animationDuration / 100) * 75);
      // 设置动画
      this.animationArr = [
        `0% {
          left: ${String(window.$clientX) ? window.$clientX + "px" : "0%"};
          top: ${String(window.$clientY) ? window.$clientY + "px" : "100%"};
          width: 0px;
          ;
          opacity: 0.5;
        `100% {
           left: ${this.left};
           top: ${this.top};
           width: ${this.width};
           height: ${this.height};
           opacity: 1;
      let selector = ".no_router_popup_animation";
      this.changeKeyframes(selector, "noRouterPopup", this.animationArr);
    // 寻找 css不是link引入的
    findNoLinkSheet() {
      var styleSheets = document.styleSheets;
      console.log("进入了findNoLinkSheet",styleSheets);
      let ssLength = styleSheets.length;
      for (var i = 0; i < ssLength; i++) {
        try {
          // 谷歌、火狐浏览器空时返回错误; uc浏览器 空为null;
          styleSheets[i].cssRules || styleSheets[i].rules;
          if (!styleSheets[i].cssRules && !styleSheets[i].rules) {
            continue;
        } catch {
          continue;
        this.sheetsIndex = i;
        console.log("this.sheetsIndex", this.sheetsIndex);
        break;
    // 添加新动画
    addKeyframes(selector, animName, AnimationArr) {
      var styleSheets = document.styleSheets;
      let animationString = "";
      AnimationArr.forEach((item) => {
        // keyframesArr[k].insertRule(item);
        animationString += item;
      });
      let Keyframes = `@keyframes ${animName}{${animationString}}`;
      console.log("Keyframes");
      if (styleSheets[this.sheetsIndex].appendRule) {
        styleSheets[this.sheetsIndex].insertRule =
          styleSheets[this.sheetsIndex].appendRule;
      styleSheets[this.sheetsIndex].insertRule(Keyframes);
      console.log(
        "styleSheets[this.sheetsIndex]",
        styleSheets[this.sheetsIndex]
      this.animationName = animName;
      // 动画总耗时设置
      let selectorDom = document.querySelectorAll(selector);
      selectorDom[selectorDom.length - 1].style.animationDuration =
        this.animationDuration + "ms";
      // 重新指定动画名字使之生效
      selectorDom[
        selectorDom.length - 1
      ].style.animationName = this.animationName;
    // 查找动画keyframe
    findKeyframesRule(animName) {
      var styleSheets = document.styleSheets;
      // console.log("styleSheets", styleSheets);
      let ssLength = styleSheets.length;
      for (var i = 0; i < ssLength; i++) {
        try {
          // 谷歌、火狐浏览器空时返回错误; uc浏览器 空为null;
          styleSheets[i].cssRules || styleSheets[i].rules;
          if (!styleSheets[i].cssRules && !styleSheets[i].rules) {
            continue;
        } catch {
          continue;
        var oRules = styleSheets[i].cssRules
          ? styleSheets[i].cssRules
          : styleSheets[i].rules;
        let oRulesLength = oRules.length;
        for (var x = 0; x < oRulesLength; x++) {
          // 跳过name为 undefined
          if (!oRules[x].name) {
            continue;
          let rule = oRules[x];
          if (
            String(rule.name).indexOf(animName) != -1 &&
            (rule.type == CSSRule.KEYFRAMES_RULE ||
              rule.type == CSSRule.WEBKIT_KEYFRAMES_RULE)
            // console.log("rule.name", rule.name);
            // console.log("oRules", oRules);
            // 递归查找keyframes
            return this.findKeyframesCallBack(oRules, animName, x);
     * @name: 递归查找keyframes
     * @test: test font
     * @msg:
     * @param {*} oRules document.styleSheets[i].cssRules||document.styleSheets[i].rules
     * @param {*} animName 修改的动画名称
     * @param {*} index  cssRules或rules数组下标
     * @param {*} ruleArr  保存具有与animName的keyframes数组
     * @return {*} ruleArr
    findKeyframesCallBack(oRules, animName, index, ruleArr = []) {
      let ruleItem = oRules[index];
      if (
        String(ruleItem.name).indexOf(animName) != -1 &&
        (ruleItem.type == CSSRule.KEYFRAMES_RULE ||
          ruleItem.type == CSSRule.WEBKIT_KEYFRAMES_RULE)
        this.animationName = ruleItem.name;
        this.keyframeIndex = index;
        ruleArr.push(ruleItem);
        return this.findKeyframesCallBack(oRules, animName, index + 1, ruleArr);
      } else {
        return ruleArr;
    // 改变已有动画
    changeKeyframes(selector, animName, AnimationArr) {
      var keyframesArr = [];
      try {
        keyframesArr = this.findKeyframesRule(animName);
      } catch {
        return;
      // 如果找不到则添加一个动画
      if (!keyframesArr) {
        console.log("!keyframesArr", !keyframesArr);
        this.findNoLinkSheet();
        this.addKeyframes(selector, animName, AnimationArr);
        return;
      const keyframesArrLength = keyframesArr.length;
      // 遍历修改所有的keyframes 不全部修改会出现动画不生效 或者只生效一次
      for (var k = 0; k < keyframesArrLength; k++) {
        // 兼容ie (暂未验证)
        if (!keyframesArr[k].deleteRule) {
          keyframesArr[k].deleteRule = keyframesArr[k].removeRule;
        // 删除已经存在的开始和结束帧
        keyframesArr[k].deleteRule("0%");
        keyframesArr[k].deleteRule("100%");
        // 兼容谷歌与火狐
        if (keyframesArr[k].appendRule) {
          keyframesArr[k].insertRule = keyframesArr[k].appendRule;
        // // 兼容ie (暂未验证)
        // else if (keyframesArr[k].addRule) {
        //   keyframesArr[k].insertRule = function (rule, index = 0) {
        //     let selector = rule.split("{")[0];
        //     let selectorLength = selector.length;
        //     let style = rule.slice(selectorLength);
        //     return keyframesArr[k].addRule(selector, style, index);
        //   };
        // 添加动画
        AnimationArr.forEach((item) => {
          keyframesArr[k].insertRule(item);
        });
      var styleSheets = document.styleSheets;
      // this.animationName = animName;
      // 动画总耗时设置
      let selectorDom = document.querySelectorAll(selector);
      selectorDom[selectorDom.length - 1].style.animationDuration =
        this.animationDuration + "ms";
      // 重新指定动画名字使之生效
      selectorDom[
        selectorDom.length - 1
      ].style.animationName = this.animationName;
                                    css3中@keyframes死的,如果需要动态修改则需要js,其实操作起来也很简单,只是一些用到了一些不常用的api1、获取页面样式表并查找keyframes所在的styleSheet2、删除原来的styleSheet的动画帧3、添加js动态修改过后的动画帧实现三个步骤的代码1、关于获取styleSheet这给出了一个通用方法functionfindKeyframesRule(rule)...
                                    在css3中,我们可以通过@keyframes创建关键帧动画效果。我们需要将@keyframes绑定到选择器中,否则不会有效果出现。同时,我们还需定义动画时长和动画名称
CSS Code复制内容到剪贴板
    @keyframes animationname {keyframes-selector {css-styles;}}   
                                    vue动画特效-渐变动画和@keyframes过渡原理实现@keyframes动画使用animated.css同时使用过渡和@keyframes动画
今天学习vue的动画的时候,感觉机制有点繁琐,总结一下。
Vue使用动画需要用到一个封装好的组件<transition>,Vue官方文档是这么介绍的:
Vue 提供了 <transition>的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
条件渲染 (使用 v-if)
条件展示 (使用 v-show)
                                    CSS3中增加了@keyframes规则用于创建动画,创建动画的原理是,将一套 CSS 样式逐渐变化为另一套样式。也就是说通过改变CSS样式而达到动画的效果,所以,要动态去改变动画,只有修改样式。
你可以打印一下document.styleSheets,console.log(document.styleSheets),会发现document.styleSheets是一个对象数组。
拿到样式表后就可以操作样式啦~
insertRule方法用来给当前样式表插入新的样式规则。举个栗子:
var style = 
document.styleSheets[0].insertRule(`
          @-webkit-keyframes ani${index}{ from{ top:150px;left:150px } to { top:${item.y}px;left:${item.x}px }}
          @-moz-keyframes ani${index}{ from{ top:150px;left:150px } to..
                                    路易斯维尔代码JavaScript项目
Rick Sweeney为Code Louisville创作的Golden Anniversary Hits网站项目
提示输入密码:接受以下内容:
 该项目利用了跟踪技术。
 标题与导航选项垂直对齐。 但是通过@media查询,当视口增加到769px时,切换到标题下方的导航选项的水平对齐方式,并在视口大小增加到1025px或更高时将导航选项移动到与标题名称相同的行。
 当指针悬停在Banner上时,Banner使用CSS @keyframes和:hover伪类为徽标设置动画。
 具有每月点击量“日历”的主要内容部分:
 * demonstrates use of flexbox to expand vertical mobile alignment into rows as increased viewport space allows.
其他Jav
三. 技术分析
其中运动ball是反复重复一个动作运动,不能使用transition渐变方式,因为transition只能执行一次渐变效果,重复运动最佳的方式就是采用animation。
四. 问题
@keyframescss中是死的,此时需要结束js操作@keyframes,那js是如何操作@keyframes呢,下面是我花了一天查询资料加上自己的摸索,解决了兼容IE的解决方案。
五. js