美文网首页
transition 相关记录(如何让子元素不受父元素影响)

transition 相关记录(如何让子元素不受父元素影响)

作者: 吃柠檬的刺猬 | 来源:发表于2017-03-13 10:38 被阅读0次

    当前情况:在某个文件统一对所有的页面 View 组件设置了 CSS3 动画,包括 transform 和 opacity,但是其中两个页面有 Navbar 组件(View 组件的子元素)希望是完全不受动画影响。
    限制条件:不希望将 Navbar 单独拿出来作为 View 组件的兄弟。

    由于通过使用的是 Reactcsstransitiongroup 添加的动画。所以我有几个解决的思路(不确定能成功的)

    1. 通过自带属性修改作用的 DOM 元素
    2. 修改 CSS 样式
    3. 修改 DOM 结构
    4. 通过 js 判断需要作用的 DOM

    下面一个一个来尝试:
    方式一:这个主要是想要查看 Reactcsstransitiongroup 组件本身是否有提供一些属性能够让子组件不受动画影响,查看了资料以后当然是发现没有;
    方式二:修改 CSS 样式是要去修改子组件的样式让它不受父组件影响,这个也是后来成功的方式,待会儿再细说。
    方式三:修改 DOM 的方法其实就是相当于将 Navbar 组件从 View 组件中拿出来,这样其实能够很快解决问题,但是问题在于这样一来页面结构不够清晰,代码就不太好维护。所以这个方式其实应该是放在最后的才考虑的。
    方式四:这个方式没有去尝试,因为通过修改 CSS 样式就已经解决了问题,所以不确定此方式的可行性,这里列出只是记录一下。

    (使用的工具其实很简单,就是 chrome 的 developer tools,新版浏览器的查看动画是在工具栏最右侧三个点,点开然后选择 More tools,第一个选项 Animations 就能查看到动画情况。)

    现在主要讲一下修改 CSS 样式的这种方式,首先如果想要通过设置子元素 position: absolute 是绝对不可行的,是的,我有去傻傻尝试过。
    我先考虑的是如何解决 transform 的问题,父元素的动画是 transform: translateY(10px);transform: translateY(0); ,Y轴坐标从 10px 变换到 0px,其实仔细想想,只要对子元素做一个反向的动画就可以,所以我对子元素设置成 transform: translateY(10px);transform: translateY(0); ,查看效果,并不会存在晃动的情况,而是十分平稳的不会有任何动作。但是需要注意的是子元素并没有 enter 和 leave 的动画,只有 appear 的动画,所以需要找到父元素对应的动画情况来做坐标的抵消,比如父元素的 appear 和 enter 都应该和子元素的 appear 进行抵消。
    例如:

    // 父元素 css
    .enter {
      transform: translateY(10px);
      &.enterActive {
        transform: translateY(0);
        transition: all 400ms ease;
      }
    }
    
    // 子元素 css
    .appear {
      transform: translateY(-10px);
      &.appearActive {
        transform: translateY(0px);
        transition: all 400ms ease;
      }
    }
    

    接着是 opacity 的问题,要明确一点的是 opacity 是无法进行抵消的,它的范围是 0 ~ 1,不论设置什么小于0的值,最后的取值都是 0,无论设置什么大于1的值,最后的取值都是1,如果父元素设置为0.5,子元素想要设置2来抵消动画行为是不可行的。子元素的 opacity 属性的设置,永远是建立在父元素的基础上,比如:

    // 父元素 css
    .enter {
      opacity:0.5
    }
    // 子元素 css
    .enter-child {
    opacity: 1
    }
    // 父元素设置为 0.5,子元素设置为1,但是子元素看起来的效果和父元素是一样的
    // 因为子元素是在 0.5 的基础上设置1,如果子元素也设置0.5,则子元素看到的就是 0.25 的效果。
    

    网上有查询到其它的方法,还有另外两种,都是不使用 opacity,毕竟拿它没办法,一种是使用 background:rgba(0,0,0,0.5) 替代,当然并不一定 rgb 都是零,另外一种是使用半透明图片替代,这两种方法并不是针对动画中的半透明,而是针对静态情况下的半透明,但是感觉大同小异。总之对于我的项目并不是一个好的方式,毕竟我不仅仅需要背景半透明。
    所以在对 opacity 的处理上,是让效果减少的最小,让它看起来没有很明显的动画,说白了也是在父组件和子组件之间取得平衡,父组件既不因为动画不明显而变化得太突兀,子组件也不会有很明显的有淡入淡出的效果,让 leave 和 enter 的动画衔接得很紧。
    代码如下:

    // 父组件 css
    .appear {
      opacity: 0.5;
      transform: translateY(10px);
      &.appearActive {
        opacity: 1;
        transform: translateY(0px);
        transition: all 400ms ease;
      }
    }
    
    .leave {
      opacity: 1;
      &.leaveActive {
        opacity: 0;
        transition: all 400ms ease;
      }
    }
    // 子组件不需要设置 opacity
    

    相关文章

      网友评论

          本文标题:transition 相关记录(如何让子元素不受父元素影响)

          本文链接:https://www.haomeiwen.com/subject/vqtogttx.html