用原生js实现矩形框选
先上效果图:
从效果图中可以看到可以获取到选中区域的某个点的具体坐标:(554,249);
554 代表的是左边离 左侧浏览器的位置距离;
249代表,右上点距离右上浏览器的距离;
如何得到Aid 和 Bid 的位置信息呢? 思路如下:
// aid的left=矩形的left; top=top+height
// bid的left=矩形的left+width; top=top+height
//Aid 的位置坐标
// let AId_left = e.clientX;
// let AId_hight = (e.clientY + Math.abs(posy - ev.clientY));
//Bid 的位置坐标
// let BId_left = e.clientX + Math.abs(posx - ev.clientX);
// let BId_hight = (e.clientY + Math.abs(posy - ev.clientY));
原生的具体代码如下(仅供参考):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>鼠标框选效果</title>
<style>
*{
padding:0;
margin:0;
}
#bottom{
position:absolute;
bottom:0px;
width:100%;
height:40px;
border:1px solid #000;
background:#000;
color:#fff;
}
.tempDiv{
border:1px dashed blue;
background:#5a72f8;
position:absolute;
width:0;
height:0;
filter:alpha(opacity:10);
opacity:0.1;
}
</style>
<script type = "text/javascript">
window.onload = function(){
var stateBar = document.getElementById("bottom");
document.onmousedown = function(e){
var posx = e.clientX;
var posy = e.clientY;
var div = document.createElement("div");
div.className = "tempDiv";
div.style.left = e.clientX+"px";
div.style.top = e.clientY+"px";
document.body.appendChild(div);
document.onmousemove = function(ev){
div.style.left = Math.min(ev.clientX, posx) + "px";
div.style.top = Math.min(ev.clientY, posy) + "px";
div.style.width = Math.abs(posx - ev.clientX)+"px";
div.style.height = Math.abs(posy - ev.clientY)+"px";
stateBar.innerHTML = "MouseX: " + ev.clientX + "<br/>MouseY: " + ev.clientY;
console.log("x,y",ev.clientX,ev.clientY);
document.onmouseup = function(){
div.parentNode.removeChild(div);
document.onmousemove = null;
document.onmouseup = null;
alert("1");
}
}
}
}
</script>
</head>
<body>
<div>
<div id = "bottom" ></div>
<div>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
</div>
</body>
</html>
第2中情况在vue的情况下使用:
先上效果图:
注意事项:
①:window.onload 在vue 里面是不起作用额;
②:document. 代表是全局的
③:鼠标移动时禁止选中文字 的方法:css style:html,body{-moz-user-select: none; -khtml-user-select: none; user-select: none;}或者:<div unselectable="on" onselectstart="return false;" style="-moz-user-select:none;">
屏蔽选择的样式定义:-moz-user-select属性(只支持ff)。
属性有三个属性值:
1、 none:用none,子元素所有的文字都不能选择,包括input输入框中的文字也不能选择。
2、 -moz-all:子元素所有的文字都可以被选择,但是input输入框中的文字不可以被选择。
3、 -moz-none:子元素所有的文字都不能选择,但是input输入框中的文字除外。
vue中改正:
var trainSelected = document.getElementById('trainSelected');
//当鼠标按下时,按钮事件
trainSelected.onmousedown
//当鼠标指针移出时,
trainSelected.onmousemove
//当松开鼠标按钮时,
trainSelected.onmouseup
附加信息:如何得到AID 和 BID 的具体信息:
第一步:通过@mousemove="move()" 方法绑定id
第二步:通过:
//取出来:矩形里开始位置的Aid 和 结束位置的Bid
move(data){
if (!this.pressed) return
// console.log("data",data);
this.pressData.push(data);
},
第三步:定义数组:this.pressData = []; //圈中的值,初始化
最后:
//当松开鼠标按钮时,
trainSelected.onmouseup = (event) =>{
console.log("end",this.pressData, this.pressData[0], this.pressData[this.pressData.length-1]);
AID= this.pressData, this.pressData[0],
BID = this.pressData[this.pressData.length-1];
}
由于我没放真实的 数组id 在 这里 @mousemove="move()" move( 数组id)
所以end 打印的都没有值:
具体代码如下:
<template>
<div unselectable="on" onselectstart="return false;" style="-moz-user-select:none;">
<div id = "bottom" ></div>
<div id="trainSelected" @mousemove="move()">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
</div>
</template>
<script>
export default {
data(){
return{
pressed: false,
pressData:null,
}
},
methods:{
//取出来:矩形里开始位置的Aid 和 结束位置的Bid
move(data){
if (!this.pressed) return
// console.log("data",data);
this.pressData.push(data);
},
boxSelection(){
this.pressData = []; //圈中的值,初始化
var stateBar = document.getElementById("bottom");
var trainSelected = document.getElementById('trainSelected');
//当鼠标按下时,按钮事件
trainSelected.onmousedown = (e) =>{
this.pressed = true;
// console.log('开始',e , e.clientY, e.clientY)
var posx = e.clientX;
var posy = e.clientY;
var div = document.createElement("div");
div.className = "tempDiv";
div.style.left = e.clientX+"px";
div.style.top = e.clientY+"px";
// document.body.appendChild(div);
trainSelected.appendChild(div);
//当鼠标指针移出时,
trainSelected.onmousemove = (ev) =>{
div.style.left = Math.min(ev.clientX, posx) + "px";
div.style.top = Math.min(ev.clientY, posy) + "px";
div.style.width = Math.abs(posx - ev.clientX)+"px";
div.style.height = Math.abs(posy - ev.clientY)+"px";
// aid的left=矩形的left; top=top+height
// bid的left=矩形的left+width; top=top+height
//Aid 的位置坐标
// let AId_left = e.clientX;
// let AId_hight = (e.clientY + Math.abs(posy - ev.clientY));
//Bid 的位置坐标
// let BId_left = e.clientX + Math.abs(posx - ev.clientX);
// let BId_hight = (e.clientY + Math.abs(posy - ev.clientY));
stateBar.innerHTML = "MouseX: " + ev.clientX + "<br/>MouseY: " + ev.clientY;
//当松开鼠标按钮时,
trainSelected.onmouseup = (event) =>{
console.log("end",this.pressData, this.pressData[0], this.pressData[this.pressData.length-1]);
this.pressed = false;
// console.log('结束', event.clientX, event.clientY)
div.parentNode.removeChild(div);
trainSelected.onmousemove = null;
trainSelected.onmouseup = null;
// this.show = true;
}
}
}
},
},
created(){
},
mounted(){
this.boxSelection();
}
}
</script>
<style>
*{
padding:0;
margin:0;
}
/* /鼠标移动时禁止选中文字/ */
div{
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
cursor: pointer;
}
#bottom{
position:absolute;
bottom:0px;
width:100%;
height:40px;
border:1px solid #000;
background:#000;
color:#fff;
}
.tempDiv{
border:1px dashed blue;
background:#5a72f8;
position:absolute;
width:0;
height:0;
filter:alpha(opacity:10);
opacity:0.1;
}
#trainSelected {
height: 200px;
width: 100%;
}
</style>
如需要更详细的代码请上github done:https://github.com/nieyangyang712/vue-Rectangular-box-selection
修复bug:
当鼠标超过一个屏了,画的矩形消失了,不显示? 为什么?
修改办法:
在js里面:
修复bug:鼠标的右键事件会影响鼠标的滑动位置,多生成一个矩形框;
解决办法:
1.在 onmousedown 方法里面 禁止右键事件
if(e.button ==2) return false; //禁止鼠标右键事件
2.点击时候,移除创建的矩形框
//点击后---松开鼠标按钮时
trainSelected.onmouseup = (event) =>{
this.pressed = false; // 禁止拖动
trainSelected.onmousemove = null;
trainSelected.onmouseup = null;
// div.parentNode.removeChild(div); // 移除框选的虚线框
// console.log(event,event.button);
if(event.button == 0 && event.button == 1 && event.button == 2){
div.parentNode.removeChild(div); // 移除框选的虚线框
}
// console.log(1);
for(let i= 0; i < preBoxs.length; i++){
if(preBoxs[i]){
trainSelected.removeChild(preBoxs[i])
}
}
}
更多方法请移步github:https://github.com/nieyangyang712/mouse-drawing-rectangle
最后为了方便大家的沟通与交流请加QQ群: 625787746
请进QQ群交流:【IT博客技术分享群①】:https://jq.qq.com/?_wv=1027&k=DceI0140