項目中出現需求,要求動態調整各個分塊的大小,方便縮放查看信息,以下實現了寬度的動態調整(高度的后續會補上)
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> <style media="screen"> html,body { height: 100%; margin: 0; padding: 0; } .flex-dragable { display: flex; } .flex-row { height: 80%; display: flex; flex-direction: column; } .flex-item { flex: 1 1 100%; padding: 15px; margin: 5px; border: 1px solid #a3a3a3; overflow: auto; } .flex-row-item { flex: 1 1 100%; } </style> </head> <body> <div class="flex-row"> <div class="flex-dragable flex-row-item"> <div class="flex-item"> content 1 ... </div> <div class="flex-item"> content 2 ... </div> <div class="flex-item"> content - ... </div> </div> <div class="flex-dragable flex-row-item"> <div class="flex-item"> content 3 ... </div> <div class="flex-item"> content 4 ... </div> </div> </div> </body> <script type="text/javascript"> var items = document.querySelectorAll('.flex-dragable'); Array.from(items).map(function(item){ dragablize(item); }); /** * 初始化拖拽 **/ function dragablize(ctn) { var items = ctn.querySelectorAll('.flex-item'), lastX; Array.from(items).map(function(item){ item.onmousedown = function(event) { var target = getTarget(event), prevItem = target.previousElementSibling, suffItem = target.nextElementSibling; lastX = event.clientX; if (suffItem && (event.offsetX > this.offsetWidth - 10)) { item.mouseDown = true; item.oldX = event.x; item.oldWidth = item.offsetWidth; }else if(prevItem && (event.offsetX < 10)) {// 左邊拖拽時,實際設置前置元素的寬度 var evt = newMouseEvent(event,'mousedown'); prevItem.dispatchEvent(evt); } }; item.onmouseup = function(event) { var target = getTarget(event), prevItem = target.previousElementSibling; item.mouseDown = false; item.style.cursor = ''; lastX = null; if(prevItem) {// 左邊拖拽時觸發前置元素mouseup,避免響應異常 var evt = newMouseEvent(event,'mouseup'); prevItem.dispatchEvent(evt); } }; }); ctn.onmousemove = function(event) { var target = getTarget(event); if(Array.from(items).includes(target)) { var prevItem = target.previousElementSibling, suffItem = target.nextElementSibling, direction = event.clientX - lastX; /** * 改變鼠標樣式 * 1:中間的元素左右邊都可拖拽樣式(左邊拖拽時,實際設置前置元素寬度) * 2:沒有前置元素的只能有右邊拖拽樣式 * 3:沒有后置元素的只能有左邊拖拽樣式 **/ if (suffItem && (event.offsetX > target.offsetWidth - 10) || prevItem && (event.offsetX < 10)) { target.style.cursor = 'col-resize'; }else { target.style.cursor = ''; } //調整寬度 var item = getClickedTarget(items); if(item && item.mouseDown && direction) { setWidth(item,direction); lastX = event.clientX; } } }; function setWidth(item,offset) { var style = getComputedStyle(item), width = style.width.replace('px','')-0; // maxWidth、minWidth 防止flex布局對寬度計算的影響 item.style.width = width + offset + 'px'; item.style.maxWidth = width + offset + 'px'; item.style.minWidth = width + offset + 'px'; } } function addListener(element,type,listener,useCapture){ element.addEventListener?element.addEventListener(type,listener,useCapture):element.attachEvent("on" + type,listener); } function getTarget(evt){ return evt.target || evt.srcElement; } function getClickedTarget(items){ var t; Array.from(items).map(function(item){ if(item.mouseDown == true) t = item; }); return t; } /** * 創建鼠標事件 **/ function newMouseEvent(event,eventType){ var clientX = event.clientX,clientY=event.clientY,screenX=event.screenX,screenY=event.screenY; var simEvent = new MouseEvent(eventType,{clientX:clientX,clientY:clientY,screenX:screenX,screenY:screenY}); return simEvent; } </script> </html>