最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • HTML 拖拉功能

    正文概述 掘金(OctopusRoe)   2021-01-29   301

    基于 vue

    此功能核心思想就是通过 JavaScript 代码控制 node 在页面上的左边距与顶边距,不同的的样式定位方式有不同的解决方案

    本方案采用 position: absolute 定位方式的解决方案

    css 样式的核心代码

      // 父容器核心样式
    
      width: 100%;
      height: 100%;
    
    
      // 子容器核心样式
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
    

    父容器通过 width && height 字段占满整个浏览器的可视范围,子容器通过 position: absolute 属性开启在父容器内的绝对定位,在通过 top && left && transform: translate(-50%, -50%) 属性控制子容器在父容器内的绝对位置

    JavaScript 逻辑控制的核心代码

    首先分解下,要实现 node 的移动需要哪些步骤和对应的 event 事件

    1. 子容器创建时,在父容器内的绝对位置
    2. 鼠标按键按下时,onmousedown 事件
    3. 鼠标移动时,onmousemove 事件
    4. 鼠标按键弹起时,onmouseup 事件

    只要使用 onMousedown、onMousemove和onMouseup 这三个事件,就可以实现最简单的移动

    
    /*
    * 在子容器创建的时候获取子容器相对于父容器的 top 和 left 位置
    */
    
    mounted () {
      this.left = this.$refs.fatherBox.offsetLeft
      this.top = this.$refs.fatherBox.offsetTop
    }
    
    
    
    /*
    * 鼠标按下时
    * 1. 开启允许子容器移动的 flag
    * 2. 记录鼠标点击时的位置信息
    */
    
    mouseDown (e) {
      // 设置允许弹窗移动的 flag
      this.moveFlag = true
      // 保存鼠标开始位置
      this.startLeft = e.clientX - this.left
      this.startTop = e.clientY - this.top
    }
    
    
    
    /*
    * 鼠标移动时
    * 1. 判断 flag 是否允许子容器移动
    * 2. 设置弹框左边位置
    * 3. 设置弹框右边位置
    */
    
    move (e) {
      // 判断 flag 是否允许移动
      if (!this.moveFlag) return
    
      // 设置弹框左边位置
      this.left = e.clientX - this.startLeft
      // 设置弹框右边位置
      this.top = e.clientY - this.startTop
    
    }
    
    
    /*
    * 鼠标按键弹起时
    * 1. 关闭允许子容器移动的 flag
    */
    
    mouseUp (e) {
      this.flag = false
    }
    
    

    通过这几个方法就可以获取鼠标按下移动时,鼠标的top 和 left 的偏移量,通过把这偏移量暴露出去给父组件,父组件实时设置子组件的 top 和 left 值,来使得子容器跟随鼠标的移动

    父组件部分代码

    父组件通过设置子组件的 ref、zIndex 值,而且父组件的 backValue 方法会从子组件接收 zIndex 值,通过 zIndex 来识别具体的子组件实例

    
    /*
    * 父组件代码片段 jsx 版
    */
    
    export default {
      props: {
        playList: {
          type: Array,
          required: true
        }
      },
      render () {
        return (
          <div style={{width: '100%', height: '100%'}} ref={'father'}>
            {
              this.playList && this.playList.map((item, index) => {
                return (
                  <ChildComponents
                    key={index}
                    ref={index}
                    zIndex={index}
                    visible={true}
                    backValue={this.backValue}
                    info={item}
                    width={600}
                    height={400}
                  />
                )
              })
            }
          </div>
        )
      },
      methods: {
        backValue (left, top, zIndex) {
          this.$refs[zIndex].$el.style.top = `${top}px`
          this.$refs[zIndex].$el.style.left = `${left}px`
        }
      }
    }
    
    
    <!-- 父组件代码片段 vue 文件版 -->
    
    <template>
      <div
        ref="father"
        style"width: 100%, height: 100%"
      >
        <ChildComponents
          v-for="(item, index) in playList"
          :key="index"
          :ref="index"
          :visible="true"
          :z-index="index"
          :back-value="backValue"
          :info="item"
          :close="close"
          :width="600"
          :height="400"
        />
      </div>
    </template>
    <script>
    export default {
      components: {
        VideoPlayerModal
      },
      props: {
        playList: {
          type: Array,
          required: true
        }
      },
      methods: {
        backValue (left, top, zIndex) {
          this.$refs[zIndex][0].$el.style.top = `${top}px`
          this.$refs[zIndex][0].$el.style.left = `${left}px`
        }
      }
    }
    </script>
    

    设置子组件的围栏范围

    这个功能只需要在 onmousemove 事件中进行判断 子容器的 top 和 left 是否超出浏览器的可视范围

    
    /*
    * 1. this.width 数据为父组件传递进来的 width 值,或者子组件本身设置的默认值
    * 2. this.height 数据为父组件传递进来的 height 值,或者子组件本身设置的默认值
    */
    
    move (e) {
      // 判断 flag 是否允许移动
      if (!this.moveFlag) return
    
      // 判断是否超出左边视图
          if (this.$refs.fatherBox.offsetLeft < this.width / 2) {
            // 禁止弹框移动
            this.moveFlag = false
            // 设置弹框左边位置
            this.left = this.width / 2 + 10
            // 调用回调函数把偏移量暴露给父组件
            this.backValue(this.left, this.top, this.zIndex)
            return
          }
    
          // 判断是否超出右边视图
          if (this.$refs.fatherBox.offsetLeft > document.body.clientWidth - this.width / 2) {
            // 禁止弹框移动
            this.moveFlag = false
            // 设置弹框右边位置
            this.left = document.body.clientWidth - this.width / 2 - 10
            // 调用回调函数把偏移量暴露给父组件
            this.backValue(this.left, this.top, this.zIndex)
            return
          }
    
          // 判断是否超出顶部视图
          if (this.$refs.fatherBox.offsetTop < this.height / 2 + 70) {
            // 禁止弹框移动
            this.moveFlag = false
            // 设置弹框顶部位置
            this.top = this.height / 2 + 70 + 10
            // 调用回调函数把偏移量暴露给父组件
            this.backValue(this.left, this.top, this.zIndex)
            return
          }
    
          // 判断是否超出底部视图
          if (this.$refs.fatherBox.offsetTop > document.body.clientHeight - this.height / 2 - 50) {
            // 禁止弹框移动
            this.moveFlag = false
            // 设置弹框底部位置
            this.top = document.body.clientHeight - this.height / 2 - 50 - 10
            // 调用回调函数把偏移量暴露给父组件
            this.backValue(this.left, this.top, this.zIndex)
            return
          }
    
          // 设置弹框左边位置
          this.left = e.clientX - this.startLeft
          // 设置弹框右边位置
          this.top = e.clientY - this.startTop
    
          // 调用回调函数把偏移量暴露给父组件
          this.backValue(this.left, this.top, this.zIndex)
    }
    
    

    子组件还要设置一个当鼠标超出子容器时的 onmouseout 事件,用来防止不可预期的 bug 问题

    mouseOut (e) {
      this.moveFlag = false
    }
    

    起源地下载网 » HTML 拖拉功能

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元