1. 程式人生 > 實用技巧 >【轉】jquery-ui draggable中div拖動出現輔助線方便對齊(優化)

【轉】jquery-ui draggable中div拖動出現輔助線方便對齊(優化)

<html>
  <head>
    <link rel="stylesheet" href="./jquery-ui-1.12.1/jquery-ui.min.css" />
    <title>實現div拖拽時出現輔助線,以方便和其它div很容易的對齊</title>
  </head>

  <body>
    <div class="container">
      <!-- 需要拖動的div -->
      <div class="draggable">第一個div</
div> <div class="draggable">第二個div</div> <div class="draggable">第三個div</div> <div class="draggable">第四個div</div> <div class="draggable">第五個div</div> <div class="draggable">第六個div</div> <!-- 拖動輔助線 -->
<div id="guide-h" class="guide"></div> <div id="guide-v" class="guide"></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 type
="text/javascript"> var MIN_DISTANCE = 8 //捕獲的最小距離 var guides = [] // 指標拖動輔助標線 var innerOffsetX, innerOffsetY $('.draggable').draggable({ start: function(event, ui) { guides = $.map($('.draggable').not(this), computeGuidesForElement) // offsetX、offsetY:源元素(srcElement)的X, Y座標 innerOffsetX = event.offsetX innerOffsetY = event.offsetY }, drag: function(event, ui) { // 迭代所有的guids,記住最近的h和v guids var guideV, guideH, distV = MIN_DISTANCE + 1, distH = MIN_DISTANCE + 1, offsetV, offsetH var chosenGuides = { top: { dist: MIN_DISTANCE + 1 }, left: { dist: MIN_DISTANCE + 1 } } var $t = $(this) // pageX、pageY:文件座標x、y var pos = { // top: event.pageY - innerOffsetY, // left: event.pageX - innerOffsetX top: event.clientY - innerOffsetY, left: event.clientX - innerOffsetX } // outerHeight、outerWidth:整個瀏覽器的高度、寬度 var w = $t.outerWidth() - 1 var h = $t.outerHeight() - 1 var elemGuides = computeGuidesForElement(null, pos, w, h) $.each(guides, function(i, guide) { $.each(elemGuides, function(i, elemGuide) { if (guide.type == elemGuide.type) { var prop = guide.type == 'h' ? 'top' : 'left' var d = Math.abs(elemGuide[prop] - guide[prop]) if (d < chosenGuides[prop].dist) { chosenGuides[prop].dist = d chosenGuides[prop].offset = elemGuide[prop] - pos[prop] chosenGuides[prop].guide = guide } } }) }) if (chosenGuides.top.dist <= MIN_DISTANCE) { $('#guide-h') .css('top', chosenGuides.top.guide.top) .show() ui.position.top = chosenGuides.top.guide.top - chosenGuides.top.offset } else { $('#guide-h').hide() ui.position.top = pos.top } if (chosenGuides.left.dist <= MIN_DISTANCE) { $('#guide-v') .css('left', chosenGuides.left.guide.left) .show() ui.position.left = chosenGuides.left.guide.left - chosenGuides.left.offset } else { $('#guide-v').hide() ui.position.left = pos.left } }, stop: function(event, ui) { $('#guide-v, #guide-h').hide() } }) /** * 計算 DOM 元素輔助線 * @param {String, Object} elem DOM 選擇器 * @param {Object} pos 位置座標 * @param {Number} w 寬度 * @param {Number} h 高度 * @returns {Array} 輔助線物件陣列 */ function computeGuidesForElement(elem, pos, w, h) { if (elem != null) { var $t = $(elem) // offset - 返回當前元素的偏移量 pos = $t.offset() w = $t.outerWidth() - 1 h = $t.outerHeight() - 1 } // type,方向型別,h - 垂直方向;v - 水平方向。 const guids = [ // 垂直方向 - 頂端對齊線 { type: 'h', left: pos.left, top: pos.top }, // 垂直方向 - 中心對齊線 { type: 'h', left: pos.left, top: pos.top + h / 2 }, // 垂直方向 - 中心對齊線 { type: 'h', left: pos.left, top: pos.top + h }, // 水平方向 - 左側對齊線 { type: 'v', left: pos.left, top: pos.top }, // 水平方向 - 中心對齊線 { type: 'v', left: pos.left + w / 2, top: pos.top }, // 水平方向 - 左側對齊線 { type: 'v', left: pos.left + w, top: pos.top } ] return guids } </script> <style type="text/css"> * { padding: 0px; margin: 0px; } body { height: 100%; overflow-x: hidden; overflow-y: hidden; } .container { width: 100vw; min-height: 90vh; margin: 0px auto; position: relative; overflow: auto; border-bottom: 1px gray solid; } .draggable { width: 200px; height: 100px; border: 1px solid #ccc; display: inline-block; cursor: move; position: absolute !important; top: 0px; left: 0px; } .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>