vue实现 js 控制 css

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/jufjzq/article/details/102702548

需求

封装一个使用 css3 动画帧的上下滚动文字的组件,代码如下

html

<template>
  <div class="scroll_box" @mouseenter="stopScroll" @mouseleave="startScroll" ref="scroll_box">
    <span v-for="(item,index) in text" :key="index">
      {{item}}
      <br />
    </span>
  </div>
</template>

js

methods: {
  stopScroll(e) {
    if (!e.target.style.animationPlayState) {
      e.target.style.animationPlayState = 'paused'
    }
  },
  startScroll(e) {
    e.target.style.animationPlayState = ''
  }
}

css

<style lang="less" scoped>
.scroll_box {
  width: 100%;
  text-align: justify;
  animation: moveTxt 1s 1 linear forwards;
  animation: moveTxt 45s infinite linear;
  @keyframes moveTxt {
    from {
      transform: translateY(200px);
    }
    to {
      transform: translateY(-2880px);
    }
  }
}
</style>
封装痛点

需要动态获取盒子高度,设置到 css 中的 @keyframes 中
问题:

  1. 通过绑定 ref 获取 style 对象,但是没有 @keyframes 属性,更没有 from to 等可以设置。
    查询百度,发现通过 js 设置 @keyframes 需要通过 document.styleSheet[] 的 item 遍历操作,但是 vue 中的累数组几十个,放弃,转为通过给 css 设置变量,然后 js 动态设置 css 的变量
css 变量

css 变量必须写在 .xxx{}内,不能直接在 <style>下设置变量
--xx定义变量
var(--xx)使用变量

css

<style lang="less" scoped>
.scroll_box {
  --scrollheight: 200px;     //定义变量
  width: 100%;
  text-align: justify;
  animation: moveTxt 1s 1 linear forwards;
  animation: moveTxt 45s infinite linear;
  @keyframes moveTxt {
    from {
      transform: translateY(200px);
    }
    to {
      transform: translateY(var(--scrollheight)) //使用变量
    }
  }
}
</style>

js 控制变量
this.$refs.refName.style.setProperty('变量名', 值 )

mounted() {
  let height = this.$refs.scroll_box.offsetHeight
  this.$refs.scroll_box.style.setProperty('--scrollheight', -height+'px' )
  console.log(this.$refs.scroll_box.style.getPropertyValue('--scrollheight'))
}
通过调试发现设置上了,但是动画不生效,必须鼠标移入移除后才能正常执行动画,并有卡顿

解决:模拟鼠标事件,在设置上 css 后出发鼠标进入移除事件,触发 css 更新

js

mounted() {
    let height = this.$refs.scroll_box.offsetHeight
    this.$refs.scroll_box.style.setProperty('--scrollheight', -height + 'px')
    console.log(this.$refs.scroll_box.style.getPropertyValue('--scrollheight'))
    // this.$forceUpdate()
    var oMouseenter = document.createEvent('MouseEvent')
    oMouseenter.initEvent('mouseenter', false, false)
    this.$refs.scroll_box.dispatchEvent(oMouseenter)
    oMouseenter.initEvent('mouseleave', false, false)
    setTimeout(() => {
      this.$refs.scroll_box.dispatchEvent(oMouseenter)
    }, 50)
  }

PS:

强制刷新 vue 组件: this.$forceUpdate()

个人总结

  1. css/less/sass 等变量知识空缺
  2. 模拟事件知识空缺
  3. 事件相关函数知识空缺

猜你喜欢

转载自blog.csdn.net/jufjzq/article/details/102702548