jquery-ui draggable中div拖动出现辅助线方便对齐,实现简单布局器

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>实现div拖拽时出现辅助线,以方便和其它div很容易的对齐,实现简单布局器</title>
    <link rel="stylesheet" href="./jquery-ui-1.12.1/jquery-ui.min.css" />
  </head>
  <body>
    <!-- 网格线 -->
    <div id="grid-line"></div>
    <div class="container">
      <!-- 拖动辅助线 -->
      <div id="guide-h" class="guide"></div>
      <div id="guide-v" class="guide"></div>

      <div class="draggable"></div>
      <div class="draggable" style="background-color: blanchedalmond;"></div>
    </div>
    <script src="./jquery-ui-1.12.1/external/jquery/jquery.js"></script>
    <script src="./jquery-ui-1.12.1/jquery-ui.min.js"></script>
    <script>
      const gridSpace = 50
      // 拖拽部件选项
      const draggableOption = {
        // 约束在指定元素或区域的边界内拖拽
        containment: '.container',
        // 鼠标按下后拖拽开始前必须移动的距离,以像素计。该选项可以防止点击在某个元素上时不必要的拖拽
        distance: 10,
        // 当被拖拽时助手(helper)的不透明度
        opacity: 0.5,
        // 如果设置为 true,当拖拽时容器会自动滚动
        scroll: true,
        // 从要滚动的视区边缘起的距离,以像素计。距离是相对于指针的,不是相对于 draggable。如果 scroll 选项是 false 则忽略
        scrollSensitivity: 20,
        // 当鼠标指针获取到在 scrollSensitivity 距离内时,窗体滚动的速度。如果 scroll 选项是 false 则忽略
        scrollSpeed: 100,
        // 对齐拖拽助手(helper)到网格,每个 x 和 y 像素。数组形式必须是 [ x, y ]
        grid: [gridSpace, gridSpace],
        // 如果设置为 true,在每次鼠标移动(mousemove)时都会计算所有可放置的位置。注意:这解决了高度动态的问题,但是明显降低了性能
        // refreshPositions: true,
        // 拖拽操作期间的 CSS 光标
        cursor: 'move',
        // 元素是否对齐到其他元素
        snap: true,
        // 从要发生对齐的对齐元素边缘起的距离,以像素计。如果 snap 选项是 false 则忽略
        snapTolerance: 20
      }
      // 缩放部件选项
      const resizeableOption = {
        // 约束在指定元素或区域的边界内拖拽
        containment: '.container',
        // 当用户鼠标没有悬浮在元素上时是否隐藏手柄
        autoHide: true,
        // 把可调整尺寸元素对齐到网格,每个 x 和 y 像素。数组形式必须是 [ x, y ]
        grid: [gridSpace, gridSpace],
        // 如果设置为 true,则为调整尺寸显示一个半透明的辅助元素
        // ghost: true
        // grid: 50
        // resizable 允许被调整到的最小宽度
        minWidth: 50,
        // resizable 允许被调整到的最小高度
        minHeight: 50
      }

      $(function() {
        // 初始化组件拖拽、缩放
        initComponent('.draggable')
      })

      // 初始化组件拖拽、缩放
      function initComponent(selector) {
        $(selector)
          // 拖拽部件文档:https://www.jqueryui.org.cn/api/3722.html
          .draggable(
            Object.assign(draggableOption, {
              /**
               * 在拖拽期间当鼠标移动时触发
               */
              drag: function(event, ui) {
                const x = ui.position.left
                const y = ui.position.top
                const containerHeight = $('.container').height() + $('.container').scrollTop()
                const containerWidth = $('.container').width() + $('.container').scrollLeft()

                initGrid()

                $('#guide-v').css({ height: containerHeight + 'px', left: x })
                $('#guide-h').css({  containerWidth + 'px', top: y })
                $('#guide-v,#guide-h').show()
              },
              /**
               * 当拖拽停止时触发
               */
              stop: function(event, ui) {
                $('.container .grid-line').remove()
                $('#guide-v,#guide-h').hide()
              }
            })
          )
          // 缩放部件文档:https://www.jqueryui.org.cn/api/3725.html
          .resizable(
            Object.assign(resizeableOption, {
              /**
               * 在调整尺寸期间当调整手柄拖拽时触发
               * @param {Event} event 事件对象
               * @param {Object} ui 拖拽 ui 元素
               *    helper - jQuery 对象,表示被调整尺寸的助手(helper)
               *    originalElement - jQuery 对象,表示被包裹之前的原始元素
               *    originalPosition - resizable 调整前的位置,表示为 { top, left }
               *    originalSize - resizable 调整前的尺寸,表示为 { width, height }
               *    position - 助手(helper)的当前 CSS 位置,比如 { top, left } 对象
               *    size - 助手(helper)的当前大小,比如 { top, left } 对象
               */
              resize: function(event, ui) {
                initGrid()
              },
              /**
               * 当调整尺寸操作停止时触发
               */
              stop: function(event, ui) {
                $('.container .grid-line').remove()
              }
            })
          )
      }

      function initGrid() {
        const containerHeight = $('.container').height() + $('.container').scrollTop()
        const containerWidth = $('.container').width() + $('.container').scrollLeft()

        $('.container .grid-line').remove()
        let lineTop = 0
        while (lineTop < containerHeight) {
          let gridLine = $('#grid-line').clone()
          gridLine.removeAttr('id')
          gridLine.addClass('grid-line')
          gridLine.addClass('grid-line-h')
          gridLine.attr('top', lineTop)
          gridLine = gridLine[0]

          lineTop += gridSpace
          gridLine.style.top = lineTop + 'px'
          gridLine.style.left = '0px'
          gridLine.style.width = containerWidth + 'px'
          gridLine.style.height = '1px'
          $('.container').append(gridLine)
        }

        let lineLeft = 0
        while (lineLeft < containerWidth) {
          let gridLine = $('#grid-line').clone()
          gridLine.removeAttr('id')
          gridLine.addClass('grid-line')
          gridLine.addClass('grid-line-v')
          gridLine.attr('left', lineLeft)
          gridLine = gridLine[0]

          lineLeft += gridSpace
          gridLine.style.top = '0px'
          gridLine.style.left = lineLeft + 'px'
          gridLine.style.width = '1px'
          gridLine.style.height = containerHeight + 'px'
          $('.container').append(gridLine)
        }
      }
    </script>
    <style>
      .container {
        /* margin-top: 100px; */
        top: 20px;
        min-height: 700px;
        /* padding-bottom: 100px; */
        position: relative;
        /* 修复拖拽元素吸附到其他元素时超出容器区域 */
        overflow: scroll;
        /* background-color: gray; */
        border: 1px #c0c0c0 solid;
        z-index: 0;
      }
      .container .grid-line {
        position: absolute;
        z-index: 0;
        /* border: 1px red solid; */
      }
      .container .grid-line-h {
        border-top: 1px dashed rgb(236, 236, 236);
        /* border-top: 1px dashed rgb(255, 0, 0); */
        width: 100%;
      }
      .container .grid-line-v {
        border-left: 1px dashed rgb(236, 236, 236);
        /* border-left: 1px dashed rgb(255, 0, 0); */
        height: 100%;
      }

      .draggable {
        width: 150px;
        height: 150px;
        background-color: gray;
        position: absolute;
        top: 0px;
        left: 0px;
        z-index: 1;
      }

      .guide {
        display: none;
        position: absolute;
        left: 0;
        top: 0;
      }

      /* 水平 */
      #guide-h {
        border-top: 1px red solid;
        width: 100%;
      }

      /* 垂直 */
      #guide-v {
        border-left: 1px red solid;
        height: 100%;
      }
    </style>
  </body>
</html>
原文地址:https://www.cnblogs.com/jardeng/p/14049585.html