js PC端选择框特效

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>canvas</title>
    <style>
        html,body {
            margin: 0;
            padding: 0;
            height: 100vh;
            width: 100vw;
        }
		/* 选择框样式 */
        #rubberband {
            width: 0;
            height: 0;
            border: 1px solid rgb(0 209 255);
            background-color: rgba(0,209,255,0.25);
            position: absolute;
            z-index: 999;
        }
    </style>
</head>
<body>   
    <script>
    	addRubberband(document.body,{mouseup(o) {console.log(o)}})

		// 添加选择框,选择框的信息会以回调函数方式返回
		// @params{HTMLElement} 选择框的容器
		// @params{object} mousedown,mousemove,mouseup 回调函数, 信息是第一个参数
		function addRubberband(container,eventCb={}) {
		    let div = document.createElement("div");
		    let width,height,startX,startY,endX,endY,left,top;
		    let containerBox = {}
		    
		    div.id = "rubberband";
		    document.body.appendChild(div)
		    let event = {
		        mousedown(e) {
		            containerBox = container.getBoundingClientRect(); // 实时获取最新状态
		            startX = left = e.clientX;
		            startY = top = e.clientY;
		            window.addEventListener("mousemove",event.mousemove)
		            eventCb.mousedown && eventCb.mousedown(div.getDivRect())
		        },
		        mousemove(e) {
		            endX = e.clientX;
		            endY = e.clientY;
		            width = endX - startX;
		            height = endY - startY;
		            
		            // x反向选择
		            if (startX > endX) {
		                width = Math.abs(startX - endX);
		                left = startX-Math.abs(startX - endX);
		            }
		            // y反向选择
		            if (startY > endY) {
		                height = Math.abs(startY - endY);
		                top = startY-Math.abs(startY - endY);
		            }
		            // 选框不超出容器才渲染
		            if (
		            left >= containerBox.left && 
		            endX <= (containerBox.left+containerBox.width) &&
		            top >= containerBox.top && 
		            endY <= (containerBox.top+containerBox.height)
		            ) {
		                event.updateStyle();
		            }
		            
		            eventCb.mousemove && eventCb.mousemove(div.getDivRect())
		        },
		        mouseup(e) {
		            window.removeEventListener("mousemove",event.mousemove);
		            eventCb.mouseup && eventCb.mouseup(event.getDivRect())
		            div.style.display = "none"
		            width = height = 0;
		        },
		        // 更新选择框样式
		        updateStyle() {
		            div.style = `
		            display: block;
		            left: ${left}px;
		            top: ${top}px;
		            width: ${width}px;
		            height: ${height}px
		            `;
		        },
		        // 获取选择框信息,选择框定位信息是相对于容器的
		        getDivRect() {
		            let {left,top,width,height} = div.getBoundingClientRect();
		            return {
		                startX: left-containerBox.left,
		                startY: top - containerBox.top,
		                endX: left-containerBox.left+width,
		                endY: top-containerBox.top+height,
		                width,height
		            }
		        }
		    }
		    container.addEventListener("mousedown",event.mousedown)
		    window.addEventListener("mouseup",event.mouseup)
		}
	</script>
</body>
</html>

注意:

  1. 默认会向window 添加了 mouseup 事件
  2. 选择框信息有 宽高,定位
  3. 移动端需要将鼠标事件换成touch事件,把 e.clientX 替换成 e.targetTouches[0].clientX, e.clientY 也同理
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值