VUE:指定元素内,鼠标滚轮横向滚动内容,支持平滑滚动

14 篇文章 0 订阅
4 篇文章 0 订阅

简介

页面上,有纵向滚动的元素,也有横向滚动的元素。由于纵向滚动是默认的,所以就需要把横向滚动事件区分开来。

具体实现

对需要滚动条(纵向转变为横向)的标签设置个id(避免重复),然后调用如下 setScroolFun 方法(注意元素渲染后调用)。

 

data () {
  return {
    documentObj : null
  }
},
methods: {
   /*容器绑定鼠标滚轮事件*/
      setScroolFun() {
        //绑定的容器
        this.documentObj = document.getElementById('jjListDiv') // 获取DOM元素节点
        // 添加监听事件(不同浏览器,事件方法不一样,所以可以作判断,也可以如下偷懒)
        this.documentObj.addEventListener('DOMMouseScroll', this.handlerMouserScroll, false)//滚轮事件
        this.documentObj.addEventListener('mousewheel', this.handlerMouserScroll, false)//滚轮事件
      },
      handlerMouserScroll(event) {
        //获取滚轮跨距,兼容获取方式
        let detail = event.wheelDelta || event.detail || event.wheelDeltaY
        /*反向*/
        let moveForwardStep = -1
        /*正向*/
        let moveBackStep = 1
        let step = 0
        //如果跨步大于0,表明正向跨步,将跨步放大100倍,改变滑动速度,如果跨步小于0,表明反向跨步,将跨步放大500倍,改变滑动速度
        step = detail > 0 ? moveForwardStep * 80 : moveBackStep * 80
        /*覆盖当前滚动条的位置,单位是像素,叠增或剃减*/
        this.documentObj.scrollLeft = this.documentObj.scrollLeft + step

        //平滑值(越小越慢,不能小于等于0)
        let slipNum = 0.8
        //末尾值(越小,则越平稳,越大越仓促)
        let endNum = 5
        /*递减步伐值*/
        let decreasingPaceNum = step
        /*速度*/
        let paceNum=60;

        /*效果一*/
        let t = setInterval(() => {
          if (Math.abs(decreasingPaceNum) < endNum) {
            clearInterval(t)
            return
          }
          decreasingPaceNum = decreasingPaceNum * slipNum
          this.documentObj.scrollLeft = this.documentObj.scrollLeft + decreasingPaceNum
        }, paceNum)

        /*效果二*/
        /*for(let i=1;Math.abs(decreasingPaceNum) > endNum;i++){
          decreasingPaceNum = decreasingPaceNum * slipNum
          setTimeout(() => {
            this.documentObj.scrollLeft = this.documentObj.scrollLeft + decreasingPaceNum
          }, i * paceNum)
        }*/
      },
}

 

注意

页面销毁时,取消监听事件,避免资源浪费!

 

//销毁事件
beforeDestroy() {
  if (!this.documentObj) return
  this.documentObj.removeEventListener('DOMMouseScroll', this.handlerMouserScroll)
  this.documentObj.removeEventListener('mousewheel', this.handlerMouserScroll)
}

 

 

完整代码

index.vue

<style>

  .bg-purple-light {
    background: #e5e9f2;
  }

  .grid-content {
    border-radius: 4px;
    min-height: 36px;
  }


  .lateral-sliding {
    display: flex;
    overflow-y: hidden;
    overflow-x: scroll;
  }

  .lateral-sliding-item {
    display: flex;
    margin-right: 8px;
    background-color: yellow;
  }

  .each-img {
    min-width: 350px;
    min-height: 758px;
  }

</style>

<template>
  <div class="app-container">
    <el-row :gutter="15" type="flex" justify="start" align="middle">
      <!--左侧条件-->
      <el-col v-if="!hideSearch" :span="4">
        <div class="grid-content ">
          <el-form :model="ruleForm"
                   status-icon
                   :rules="rules"
                   label-suffix=":"
                   inline-message
                   label-position="left"
                   ref="ruleForm"
                   label-width="100px"
                   size="mini"
                   class=""
                   :inline="false">
            <el-form-item label="基金代码" prop="jjCode">
              <el-input style="max-width: 184px" v-model.number="ruleForm.code">
              </el-input>
            </el-form-item>
            <el-form-item label="基金经理" prop="jjjl">
              <el-input style="max-width: 184px" v-model.number="ruleForm.jjjl">
              </el-input>
            </el-form-item>
            <el-form-item label="基金类型" prop="jjType">
              <el-select v-model="ruleForm.jjType" placeholder="请选择">
                <el-option
                  v-for="item in jjTypeOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="晨星等级" prop="cxGrade">
              <div @dblclick="dblclickCxGrade">
                <el-rate
                  v-model="ruleForm.cxGrade"
                  :texts="['很差','较差','一般','较好','优秀']"
                  show-text
                  :colors="['#99A9BF', '#F7BA2A', '#FF9900']">
                </el-rate>
              </div>
            </el-form-item>
            <el-form-item label="时间" prop="time">
              <el-select v-model="ruleForm.time" placeholder="请选择">
                <el-option
                  v-for="item in timeOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item label="规模" prop="guiMo">
              <el-select v-model="ruleForm.guiMo" placeholder="请选择">
                <el-option
                  v-for="item in guimoOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
                <el-option disabled value="guiMo">
                  自定义
                  <el-input @input="checkMoneyS($event)" v-model="guiMoStart"
                            style="width: 60px"/>
                  至
                  <el-input @input="checkMoneyS($event)" v-model="guiMoEnd"
                            style="width: 60px"/>
                  (亿元)
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item label="所属板块" prop="ssBanKuai">
              <el-select v-model="ruleForm.ssBanKuai" placeholder="请选择">
                <el-option
                  v-for="item in ssBanKuaiOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item>
              <el-button type="primary">搜索</el-button>
              <el-button>重置</el-button>
            </el-form-item>
          </el-form>
        </div>
      </el-col>

      <el-divider content-position="left" direction="vertical">====</el-divider>
      <!--列表-->
      <el-col :span="20">
        <div id="jjListDiv" class="grid-content bg-purple-light lateral-sliding">
          <div class="lateral-sliding-item" v-for="(item,index) in 99" :key="index">
            <div class="each-img">{{index}}</div>
          </div>
        </div>
      </el-col>


    </el-row>


  </div>
</template>
<script>
  import 'element-ui/lib/theme-chalk/display.css'

  export default {
    name: 'list',
    components: {},
    props: {},
    data() {
      return {
        documentObj: null,
        currentDate: new Date(),

        /*左侧容器显示状态*/
        hideSearch: false,
        /*左侧搜索表单*/
        ruleForm: {
          JJCode: '',//基金代码
          jjjl: '',//基金经理
          jjType: '',//基金类型
          cxGrade: 0,//晨星等级
          time: '',//时间
          guiMo: '',//规模
          ssBanKuai: ''//所属板块
        },
        guiMoStart: 100,
        guiMoEnd: 300,
        /*基金规模选项*/
        guimoOptions: [
          {
            value: '不限',
            label: '不限'
          }, {
            value: '10亿以内',
            label: '10亿以内'
          }, {
            value: '10至50亿',
            label: '10至50亿'
          }, {
            value: '50至150亿',
            label: '50至150亿'
          }, {
            value: '大于150亿',
            label: '大于150亿'
          }],

        /*板块选项*/
        ssBanKuaiOptions: [
          {
            value: '白酒',
            label: '白酒'
          }, {
            value: '医药',
            label: '医药'
          }, {
            value: '军工',
            label: '军工'
          }, {
            value: '新能源',
            label: '新能源'
          }, {
            value: '有色金属',
            label: '有色金属'
          }],

        /*时间选项*/
        timeOptions: [
          {
            value: '今年来',
            label: '今年来'
          }, {
            value: '日涨幅',
            label: '日涨幅'
          }, {
            value: '近一周',
            label: '近一周'
          }, {
            value: '近一月',
            label: '近一月'
          }, {
            value: '近一年',
            label: '近一年'
          }
          , {
            value: '近两年',
            label: '近两年'
          }
          , {
            value: '近三年',
            label: '近三年'
          }
          , {
            value: '近五年',
            label: '近五年'
          }
          , {
            value: '成立以来',
            label: '成立以来'
          }],

        /*基金类型选项*/
        jjTypeOptions: [
          {
            value: '混合型',
            label: '混合型'
          }, {
            value: '股票型',
            label: '股票型'
          }, {
            value: '债券型',
            label: '债券型'
          }, {
            value: '指数型',
            label: '指数型'
          }, {
            value: 'FOF型',
            label: 'QDll型'
          }],

        /*左侧搜索表单校验*/
        rules: {
          /*age: [
            { required: true, message: '请输入活动名称', trigger: 'blur' },
          ],*/

        }
      }
    },
    watch: {
      /*监听晨星等级变化*/
      /*'ruleForm.cxGrade': {
        handler: function(o, l) {

        }
      },
*/
      /*
      /!*监听晨星等级变化*!/
      getCxGrade: {
        handler: function(o,l) {
          console.log('o,l::', o,l)
        },
      }*/

    },

    computed: {
      getCxGrade: function() {
        return this.ruleForm.cxGrade
      }
    },

    created() {

    },

    mounted() {
      this.$nextTick(() => {
        this.setScroolFun()
      })
    },
    beforeDestroy() {
      if (!this.documentObj) return
      this.documentObj.removeEventListener('DOMMouseScroll', this.handlerMouserScroll)
      this.documentObj.removeEventListener('mousewheel', this.handlerMouserScroll)
    },
    methods: {

      /*容器绑定鼠标滚轮事件*/
      setScroolFun() {
        //绑定的容器
        this.documentObj = document.getElementById('jjListDiv') // 获取DOM元素节点
        // 添加监听事件(不同浏览器,事件方法不一样,所以可以作判断,也可以如下偷懒)
        this.documentObj.addEventListener('DOMMouseScroll', this.handlerMouserScroll, false)//滚轮事件
        this.documentObj.addEventListener('mousewheel', this.handlerMouserScroll, false)//滚轮事件
      },
      handlerMouserScroll(event) {
        //获取滚轮跨距,兼容获取方式
        let detail = event.wheelDelta || event.detail || event.wheelDeltaY
        /*反向*/
        let moveForwardStep = -1
        /*正向*/
        let moveBackStep = 1
        let step = 0
        //如果跨步大于0,表明正向跨步,将跨步放大100倍,改变滑动速度,如果跨步小于0,表明反向跨步,将跨步放大500倍,改变滑动速度
        step = detail > 0 ? moveForwardStep * 80 : moveBackStep * 80
        /*覆盖当前滚动条的位置,单位是像素,叠增或剃减*/
        // this.documentObj.scrollLeft = this.documentObj.scrollLeft + step

        //平滑值(越小越平滑越持久,反之,总之。总之,不能小于等于0,不能大于等于1,作者建议值:0.8)
        let slipNum = 0.8
        //末尾值(越小,则越平稳,越大,则越仓促,作者建议值:5)
        let endNum = 5
        /*递减步伐最大初始值=滚轮单位跨步值*/
        let decreasingPaceNum = step
        /*平滑速度,越大,则越慢,越小,则越慢,作者建议值:70*/
        let paceNum=70;

        /*效果一*/
        let t = setInterval(() => {
          if (Math.abs(decreasingPaceNum) < endNum) {
            clearInterval(t)
            return
          }
          decreasingPaceNum = decreasingPaceNum * slipNum
          this.documentObj.scrollLeft = this.documentObj.scrollLeft + decreasingPaceNum
        }, paceNum)


      },

      /*规模校验*/
      checkMoneyS(value) {
        if (!value) {
          this.$message.error('不能为空')
        } else if (value < 1 || value > 1000) {
          this.$message.error('应在1在1000之间')
        } else {
          let reg = /(^[1-9]\d*$)///小数点左边最高16位,小数点右边最多4位
          if (reg.test(value)) {
            if (this.guiMoStart >= this.guiMoEnd) {
              this.$message.error('前者应该小于后者')
            }
            this.ruleForm.guiMo = this.guiMoStart + '至' + this.guiMoEnd + '亿'
          } else {
            this.$message.error('应该为正整数')
          }
        }
      }
      ,

      /*晨星等级:双击清空*/
      dblclickCxGrade() {
        this.ruleForm.cxGrade = 0
      }

    }
  }
</script>


<style lang="scss" scoped>

</style>

 

 

 

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值