框选效果

小序:

朋友发来一个框选的demo, 但是有一个问题,有时候在框选时会出现 禁止按钮导致有一些问题

今天俺们来搞一搞这个问题

框选效果

点击按住移动出现选中区域松开 选中选中区域的元素

是为了解决禁止选中问题, 就不重头写了

先在百度copy一个框选的效果

/***
  * 信息提示组件Toast v1.0
    * @param {Object} box 外部容器(必填)
    * @param {Object} container 内容容器(必填)
    * @param {Object} 
    * 使用方法
    * var toast = new CheckAll({});
    * toast.getNature();获取属性(返回list数组)
  */

(function(){
  var CheckAll = function(options){
    var o = options;
    //目标选中
    var selList = [];
    // 用来存放鼠标点击初始位置
    var startX = 0;// 鼠标的x
    var startY = 0;// 鼠标的y
    var caseX = o.box.offsetLeft; // wrapper到左侧的距离
    var caseY = o.box.offsetTop; // wrapper到顶部的距离
    var scrollX = o.box.scrollLeft;// scroll向左滚动的距离
    var scrollY = o.box.scrollTop;// scroll向上滚动的距离
    var oBoxW = o.box.style.width;// wrapper的宽度
    var i = 0;
     // 定时器id
    var mouseStopId,mouseMax;
     // 是否开启框选功能
     var mouseOn = false;
    o.container.onmousedown = function(e) { 
      console.log(e, '按下')
      var fileNodes = o.box.getElementsByTagName(o.tagName);
      // console.log(fileNodes); 
      for ( var i = 0; i < fileNodes.length; i++) { 
        if (fileNodes[i].className.indexOf(o.slideClassName) != -1) { 
          fileNodes[i].className = o.slideClassName; 
          selList.push(fileNodes[i]);
        } 
      } 
        clearEventBubble(e);
        //判断是否为左键按下
        if (e.buttons !== 1 || e.which !== 1) return;
          mouseOn = true;
        // mouseStopId = setTimeout(function () {
            caseX = o.box.offsetLeft;
            caseY = o.box.offsetTop;
            scrollX = o.box.scrollLeft;
            scrollY = o.box.scrollTop;

            startX = e.clientX - caseX + scrollX;
            startY = e.clientY - caseY + scrollY;

            // 创建一个框选元素
            var selDiv = document.createElement('div');
            // 给框选元素添加css样式,这里使用绝对定位
            selDiv.style.cssText = 'position:absolute;width:0px;height:0px;font-size:0px;margin:0px;padding:0px;border:1px dashed #0099FF;background-color:#C3D5ED;z-index:1000;filter:alpha(opacity:60);opacity:0.6;display:none;cursor:default';
            // 添加id
            selDiv.id = 'selectDiv';
            o.container.appendChild(selDiv);
            // 根据起始位置,添加定位

            selDiv.style.left = startX + 'px';
            selDiv.style.top = startY + 'px';
            selDiv.style.width = '0px';
            selDiv.style.height = '0px';
        //   }, 300); // 间隔300毫秒后执行,判定这时候鼠标左键被按住不放
    } 
    
    o.container.addEventListener('mousemove', function (e) {
        // 如果并非框选开启,退出
        if (!mouseOn) return false;
        console.log(e, '移动')
        // console.log('move'+ mouseOn)
        clearEventBubble(e);
        // 处理鼠标移动
        caseX = o.box.offsetLeft; // wrapper到左侧的距离
        caseY = o.box.offsetTop; // wrapper到顶部的距离
        scrollX = o.box.scrollLeft;// scroll向左滚动的距离
        scrollY = o.box.scrollTop;// scroll向上滚动的距离
        var _x = e.clientX - caseX + scrollX;
        var _y = e.clientY - caseY + scrollY;
        
        // 根据坐标给选框修改样式
        var selDiv = document.getElementById('selectDiv');
        // console.log(selDiv);
        selDiv.style.display = 'block';
        selDiv.style.left = Math.min(_x, startX) + 'px';
        selDiv.style.top = Math.min(_y, startY) + 'px';
        selDiv.style.width = Math.abs(_x - startX) + 'px';
        selDiv.style.height = Math.abs(_y - startY) + 'px';

        //搂取子元素
        var _l = selDiv.offsetLeft, _t = selDiv.offsetTop; 
        var _w = selDiv.offsetWidth, _h = selDiv.offsetHeight; 
        for ( var i = 0; i < selList.length; i++) { 
          var sl = selList[i].offsetWidth + selList[i].offsetLeft; 
          var st = selList[i].offsetHeight + selList[i].offsetTop; 
          if (sl > _l && st > _t && selList[i].offsetLeft < _l + _w && selList[i].offsetTop < _t + _h) { 
            if (selList[i].className.indexOf("seled") == -1) { 
              selList[i].className = selList[i].className + " seled"; 
            } 
          } else {
            if (selList[i].className.indexOf("seled") != -1) { 
              selList[i].className = o.slideClassName; 
            } 
          } 
        } 
      });
      // 添加鼠标点击松开事件监听
    document.addEventListener('mouseup', function (e) {
        mouseOn = false;
        clearEventBubble(e);
        if (mouseOn) return;
        console.log(e, '撒开')
            // clearEventBubble(e);
            var selDiv = document.getElementById('selectDiv');
            var selectedEls = [];
            
            if (selDiv) { 
              o.container.removeChild(selDiv); 
              showSelDiv(selList); 
            } 
            selList = [];
            mouseMax = null;
            startX = 0;
            startY = 0;
      });
  }
  window.CheckAll = CheckAll;
}());
  CheckAll.prototype.getNature = function(){
  }
  function clearEventBubble(evt) { 
    if ( evt && evt.stopPropagation ) {
        evt.stopPropagation()
    }else{
        window.evt.cancelBubble  = true; 
    }
  } 
  function showSelDiv(arr) { 
    var count = 0; 
    var selInfo = ""; 
    for ( var i = 0; i < arr.length; i++) { 
      if (arr[i].className.indexOf("seled") != -1) { 
        count++; 
        selInfo += arr[i].innerHTML + "\n"; 
      } 
    } 
  } 

排版就不列出来了, 正常情况

偶尔出现这个的问题,禁止按钮

定位问题

正常情况: 按下 - 移动 - 移动 - 移动 .... - 撒开

非正常情况: 按下 - 移动 - 禁止状态(也可以移动,但是不走我们的事件) - 松开 - 移动 ...一直就没有撒开事件 / 按下 - 撒开

为什么会出现这种情况, 百度过,没有找到类似的,但是有拖拽时候出现这种问题,

问题来源: 拖动时如果碰到相邻元素,会出现禁止符号

个人认为 应该是浏览器的默认行为, 就在事件的同时阻止默认行为就好了

function clearEventBubble(evt) { 
    if ( evt && evt.preventDefault ) {
        evt.preventDefault()
    }else{
        window.evt.returnValue = false; 
    }
  } 

就可以畅快的框选了

就是这么简单 哈哈哈哈

嗖嗖嗖~ 对应原文

猜你喜欢

转载自blog.csdn.net/my_atlassian_yhl/article/details/84256158