欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript原生实现HTML元素8方位拉伸拖拽

程序员文章站 2022-07-10 21:49:30
JavaScript原生实现HTML元素8方位拉伸拖拽实现思路代码实现实现思路拖拽元素(窗口)的实现很简单,在此不过多阐述,主要是选中元素,计算相对位置,然后将事件聚焦到待拖动的元素里面,计算移动的距离,应用到元素的CSS样式上,最后释放事件就可以了。8方位的拉伸,网上现在先行的比较流行的代码是在一个DIV里面添加8个DIV以确定方位角,(但是这种方法真的是low爆了)完全不符合现行的模块化开发思路。(我总不能为了做个拉伸,还得在里面添加8个无用的DIV吧)所以,最好的方式,就是鼠标到元素(窗口)的指...

JavaScript原生实现HTML元素8方位拉伸拖拽

实现思路

拖拽元素(窗口)的实现很简单,在此不过多阐述,主要是选中元素,计算相对位置,然后将事件聚焦到待拖动的元素里面,计算移动的距离,应用到元素的CSS样式上,最后释放事件就可以了。
8方位的拉伸,网上现在先行的比较流行的代码是在一个DIV里面添加8个DIV以确定方位角,(但是这种方法真的是low爆了)完全不符合现行的模块化开发思路。(我总不能为了做个拉伸,还得在里面添加8个无用的DIV吧)所以,最好的方式,就是鼠标到元素(窗口)的指定位置,就能变换光标样式,(就和你在window里面拉动窗口一样)这样就必然会使用到mousemove事件,所以只要能确定元素的X/Y向偏移和元素自身的长宽,这个问题就很好解决了。
对于拉伸而言,方位检测一旦完成,拉伸就很好做了,和拖拽的思路基本一致,拖拽是改变元素的top/left值,而拉伸改变的是height/width/top/left的值罢了。

代码实现
<html>
  <head>
  </head>
  <body>
    <div id="main" style="width: 200px; height: 200px; background: #cccccc;"></div>
    <script>
      const el = document.querySelector('#main')
      el.style.position = 'absolute'
      el.style.top = '100px'
      el.style.left = '100px'
      el.style.zIndex = "99"
      const accuracy = 10
      const minWidth = 100
      const minHeight = 100
      el.onmousemove = (event) => {
        const x = event.clientX
        const y = event.clientY
        const topYUpperLimit = el.offsetTop + accuracy, topYLowerLimit = el.offsetTop
        const bottomYUpperLimit = el.offsetTop + el.clientHeight, bottomYLowerLimit = el.offsetTop + el.clientHeight - accuracy
        const leftXUpperLimit = el.offsetLeft + accuracy, leftXLowerLimit = el.offsetLeft
        const rightXUpperLimit = el.offsetLeft + el.clientWidth, rightXLowerLimit = el.offsetLeft + el.clientWidth - accuracy
        const CENTER = 0, LEFTTOP = 1, TOP = 2, RIGHTTOP = 3, RIGHT = 4, RIGHTBOTTOM = 5, BOTTOM = 6, LEFTBOTTOM = 7, LEFT = 8
        const checkWindowSize = (el) => {
          if (parseInt(el.style.width) < minWidth) {
            el.style.width = minWidth + 'px'
          }
          if (parseInt(el.style.height) < minHeight) {
            el.style.height = minHeight + 'px'
          }
        }
        const mouseDownHandler = (el, location) => {
          el.onmousedown = (event) => {
            const initX = event.clientX, initY = event.clientY
            const clientX = el.clientWidth, clientY = el.clientHeight
            const offsetX = el.offsetLeft, offsetY = el.offsetTop
            const relativeX = event.clientX - el.offsetLeft, relativeY = event.clientY - el.offsetTop
            const windowInnerWidth = window.innerWidth, windowInnerHeight = window.innerHeight
            if (typeof el.setCapture !== 'undefined') {
              el.setCapture()
            }
            document.onmousemove = (event) => {
              if (location == LEFTTOP) {
                const moveX = event.clientX - initX
                const moveY = event.clientY - initY
                el.style.left = offsetX + moveX + 'px'
                el.style.top = offsetY + moveY + 'px'
                el.style.width = clientX - moveX + 'px'
                el.style.height = clientY - moveY + 'px'
              } else if (location == TOP) {
                const moveY = event.clientY - initY
                el.style.top = offsetY + moveY + 'px'
                el.style.height = clientY - moveY + 'px'
              } else if (location == RIGHTTOP) {
                const moveX = event.clientX - initX
                const moveY = event.clientY - initY
                el.style.top = offsetY + moveY + 'px'
                el.style.width =  clientX + moveX + 'px'
                el.style.height = clientY - moveY + 'px'
              } else if (location == RIGHT) {
                const moveX = event.clientX - initX
                el.style.width =  clientX + moveX + 'px'
              } else if (location == RIGHTBOTTOM) {
                const moveX = event.clientX - initX
                const moveY = event.clientY - initY
                el.style.width =  clientX + moveX + 'px'
                el.style.height = clientY + moveY + 'px'
              } else if (location == BOTTOM) {
                const moveY = event.clientY - initY
                el.style.height = clientY + moveY + 'px'
              } else if (location == LEFTBOTTOM) {
                const moveX = event.clientX - initX
                const moveY = event.clientY - initY
                el.style.left = offsetX + moveX + 'px'
                el.style.width =  clientX - moveX + 'px'
                el.style.height = clientY + moveY + 'px'
              } else if (location == LEFT) {
                const moveX = event.clientX - initX
                const moveY = event.clientY - initY
                el.style.left = offsetX + moveX + 'px'
                el.style.width =  clientX - moveX + 'px'
              } else if (location == CENTER) {
                let moveX = event.clientX - relativeX
                let moveY = event.clientY - relativeY
                if (moveX < 0) {
                  moveX = 0
                }
                if (moveY < 0) {
                  moveY = 0
                }
                if (moveX > windowInnerWidth - el.clientWidth) {
                  moveX = windowInnerWidth - el.clientWidth
                }
                if (moveY > windowInnerHeight - el.clientHeight) {
                  moveY =  windowInnerHeight - el.clientHeight
                }
                el.style.left = moveX + 'px'
                el.style.top = moveY + 'px'
              }
              checkWindowSize(el)
            }
            document.onmouseup = (event) => {
              el.onmousedown = null
              document.onmousemove = null
              document.onmouseup = null
              if (typeof el.setCapture !== 'undefined') {
                el.releaseCapture()
              }
            }
          }
        }
        if (leftXLowerLimit < x && x < leftXUpperLimit && topYLowerLimit < y && y < topYUpperLimit) {
          // console.log('左上角')
          el.style.cursor = 'nw-resize'
          mouseDownHandler(el, LEFTTOP)
        } else if (rightXLowerLimit < x && x < rightXUpperLimit && topYLowerLimit < y && y < topYUpperLimit) {
          // console.log('右上角')
          el.style.cursor = 'ne-resize'
          mouseDownHandler(el, RIGHTTOP)
        } else if (rightXLowerLimit < x && x < rightXUpperLimit && bottomYLowerLimit < y && y < bottomYUpperLimit) {
          // console.log('右下角')
          el.style.cursor = 'se-resize'
          mouseDownHandler(el, RIGHTBOTTOM)
        } else if (leftXLowerLimit < x && x < leftXUpperLimit && bottomYLowerLimit < y && y < bottomYUpperLimit) {
          // console.log('左下角')
          el.style.cursor = 'sw-resize'
          mouseDownHandler(el, LEFTBOTTOM)
        } else if (topYLowerLimit < y && y < topYUpperLimit){
          // console.log('上边缘')
          el.style.cursor = 'n-resize'
          mouseDownHandler(el, TOP)
        } else if (bottomYLowerLimit < y && y < bottomYUpperLimit) {
          // console.log('下边缘')
          el.style.cursor = 's-resize'
          mouseDownHandler(el, BOTTOM)
        } else if (leftXLowerLimit < x && x <leftXUpperLimit) {
          // console.log('左边缘')
          el.style.cursor = 'w-resize'
          mouseDownHandler(el, LEFT)
        } else if (rightXLowerLimit < x && x < rightXUpperLimit) {
          // console.log('右边缘')
          el.style.cursor = 'e-resize'
          mouseDownHandler(el, RIGHT)
        } else {
          el.style.cursor = 'pointer'
          mouseDownHandler(el, CENTER)
        }
      }
    </script>
  </body>
</html>

本文地址:https://blog.csdn.net/codebooks/article/details/107310747