美文网首页
关于怎么在手机端实现一个拖拽的操作

关于怎么在手机端实现一个拖拽的操作

作者: cb12hx | 来源:发表于2018-04-01 19:13 被阅读0次

    手机端,肯定是监听touchstart,touchmove,touchend事件
    先来看看效果


    aabbcc.gif

    当拖拽时,拖拽到哪个节点下面,就把哪个节点添加到这个下面

      <div>1111</div>
      <div>2222</div>
      <div>3333</div>
      <div>4444</div>
      <div>5555</div>
      <div class="hightlight"></div>
    

    前面的div,是我们要拖拽的对象,highlight是用来高亮当前拖到了哪个下面,以便于用户体验

    1.初始化

      // 获取所有的节点
      var divList = Array.from(document.querySelectorAll('div'))
      // 用来高亮的节点
      var hightlight = document.querySelector('.hightlight')
      // 手指一开始命中的那个节点
      var lastChild = null
      // 来自于lastChild,在手指离开之前,都是克隆的
      var currentChild = null
      // 要添加到的那个父节点
      var needAppendParent = null
      // 用来初始化每一个节点的边距,不要每次去算,触发回流
      function init() {
        divList.forEach(item => {
          var bound = item.getBoundingClientRect()
          item.bound = JSON.parse(JSON.stringify(bound))
        })
      }
      init()
    

    初始化,就是把每一个拖拽的对象的边距值全部保存起来,避免每次去计算导致的重绘

    1.touchstart

       /*
        手指移上去时,克隆命中的这个节点,并且这是它当前的位置,
        为手指移上去的位置,
        显示当前的hightlight命中了哪个
      */
      document.body.addEventListener('touchstart', function(e) {
        lastChild = e.target
        currentChild = e.target.cloneNode(true)
        currentChild.style.cssText = `position:absolute;left:${e.targetTouches[0].pageX }px;top:${e.targetTouches[0].pageY}px;`
        document.body.appendChild(currentChild)
        hightlight.style.cssText = `display:block;left:${lastChild.bound.left}px;top:${lastChild.bound.top}px;width:${lastChild.bound.width}px;height:${lastChild.bound.height}px;`
      })
    

    手指移上去时,我们就记下当前命中的这个节点,并且克隆出一个节点来,它设置绝对定位,位置根据手指的位置变动,并且设置高亮显示,高亮当前命中的这个节点,hightlight的位置信息,宽高,都是有命中的那个节点算出

    2.touchmove

    /*
        让这个节点一直跟着手指动,并且去判断当前高亮哪个节点,并且记下这个节点
      */
      document.body.addEventListener('touchmove', function(e) {
        var currentBound = currentChild.getBoundingClientRect()
        currentChild.style.cssText = `position:absolute;left:${e.targetTouches[0].pageX}px;top:${e.targetTouches[0].pageY}px;`
    
        divList.forEach(item => {
          if (currentBound.left > item.bound.left && currentBound.left < item.bound.right && currentBound.top > item.bound.top && currentBound.top < item.bound.bottom) {
            hightlight.style.cssText = `display:block;left:${item.bound.left}px;top:${item.bound.top}px;width:${lastChild.bound.width}px;height:${lastChild.bound.height}px;`
            needAppendParent = item
          }
        })
      })
    

    move时做了两件事情,第一件是,让克隆的那个节点跟着手指走,第二件判断当前节点的左上角,是否在某个节点里面,即是否大于某个节点的左上角,小于某个节点的右下角,如果是,记住当前节点,并且高亮它

    3.touchend

      /*
        删除手动加的样式,移除上一个节点,把克隆的节点添加到高亮的那个节点里面,hightlight隐藏
      */
      document.body.addEventListener('touchend', function(e) {
        currentChild.style.cssText = ''
        needAppendParent.appendChild(currentChild)
        document.body.removeChild(lastChild)
        hightlight.style.cssText = `display:none;`
      })
    

    touchend,即手指放开时,要做的事情,去除当前节点的position样式,并且把这个克隆的节点加到高亮的那个节点里面去,再移除掉那个被克隆的节点,高亮框隐藏
    假如我们要实现添加到高亮的那个节点后面,可以使用insertAdjacentElement来实现,具体看代码

      /*
        删除手动加的样式,移除上一个节点,把克隆的节点添加到高亮的那个节点里面,hightlight隐藏
      */
      document.body.addEventListener('touchend', function(e) {
        currentChild.style.cssText = ''
        needAppendParent.insertAdjacentElement('afterend', currentChild)
        document.body.removeChild(lastChild)
        hightlight.style.cssText = `display:none;`
      })
    

    效果


    bbb.gif

    注:本demo仅仅是讲解实现一个最简单的拖拽功能,很多场景没考虑,勿喷

    相关文章

      网友评论

          本文标题:关于怎么在手机端实现一个拖拽的操作

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