【前端】如何实现框选多个元素,并且可以进行放大缩小等操作?

想实现一个类似于下面这个图片的效果,这只是个简单的,后续可能还要加上放大缩小等操作。

【前端】如何实现框选多个元素,并且可以进行放大缩小等操作?

大家有什么好的组件或者思路嘛?

回答

这个也就是制造一个模拟框,覆盖上去,然后改变背景颜色,也就是鼠标拖拽事件,这里是你想要的效果

【前端】如何实现框选多个元素,并且可以进行放大缩小等操作?
框选同时按住 SHIFT 为增加选择
框选同时按住 ALT 为从已有选择种删除

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Batch Select</title>

<style type="text/css">

.flex-row {display:-webkit-flex;display:flex;-webkit-flex-direction:row;flex-direction:row;}

.flex-row > .flex-main {-webkit-flex:1 1 auto;flex:1 1 auto;}

.flex-row > .flex-side {-webkit-flex:0 0 auto;flex:0 0 auto;}

.flex-column {display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;}

.flex-column > .flex-main {-webkit-flex:1 1 auto;flex:1 1 auto;}

.flex-column > .flex-side {-webkit-flex:0 0 auto;flex:0 0 auto;}

.template {display:none;}

.cell-matrix {position:relative;padding:0.5em;background-color:#EEE;

-webkit-user-select: none;

-moz-user-select: none;

-ms-user-select: none;

user-select: none;}

.cell-matrix .select {position:absolute;display:none;border:1px dashed rgba(0,0,255,0.7);background-color:rgba(0,0,255,0.3);box-sizing:border-box;}

.cell-matrix .cell-list {margin:0.5em 0;}

.cell-matrix .cell-list .cell-group {white-space:nowrap;}

.cell-matrix .cell-list .cell-group .cell {display:inline-block;background-color:#FFF;box-shadow:0 0 0 1px #CCC;}

.cell-matrix .cell-list .cell-group .cell-select {background-color:#00F;}

.cell-matrix .cell-list .cell-group .gap {display:inline-block;}

.cell-data {white-space:pre;}

</style>

<script>

document.addEventListener('DOMContentLoaded', function(){

let domTpl = document.querySelector('.template .cell-group');

let arrDomCellList = document.querySelectorAll('.cell-list');

let i, domCellList, dom;

for(i=0; i<arrDomCellList.length; i++)

{

domCellList = arrDomCellList[i];

for(let j=0; j<4; j++)

{

dom = domTpl.cloneNode(true);

domCellList.appendChild(dom);

}

}

let domMatrix = document.querySelector('.cell-matrix');

let MODE_SET = 1;

let MODE_ADD = 2;

let MODE_DEL = 3;

let SelectArea = {

domBase : domMatrix,

dom : domMatrix.querySelector('.select'),

on : false,

mode : MODE_SET,

x1 : 0,

y1 : 0,

x2 : 0,

y2 : 0,

};

function update_select_cell()

{

let x1 = Math.min(SelectArea.x1, SelectArea.x2) + SelectArea.domBase.offsetLeft - SelectArea.domBase.scrollLeft;

let y1 = Math.min(SelectArea.y1, SelectArea.y2) + SelectArea.domBase.offsetTop - SelectArea.domBase.scrollTop;

let x2 = Math.max(SelectArea.x1, SelectArea.x2) + SelectArea.domBase.offsetLeft - SelectArea.domBase.scrollLeft;

let y2 = Math.max(SelectArea.y1, SelectArea.y2) + SelectArea.domBase.offsetTop - SelectArea.domBase.scrollTop;

let arrData = [];

let arrDomCellList = document.querySelectorAll('.cell-list');

let i, domCellList;

for(i=0; i<arrDomCellList.length; i++)

{

domCellList = arrDomCellList[i];

let data = '';

let arrDomCell = domCellList.querySelectorAll('.cell');

let j, domCell, rect, flag;

for(j=0; j<arrDomCell.length; j++)

{

domCell = arrDomCell[j];

rect = domCell.getBoundingClientRect();

flag = ! (x2 < rect.left

|| y2 < rect.top

|| x1 > rect.right

|| y1 > rect.bottom);

switch(SelectArea.mode)

{

case MODE_ADD:

if(flag === true)

{

data += '1';

domCell.classList.add('cell-select');

}

else

{

data += (domCell.classList.contains('cell-select')?'1':'0');

}

break;

case MODE_DEL:

if(flag === true)

{

data += '0';

domCell.classList.remove('cell-select');

}

else

{

data += (domCell.classList.contains('cell-select')?'1':'0');

}

break;

default:

if(flag === true)

{

data += '1';

domCell.classList.add('cell-select');

}

else

{

data += '0';

domCell.classList.remove('cell-select');

}

break;

}

}

arrData.push(data);

}

return arrData;

}

function update_select_rect()

{

if(SelectArea.on === false)

{

SelectArea.dom.style.display = 'none';

let arrData = update_select_cell();

document.querySelector('.cell-data').innerHTML = arrData.join('\n');

SelectArea.x1 = 0;

SelectArea.y1 = 0;

SelectArea.x2 = 0;

SelectArea.y2 = 0;

return;

}

SelectArea.dom.style.display = 'block';

SelectArea.dom.style.top = Math.min(SelectArea.y1, SelectArea.y2) + 'px';

SelectArea.dom.style.left = Math.min(SelectArea.x1, SelectArea.x2) + 'px';

SelectArea.dom.style.width = Math.abs(SelectArea.x1 - SelectArea.x2) + 'px';

SelectArea.dom.style.height = Math.abs(SelectArea.y1 - SelectArea.y2) + 'px';

}

domMatrix.addEventListener('mousedown', function($evt){

if(($evt.buttons & 0x01) !== 0x01)

return;

SelectArea.on = true;

SelectArea.x1 = $evt.clientX - SelectArea.domBase.offsetLeft + SelectArea.domBase.scrollLeft;

SelectArea.y1 = $evt.clientY - SelectArea.domBase.offsetTop + SelectArea.domBase.scrollTop;

SelectArea.x2 = SelectArea.x1;

SelectArea.y2 = SelectArea.y1;

update_select_rect();

});

domMatrix.addEventListener('mouseup', function($evt){

if(SelectArea.on === false)

return;

if(($evt.buttons & 0x01) !== 0x00)

return;

if($evt.shiftKey === true)

SelectArea.mode = MODE_ADD;

else if($evt.altKey === true)

SelectArea.mode = MODE_DEL;

else

SelectArea.mode = MODE_SET;

SelectArea.on = false;

SelectArea.x2 = $evt.clientX - SelectArea.domBase.offsetLeft + SelectArea.domBase.scrollLeft;

SelectArea.y2 = $evt.clientY - SelectArea.domBase.offsetTop + SelectArea.domBase.scrollTop;

update_select_rect();

});

domMatrix.addEventListener('mousemove', function($evt){

if(SelectArea.on === false)

return;

if(($evt.buttons & 0x01) !== 0x01)

return;

SelectArea.x2 = $evt.clientX - SelectArea.domBase.offsetLeft + SelectArea.domBase.scrollLeft;

SelectArea.y2 = $evt.clientY - SelectArea.domBase.offsetTop + SelectArea.domBase.scrollTop;

update_select_rect();

});

});

</script>

</head>

<body>

<div class="cell-matrix">

<div class="select"></div>

<div class="flex-row cell-list">

<div class="flex-side">星期一</div>

<div class="gap">&ensp;</div>

</div>

<div class="flex-row cell-list">

<div class="flex-side">星期二</div>

<div class="gap">&ensp;</div>

</div>

<div class="flex-row cell-list">

<div class="flex-side">星期三</div>

<div class="gap">&ensp;</div>

</div>

<div class="flex-row cell-list">

<div class="flex-side">星期四</div>

<div class="gap">&ensp;</div>

</div>

<div class="flex-row cell-list">

<div class="flex-side">星期五</div>

<div class="gap">&ensp;</div>

</div>

<div class="flex-row cell-list">

<div class="flex-side">星期六</div>

<div class="gap">&ensp;</div>

</div>

<div class="flex-row cell-list">

<div class="flex-side">星期日</div>

<div class="gap">&ensp;</div>

</div>

</div>

<div class="cell-data"></div>

<div class="template">

<div class="flex-side cell-group">

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="cell">&ensp;</div>

<div class="gap">&ensp;</div>

</div>

</div>

</body>

</html>

以上是 【前端】如何实现框选多个元素,并且可以进行放大缩小等操作? 的全部内容, 来源链接: utcz.com/a/80129.html

回到顶部