实现checkbox的多选

时间:2023-03-09 04:21:37
实现checkbox的多选

checkbox多选

  技术一般水平有限,有什么错的地方,望大家指正。

  全选,多选都是为了使用的方便,一般情况下全选就够用了,但是用户要求实现一个多选的功能也没有办法老老实实的做吧。

  多选的实现也较为简单,首先需要一个遮罩可以标识给用户当前所选择的区域,其次就是选中用户所需要的信息,按照这个思路我们来一步步实现。

遮罩实现

  我们用一个div来当做遮罩层:

.mask{height:1px;width:1px;position:absolute;background-color:gray;opacity:0.2}
function createMask(){
var div = document.createElement("div");
div.className = "mask";
div.id = "mask";
document.body.appendChild(div);
}

  接下来就是唯一需要注意的地方就是遮罩的大小的变化,遮罩是用一个div来实现,所以需要动态的表示出宽高位置来为用户标识出选择的位置:

实现checkbox的多选

  我们把可以移动的区域分成四份(不是个标准的四象限~凑合看),假如原点就是我们鼠标按下时的位置。

  当我们在A象限拖动时这是最正常的一种情况,鼠标按下时的点就是遮罩的左上角那个点,宽高就是鼠标运动时的坐标减去鼠标按下时的坐标。

  当在B象限拖动时,我们拖动的方向是左下方,此时鼠标按下时的点就是遮罩的右上角,决定遮罩大小的点就是我们鼠标移动时的点和鼠标按下时的点之间的距离,这个很好计算出来,在有了遮罩的大小之后最重要的就是决定遮罩的位置,我们要明白不管遮罩怎么移动决定它的位置的都是左上角那个点。当在B象限移动时moveY>downY,moveX<downX,所以此时遮罩的宽:downX-moveX,高:moveY-downY,左上角的点为moveX,downY。

  当在C象限拖动时,此时moveX<downX,moveY<downY,此时鼠标按下的位置作为遮罩的右下角,遮罩的左上角的点为moveX,moveY,宽:downX-moveX,高:downY-moveY。

  当在D象限移动时,此时moveX>downX,moveY<downY,此时遮罩的左上角的点为:downX,moveY,宽:downX-moveX,高:downY-moveY。

  在屏幕中间按下鼠标向周围移动查看效果

选中实现

  这个较为简单,记录鼠标按下时的坐标,记录鼠标松开时的坐标,两个点决定的矩形区域内的checkbox选中即可(一个demo)。

  downX,downY为鼠标按下死的坐标,upX,upY为鼠标松开是的坐标,moveX,moveY为鼠标移动时的坐标。

      //禁止左键选中
$(document).bind("selectstart",function(){
return false;
})
$(document).mousedown(function(e){
var downX = e.pageX;
var downY = e.pageY;
      createMask();
$(this).bind("mousemove",function(e){
var moveX = e.pageX;
var moveY = e.pageY;
var mask = $("#mask");
mask.css({"width":moveX-downX+"px","height":moveY-downY+"px"})
if(moveX<downX&&moveY>downY){//在B内
mask.css({"left":moveX+"px","top":downY+"px","width":downX-moveX+"px","height":moveY-downY+"px"})
}else if(moveX<downX&&moveY<downY){//在C内
mask.css({"left":moveX+"px","top":moveY+"px","width":downX-moveX+"px","height":downY-moveY+"px"})
}else if(moveX>downX&&moveY<downY){//在D内
mask.css({"left":downX+"px","top":moveY+"px","width":moveX-downX+"px","height":downY-moveY+"px"})
}else{//在A内
mask.css({"left":downX+"px","top":downY+"px","width":moveX-downX+"px","height":moveY-downY+"px"})
}
})
$(this).bind("mouseup",function(e){
var upX = e.pageX;
var upY = e.pageY;
var doms = $("input");
downX>upX&&changeX();
downY>upY&&changeY();
for(var i=0,il=doms.length;i<il;i++){
var c = $(doms[i]);
var p = c.position();
var top = p.top;
var left = p.left;
if(top>=downY&&top<=upY&&left>=downX&&left<=upX){
c.prop("checked",!c.prop("checked"));
}
}
$(this).unbind("mousemove");
$(this).unbind("mouseup");
$("#mask").remove();
function changeY(){
var c;
c = downY;
downY = upY;
upY = c;
}
function changeX(){
var c;
c = downX;
downX = upX;
upX = c;
}
}.bind(this))
})
function createMask(){
var div = $("<div id='mask' class='mask'></div>");
$("body").append(div);
}

  计算checkbox的位置如果有父级元素要使用ele.offset().top/ele.offset().left来计算当前的位置。

  基本思路就是这样,可根据实际需求做一些改造,比如按下ctrl才开始这个功能,为了使用方便也可以封装成一个方法。